From 52c66444a5cd48efcdfb81235f107c3dc6f61092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Wed, 11 Mar 2026 12:11:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E3=80=81=E5=AE=A1=E8=AE=A1=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E3=80=81=E9=80=9A=E7=9F=A5=E4=B8=AD=E5=BF=83=E3=80=81=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes .trae/docs/e2e_testing/E2E_TEST_CASES.md | 707 ++++++++++++++++++ .trae/rules/project_rules.md | 339 +++++++++ .vscode/settings.json | 14 + README.md | 61 ++ ...6-03-11-system-config-audit-notice-plan.md | 435 +++++++++++ docs/sql/init.sql | 147 ++++ e2e_tests/.env.example | 22 + e2e_tests/.gitignore | 55 ++ e2e_tests/README.md | 104 +++ e2e_tests/__init__.py | 6 + e2e_tests/api/__init__.py | 1 + e2e_tests/api/auth_api.py | 33 + e2e_tests/api/base_api.py | 58 ++ e2e_tests/api/dictionary_api.py | 42 ++ e2e_tests/api/role_api.py | 58 ++ e2e_tests/api/user_api.py | 58 ++ e2e_tests/config/__init__.py | 1 + e2e_tests/config/settings.py | 74 ++ e2e_tests/conftest.py | 161 ++++ e2e_tests/pytest.ini | 23 + e2e_tests/requirements.txt | 29 + e2e_tests/tests/__init__.py | 1 + e2e_tests/tests/test_auth.py | 83 ++ e2e_tests/tests/test_dictionary.py | 149 ++++ e2e_tests/tests/test_oauth2.py | 127 ++++ e2e_tests/tests/test_role.py | 185 +++++ e2e_tests/tests/test_user.py | 193 +++++ e2e_tests/utils/__init__.py | 3 + e2e_tests/utils/assertions.py | 83 ++ e2e_tests/utils/data_generator.py | 72 ++ e2e_tests/utils/logger.py | 33 + novalon-manage-api/manage-sys/pom.xml | 96 +++ .../manage/sys/ManageSysApplication.java | 11 + .../manage/sys/config/SecurityConfig.java | 31 + .../sys/config/SystemWebSocketHandler.java | 54 ++ .../manage/sys/config/WebSocketConfig.java | 23 + .../manage/sys/core/domain/BaseDomain.java | 43 ++ .../manage/sys/core/domain/OperationLog.java | 86 +++ .../manage/sys/core/domain/SysConfig.java | 35 + .../manage/sys/core/domain/SysDictData.java | 50 ++ .../manage/sys/core/domain/SysDictType.java | 35 + .../sys/core/domain/SysExceptionLog.java | 38 + .../manage/sys/core/domain/SysFile.java | 32 + .../manage/sys/core/domain/SysLoginLog.java | 35 + .../manage/sys/core/domain/SysMenu.java | 79 ++ .../manage/sys/core/domain/SysNotice.java | 35 + .../manage/sys/core/domain/SysRole.java | 41 + .../manage/sys/core/domain/SysUser.java | 50 ++ .../sys/core/domain/SysUserMessage.java | 29 + .../repository/IOperationLogRepository.java | 18 + .../core/repository/ISysMenuRepository.java | 18 + .../core/repository/ISysRoleRepository.java | 16 + .../core/repository/ISysUserRepository.java | 18 + .../core/service/IOperationLogService.java | 11 + .../sys/core/service/ISysConfigService.java | 14 + .../sys/core/service/ISysDictDataService.java | 14 + .../sys/core/service/ISysDictTypeService.java | 13 + .../core/service/ISysExceptionLogService.java | 14 + .../sys/core/service/ISysFileService.java | 14 + .../sys/core/service/ISysLoginLogService.java | 14 + .../sys/core/service/ISysMenuService.java | 15 + .../sys/core/service/ISysNoticeService.java | 13 + .../sys/core/service/ISysRoleService.java | 13 + .../core/service/ISysUserMessageService.java | 13 + .../sys/core/service/ISysUserService.java | 13 + .../service/impl/OperationLogService.java | 36 + .../service/impl/SysConfigServiceImpl.java | 56 ++ .../service/impl/SysDictDataServiceImpl.java | 56 ++ .../service/impl/SysDictTypeServiceImpl.java | 50 ++ .../impl/SysExceptionLogServiceImpl.java | 47 ++ .../core/service/impl/SysFileServiceImpl.java | 78 ++ .../service/impl/SysLoginLogServiceImpl.java | 47 ++ .../sys/core/service/impl/SysMenuService.java | 69 ++ .../service/impl/SysNoticeServiceImpl.java | 50 ++ .../sys/core/service/impl/SysRoleService.java | 48 ++ .../impl/SysUserMessageServiceImpl.java | 54 ++ .../sys/core/service/impl/SysUserService.java | 64 ++ .../manage/sys/dto/request/LoginRequest.java | 28 + .../dto/request/PasswordChangeRequest.java | 28 + .../sys/dto/request/UserRegisterRequest.java | 43 ++ .../sys/dto/request/UserUpdateRequest.java | 37 + .../manage/sys/dto/response/AuthResponse.java | 41 + .../manage/sys/dto/response/UserResponse.java | 82 ++ .../sys/handler/GlobalExceptionHandler.java | 78 ++ .../sys/handler/auth/SysAuthHandler.java | 59 ++ .../sys/handler/sys/SysConfigHandler.java | 62 ++ .../sys/handler/sys/SysDictHandler.java | 62 ++ .../sys/handler/sys/SysFileHandler.java | 88 +++ .../manage/sys/handler/sys/SysLogHandler.java | 77 ++ .../sys/handler/sys/SysMenuHandler.java | 56 ++ .../sys/handler/sys/SysMessageHandler.java | 47 ++ .../sys/handler/sys/SysNoticeHandler.java | 60 ++ .../sys/handler/sys/SysRoleHandler.java | 51 ++ .../sys/handler/user/SysUserHandler.java | 75 ++ .../db/converter/OperationLogConverter.java | 49 ++ .../db/converter/SysConfigConverter.java | 41 + .../db/converter/SysDictDataConverter.java | 49 ++ .../db/converter/SysDictTypeConverter.java | 41 + .../converter/SysExceptionLogConverter.java | 43 ++ .../db/converter/SysFileConverter.java | 39 + .../db/converter/SysLoginLogConverter.java | 41 + .../db/converter/SysMenuConverter.java | 45 ++ .../db/converter/SysNoticeConverter.java | 41 + .../db/converter/SysRoleConverter.java | 39 + .../db/converter/SysUserConverter.java | 41 + .../db/converter/SysUserMessageConverter.java | 37 + .../db/dao/OperationLogDao.java | 14 + .../infrastructure/db/dao/SysConfigDao.java | 17 + .../infrastructure/db/dao/SysDictDataDao.java | 19 + .../infrastructure/db/dao/SysDictTypeDao.java | 17 + .../db/dao/SysExceptionLogDao.java | 18 + .../sys/infrastructure/db/dao/SysFileDao.java | 17 + .../infrastructure/db/dao/SysLoginLogDao.java | 18 + .../sys/infrastructure/db/dao/SysMenuDao.java | 17 + .../infrastructure/db/dao/SysNoticeDao.java | 17 + .../sys/infrastructure/db/dao/SysRoleDao.java | 15 + .../sys/infrastructure/db/dao/SysUserDao.java | 15 + .../db/dao/SysUserMessageDao.java | 17 + .../infrastructure/db/entity/BaseEntity.java | 57 ++ .../db/entity/OperationLogEntity.java | 107 +++ .../db/entity/SysConfigEntity.java | 121 +++ .../db/entity/SysDictDataEntity.java | 165 ++++ .../db/entity/SysDictTypeEntity.java | 121 +++ .../db/entity/SysExceptionLogEntity.java | 121 +++ .../db/entity/SysFileEntity.java | 110 +++ .../db/entity/SysLoginLogEntity.java | 110 +++ .../db/entity/SysMenuEntity.java | 85 +++ .../db/entity/SysNoticeEntity.java | 121 +++ .../db/entity/SysRoleEntity.java | 52 ++ .../db/entity/SysUserEntity.java | 63 ++ .../db/entity/SysUserMessageEntity.java | 88 +++ .../db/repository/OperationLogRepository.java | 57 ++ .../db/repository/SysMenuRepository.java | 57 ++ .../db/repository/SysRoleRepository.java | 51 ++ .../db/repository/SysUserRepository.java | 57 ++ .../manage/sys/security/JwtTokenProvider.java | 66 ++ .../src/main/resources/application.yml | 25 + .../manage-sys/target/classes/application.yml | 25 + .../manage/sys/ManageSysApplication.class | Bin 0 -> 758 bytes .../manage/sys/config/SecurityConfig.class | Bin 0 -> 3310 bytes .../sys/config/SystemWebSocketHandler.class | Bin 0 -> 2831 bytes .../manage/sys/config/WebSocketConfig.class | Bin 0 -> 1434 bytes .../manage/sys/core/domain/BaseDomain.class | Bin 0 -> 1304 bytes .../manage/sys/core/domain/OperationLog.class | Bin 0 -> 2312 bytes .../manage/sys/core/domain/SysConfig.class | Bin 0 -> 2379 bytes .../manage/sys/core/domain/SysDictData.class | Bin 0 -> 3449 bytes .../manage/sys/core/domain/SysDictType.class | Bin 0 -> 2349 bytes .../sys/core/domain/SysExceptionLog.class | Bin 0 -> 2610 bytes .../manage/sys/core/domain/SysFile.class | Bin 0 -> 2154 bytes .../manage/sys/core/domain/SysLoginLog.class | Bin 0 -> 2310 bytes .../manage/sys/core/domain/SysMenu.class | Bin 0 -> 2528 bytes .../manage/sys/core/domain/SysNotice.class | Bin 0 -> 2379 bytes .../manage/sys/core/domain/SysRole.class | Bin 0 -> 1311 bytes .../manage/sys/core/domain/SysUser.class | Bin 0 -> 1566 bytes .../sys/core/domain/SysUserMessage.class | Bin 0 -> 1953 bytes .../repository/IOperationLogRepository.class | Bin 0 -> 1113 bytes .../core/repository/ISysMenuRepository.class | Bin 0 -> 1064 bytes .../core/repository/ISysRoleRepository.class | Bin 0 -> 864 bytes .../core/repository/ISysUserRepository.class | Bin 0 -> 1068 bytes .../core/service/IOperationLogService.class | Bin 0 -> 794 bytes .../sys/core/service/ISysConfigService.class | Bin 0 -> 1192 bytes .../core/service/ISysDictDataService.class | Bin 0 -> 1347 bytes .../core/service/ISysDictTypeService.class | Bin 0 -> 1081 bytes .../service/ISysExceptionLogService.class | Bin 0 -> 1124 bytes .../sys/core/service/ISysFileService.class | Bin 0 -> 1110 bytes .../core/service/ISysLoginLogService.class | Bin 0 -> 1087 bytes .../sys/core/service/ISysMenuService.class | Bin 0 -> 1365 bytes .../sys/core/service/ISysNoticeService.class | Bin 0 -> 1070 bytes .../sys/core/service/ISysRoleService.class | Bin 0 -> 898 bytes .../core/service/ISysUserMessageService.class | Bin 0 -> 1182 bytes .../sys/core/service/ISysUserService.class | Bin 0 -> 1269 bytes .../service/impl/OperationLogService.class | Bin 0 -> 1908 bytes .../service/impl/SysConfigServiceImpl.class | Bin 0 -> 4226 bytes .../service/impl/SysDictDataServiceImpl.class | Bin 0 -> 4263 bytes .../service/impl/SysDictTypeServiceImpl.class | Bin 0 -> 3838 bytes .../impl/SysExceptionLogServiceImpl.class | Bin 0 -> 3906 bytes .../service/impl/SysFileServiceImpl.class | Bin 0 -> 6320 bytes .../service/impl/SysLoginLogServiceImpl.class | Bin 0 -> 3809 bytes .../core/service/impl/SysMenuService.class | Bin 0 -> 6041 bytes .../service/impl/SysNoticeServiceImpl.class | Bin 0 -> 3797 bytes .../core/service/impl/SysRoleService.class | Bin 0 -> 2307 bytes .../impl/SysUserMessageServiceImpl.class | Bin 0 -> 4726 bytes .../core/service/impl/SysUserService.class | Bin 0 -> 4504 bytes .../manage/sys/dto/request/LoginRequest.class | Bin 0 -> 1057 bytes .../dto/request/PasswordChangeRequest.class | Bin 0 -> 1105 bytes .../sys/dto/request/UserRegisterRequest.class | Bin 0 -> 1599 bytes .../sys/dto/request/UserUpdateRequest.class | Bin 0 -> 1329 bytes .../sys/dto/response/AuthResponse.class | Bin 0 -> 1283 bytes .../sys/dto/response/UserResponse.class | Bin 0 -> 2583 bytes .../sys/handler/GlobalExceptionHandler.class | Bin 0 -> 5430 bytes .../sys/handler/auth/SysAuthHandler.class | Bin 0 -> 6843 bytes .../sys/handler/sys/SysConfigHandler.class | Bin 0 -> 5566 bytes .../sys/handler/sys/SysDictHandler.class | Bin 0 -> 5646 bytes .../sys/handler/sys/SysFileHandler.class | Bin 0 -> 7703 bytes .../sys/handler/sys/SysLogHandler.class | Bin 0 -> 7030 bytes .../sys/handler/sys/SysMenuHandler.class | Bin 0 -> 5048 bytes .../sys/handler/sys/SysMessageHandler.class | Bin 0 -> 4343 bytes .../sys/handler/sys/SysNoticeHandler.class | Bin 0 -> 5380 bytes .../sys/handler/sys/SysRoleHandler.class | Bin 0 -> 4834 bytes .../sys/handler/user/SysUserHandler.class | Bin 0 -> 6851 bytes .../db/converter/OperationLogConverter.class | Bin 0 -> 2390 bytes .../db/converter/SysConfigConverter.class | Bin 0 -> 2069 bytes .../db/converter/SysDictDataConverter.class | Bin 0 -> 2456 bytes .../db/converter/SysDictTypeConverter.class | Bin 0 -> 2067 bytes .../converter/SysExceptionLogConverter.class | Bin 0 -> 2225 bytes .../db/converter/SysFileConverter.class | Bin 0 -> 1953 bytes .../db/converter/SysLoginLogConverter.class | Bin 0 -> 2041 bytes .../db/converter/SysMenuConverter.class | Bin 0 -> 2238 bytes .../db/converter/SysNoticeConverter.class | Bin 0 -> 2069 bytes .../db/converter/SysRoleConverter.class | Bin 0 -> 1994 bytes .../db/converter/SysUserConverter.class | Bin 0 -> 2068 bytes .../converter/SysUserMessageConverter.class | Bin 0 -> 1934 bytes .../db/dao/OperationLogDao.class | Bin 0 -> 933 bytes .../infrastructure/db/dao/SysConfigDao.class | Bin 0 -> 1101 bytes .../db/dao/SysDictDataDao.class | Bin 0 -> 1401 bytes .../db/dao/SysDictTypeDao.class | Bin 0 -> 1109 bytes .../db/dao/SysExceptionLogDao.class | Bin 0 -> 1300 bytes .../infrastructure/db/dao/SysFileDao.class | Bin 0 -> 1111 bytes .../db/dao/SysLoginLogDao.class | Bin 0 -> 1272 bytes .../infrastructure/db/dao/SysMenuDao.class | Bin 0 -> 1129 bytes .../infrastructure/db/dao/SysNoticeDao.class | Bin 0 -> 1095 bytes .../infrastructure/db/dao/SysRoleDao.class | Bin 0 -> 906 bytes .../infrastructure/db/dao/SysUserDao.class | Bin 0 -> 908 bytes .../db/dao/SysUserMessageDao.class | Bin 0 -> 1261 bytes .../infrastructure/db/entity/BaseEntity.class | Bin 0 -> 1688 bytes .../db/entity/OperationLogEntity.class | Bin 0 -> 2722 bytes .../db/entity/SysConfigEntity.class | Bin 0 -> 3179 bytes .../db/entity/SysDictDataEntity.class | Bin 0 -> 4161 bytes .../db/entity/SysDictTypeEntity.class | Bin 0 -> 3120 bytes .../db/entity/SysExceptionLogEntity.class | Bin 0 -> 3189 bytes .../db/entity/SysFileEntity.class | Bin 0 -> 2913 bytes .../db/entity/SysLoginLogEntity.class | Bin 0 -> 2782 bytes .../db/entity/SysMenuEntity.class | Bin 0 -> 2392 bytes .../db/entity/SysNoticeEntity.class | Bin 0 -> 3169 bytes .../db/entity/SysRoleEntity.class | Bin 0 -> 1651 bytes .../db/entity/SysUserEntity.class | Bin 0 -> 1898 bytes .../db/entity/SysUserMessageEntity.class | Bin 0 -> 2422 bytes .../repository/OperationLogRepository.class | Bin 0 -> 4587 bytes .../db/repository/SysMenuRepository.class | Bin 0 -> 4456 bytes .../db/repository/SysRoleRepository.class | Bin 0 -> 4088 bytes .../db/repository/SysUserRepository.class | Bin 0 -> 4452 bytes .../sys/security/JwtTokenProvider.class | Bin 0 -> 3520 bytes .../compile/default-compile/createdFiles.lst | 22 + .../compile/default-compile/inputFiles.lst | 58 ++ novalon-manage-api/pom.xml | 162 ++++ novalon-manage-web/package.json | 49 ++ novalon-manage-web/src/App.vue | 12 + .../src/layouts/DefaultLayout.vue | 137 ++++ novalon-manage-web/src/main.ts | 18 + novalon-manage-web/src/router/index.ts | 44 ++ novalon-manage-web/src/utils/request.ts | 30 + .../src/views/audit/LoginLog.vue | 49 ++ .../src/views/audit/OperationLog.vue | 49 ++ .../src/views/config/ConfigManagement.vue | 115 +++ .../src/views/config/DictManagement.vue | 121 +++ .../src/views/file/FileManagement.vue | 118 +++ .../src/views/notify/NoticeManagement.vue | 129 ++++ .../src/views/system/Dashboard.vue | 68 ++ novalon-manage-web/src/views/system/Login.vue | 78 ++ .../src/views/system/MenuManagement.vue | 148 ++++ .../src/views/system/RoleManagement.vue | 122 +++ .../src/views/system/UserManagement.vue | 173 +++++ novalon-manage-web/vite.config.ts | 21 + 264 files changed, 10109 insertions(+) create mode 100644 .DS_Store create mode 100644 .trae/docs/e2e_testing/E2E_TEST_CASES.md create mode 100644 .trae/rules/project_rules.md create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 docs/plans/2026-03-11-system-config-audit-notice-plan.md create mode 100644 docs/sql/init.sql create mode 100644 e2e_tests/.env.example create mode 100644 e2e_tests/.gitignore create mode 100644 e2e_tests/README.md create mode 100644 e2e_tests/__init__.py create mode 100644 e2e_tests/api/__init__.py create mode 100644 e2e_tests/api/auth_api.py create mode 100644 e2e_tests/api/base_api.py create mode 100644 e2e_tests/api/dictionary_api.py create mode 100644 e2e_tests/api/role_api.py create mode 100644 e2e_tests/api/user_api.py create mode 100644 e2e_tests/config/__init__.py create mode 100644 e2e_tests/config/settings.py create mode 100644 e2e_tests/conftest.py create mode 100644 e2e_tests/pytest.ini create mode 100644 e2e_tests/requirements.txt create mode 100644 e2e_tests/tests/__init__.py create mode 100644 e2e_tests/tests/test_auth.py create mode 100644 e2e_tests/tests/test_dictionary.py create mode 100644 e2e_tests/tests/test_oauth2.py create mode 100644 e2e_tests/tests/test_role.py create mode 100644 e2e_tests/tests/test_user.py create mode 100644 e2e_tests/utils/__init__.py create mode 100644 e2e_tests/utils/assertions.py create mode 100644 e2e_tests/utils/data_generator.py create mode 100644 e2e_tests/utils/logger.py create mode 100644 novalon-manage-api/manage-sys/pom.xml create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SystemWebSocketHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/BaseDomain.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/OperationLog.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysConfig.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictData.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictType.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysExceptionLog.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysFile.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysLoginLog.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysMenu.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysNotice.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysRole.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUser.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUserMessage.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/IOperationLogRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysMenuRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysRoleRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysUserRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/IOperationLogService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysConfigService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictDataService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictTypeService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysExceptionLogService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysFileService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysLoginLogService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysMenuService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysNoticeService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysRoleService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserMessageService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictDataServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictTypeServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysMenuService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysRoleService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageServiceImpl.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserService.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/LoginRequest.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserRegisterRequest.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserUpdateRequest.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/AuthResponse.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/UserResponse.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/GlobalExceptionHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/auth/SysAuthHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysConfigHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysDictHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysFileHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysLogHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMenuHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMessageHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysRoleHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/user/SysUserHandler.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictDataConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysExceptionLogConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysFileConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysLoginLogConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserMessageConverter.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysNoticeDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysRoleDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysConfigEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictDataEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysExceptionLogEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysFileEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysNoticeEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysRoleEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.java create mode 100644 novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/security/JwtTokenProvider.java create mode 100644 novalon-manage-api/manage-sys/src/main/resources/application.yml create mode 100644 novalon-manage-api/manage-sys/target/classes/application.yml create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/ManageSysApplication.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/config/SecurityConfig.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/config/SystemWebSocketHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/config/WebSocketConfig.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/BaseDomain.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/OperationLog.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysConfig.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysDictData.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysDictType.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysExceptionLog.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysFile.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysLoginLog.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysMenu.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysNotice.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysRole.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysUser.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysUserMessage.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/IOperationLogRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/ISysMenuRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/ISysRoleRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/ISysUserRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/IOperationLogService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysConfigService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysDictDataService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysDictTypeService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysExceptionLogService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysFileService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysLoginLogService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysMenuService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysNoticeService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysRoleService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserMessageService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/OperationLogService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysDictDataServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysDictTypeServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysExceptionLogServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysMenuService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysNoticeServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysRoleService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysUserMessageServiceImpl.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysUserService.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/LoginRequest.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/UserRegisterRequest.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/UserUpdateRequest.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/AuthResponse.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/UserResponse.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/GlobalExceptionHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/auth/SysAuthHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysConfigHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysDictHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysFileHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysLogHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMenuHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMessageHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysRoleHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/user/SysUserHandler.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysDictDataConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysExceptionLogConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysFileConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysLoginLogConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysUserMessageConverter.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysNoticeDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysRoleDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysConfigEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysDictDataEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysExceptionLogEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysFileEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysNoticeEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysRoleEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysUserEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.class create mode 100644 novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/security/JwtTokenProvider.class create mode 100644 novalon-manage-api/manage-sys/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 novalon-manage-api/manage-sys/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 novalon-manage-api/pom.xml create mode 100644 novalon-manage-web/package.json create mode 100644 novalon-manage-web/src/App.vue create mode 100644 novalon-manage-web/src/layouts/DefaultLayout.vue create mode 100644 novalon-manage-web/src/main.ts create mode 100644 novalon-manage-web/src/router/index.ts create mode 100644 novalon-manage-web/src/utils/request.ts create mode 100644 novalon-manage-web/src/views/audit/LoginLog.vue create mode 100644 novalon-manage-web/src/views/audit/OperationLog.vue create mode 100644 novalon-manage-web/src/views/config/ConfigManagement.vue create mode 100644 novalon-manage-web/src/views/config/DictManagement.vue create mode 100644 novalon-manage-web/src/views/file/FileManagement.vue create mode 100644 novalon-manage-web/src/views/notify/NoticeManagement.vue create mode 100644 novalon-manage-web/src/views/system/Dashboard.vue create mode 100644 novalon-manage-web/src/views/system/Login.vue create mode 100644 novalon-manage-web/src/views/system/MenuManagement.vue create mode 100644 novalon-manage-web/src/views/system/RoleManagement.vue create mode 100644 novalon-manage-web/src/views/system/UserManagement.vue create mode 100644 novalon-manage-web/vite.config.ts diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 完成系统配置(字典管理、系统参数)、审计中心(登录日志、操作日志、异常追踪)、通知中心(系统公告、消息推送WebSocket)、文件管理(上传/下载/预览)的数据库持久化与功能完善 + +**Architecture:** 基于Spring R2DBC响应式架构,遵循现有分层模式(Handler->Service->Repository->Entity),使用H2/PostgreSQL + Caffeine缓存,消息推送采用WebSocket + +**Tech Stack:** Spring WebFlux, Spring Data R2DBC, H2/PostgreSQL, Caffeine, WebSocket, Lombok + +--- + +## 第一阶段:数据层基础设施建设 + +### Task 1: 创建数据库表SQL脚本 + +**Files:** +- Modify: `docs/sql/init.sql` (创建以下表) + +**Step 1: 编写SQL脚本** + +```sql +-- 字典类型表 +CREATE TABLE IF NOT EXISTS sys_dict_type ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + dict_name VARCHAR(100) NOT NULL COMMENT '字典名称', + dict_type VARCHAR(100) NOT NULL UNIQUE COMMENT '字典类型', + status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', + remark VARCHAR(500) COMMENT '备注', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 字典数据表 +CREATE TABLE IF NOT EXISTS sys_dict_data ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + dict_sort INT DEFAULT 0 COMMENT '字典排序', + dict_label VARCHAR(100) NOT NULL COMMENT '字典标签', + dict_value VARCHAR(100) NOT NULL COMMENT '字典键值', + dict_type VARCHAR(100) NOT NULL COMMENT '字典类型', + css_class VARCHAR(100) COMMENT '样式属性', + list_class VARCHAR(100) COMMENT '表格回显样式', + is_default VARCHAR(1) DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 系统配置表 +CREATE TABLE IF NOT EXISTS sys_config ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + config_name VARCHAR(100) NOT NULL COMMENT '配置名称', + config_key VARCHAR(100) NOT NULL UNIQUE COMMENT '配置键名', + config_value VARCHAR(500) NOT NULL COMMENT '配置值', + config_type VARCHAR(1) DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 登录日志表 +CREATE TABLE IF NOT EXISTS sys_login_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(50) COMMENT '用户名', + ip VARCHAR(50) COMMENT 'IP地址', + location VARCHAR(255) COMMENT '登录位置', + browser VARCHAR(50) COMMENT '浏览器类型', + os VARCHAR(50) COMMENT '操作系统', + status VARCHAR(1) COMMENT '登录状态(0成功 1失败)', + message VARCHAR(255) COMMENT '提示消息', + login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 异常日志表 +CREATE TABLE IF NOT EXISTS sys_exception_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(50) COMMENT '用户名', + title VARCHAR(100) COMMENT '异常标题', + exception_name VARCHAR(100) COMMENT '异常名称', + method_name VARCHAR(100) COMMENT '方法名称', + method_params TEXT COMMENT '方法参数', + exception_msg TEXT COMMENT '异常信息', + exception_stack TEXT COMMENT '堆栈信息', + ip VARCHAR(50) COMMENT 'IP地址', + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 系统公告表 +CREATE TABLE IF NOT EXISTS sys_notice ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + notice_title VARCHAR(100) NOT NULL COMMENT '公告标题', + notice_type VARCHAR(1) DEFAULT '1' COMMENT '公告类型(1通知 2公告)', + notice_content TEXT COMMENT '公告内容', + status VARCHAR(1) DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 文件管理表 +CREATE TABLE IF NOT EXISTS sys_file ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_name VARCHAR(255) NOT NULL COMMENT '文件名', + file_path VARCHAR(500) NOT NULL COMMENT '文件路径', + file_size VARCHAR(50) COMMENT '文件大小', + file_type VARCHAR(50) COMMENT '文件类型', + storage_type VARCHAR(20) DEFAULT 'local' COMMENT '存储类型(local/oss/s3)', + create_by VARCHAR(50) COMMENT '创建者', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 用户消息表(消息推送用) +CREATE TABLE IF NOT EXISTS sys_user_message ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL COMMENT '接收用户ID', + title VARCHAR(100) COMMENT '消息标题', + content TEXT COMMENT '消息内容', + message_type VARCHAR(1) DEFAULT '1' COMMENT '消息类型(1系统 2通知)', + is_read VARCHAR(1) DEFAULT '0' COMMENT '是否已读(0未读 1已读)', + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +**Step 2: 提交SQL脚本** + +```bash +git add docs/sql/init.sql +git commit -m "feat: 添加系统配置和审计模块数据库表脚本" +``` + +--- + +### Task 2: 创建字典类型Entity + +**Files:** +- Create: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java` +- Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java` + +**Step 1: 在BaseEntity添加公共字段** + +查看现有BaseEntity确保包含: +- id, createdAt, updatedAt, deletedAt + +**Step 2: 创建SysDictTypeEntity** + +```java +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table("sys_dict_type") +public class SysDictTypeEntity { + + @Id + private Long id; + + @Column("dict_name") + private String dictName; + + @Column("dict_type") + private String dictType; + + @Column("status") + private String status; + + @Column("remark") + private String remark; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + private LocalDateTime deletedAt; + + // Getters and Setters +} +``` + +**Step 3: 提交** + +```bash +git add entity/SysDictTypeEntity.java +git commit -m "feat: 添加字典类型Entity" +``` + +--- + +### Task 3: 创建其他Entity(字典数据、系统配置、登录日志、异常日志、公告、文件、消息) + +**Files:** +- Create: `infrastructure/db/entity/SysDictDataEntity.java` +- Create: `infrastructure/db/entity/SysConfigEntity.java` +- Create: `infrastructure/db/entity/SysLoginLogEntity.java` +- Create: `infrastructure/db/entity/SysExceptionLogEntity.java` +- Create: `infrastructure/db/entity/SysNoticeEntity.java` +- Create: `infrastructure/db/entity/SysFileEntity.java` +- Create: `infrastructure/db/entity/SysUserMessageEntity.java` + +**每Entity结构:** 继承BaseEntity,添加对应字段的@Column注解和getter/setter + +**示例 - SysConfigEntity:** +```java +@Table("sys_config") +public class SysConfigEntity { + @Id + private Long id; + + @Column("config_name") + private String configName; + + @Column("config_key") + private String configKey; + + @Column("config_value") + private String configValue; + + @Column("config_type") + private String configType; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + private LocalDateTime deletedAt; + + // Getters and Setters +} +``` + +--- + +### Task 4: 创建Repository接口 + +**Files:** +- Create: `infrastructure/db/repository/SysDictTypeRepository.java` +- Create: `infrastructure/db/repository/SysDictDataRepository.java` +- Create: `infrastructure/db/repository/SysConfigRepository.java` +- Create: `infrastructure/db/repository/SysLoginLogRepository.java` +- Create: `infrastructure/db/repository/SysExceptionLogRepository.java` +- Create: `infrastructure/db/repository/SysNoticeRepository.java` +- Create: `infrastructure/db/repository/SysFileRepository.java` +- Create: `infrastructure/db/repository/SysUserMessageRepository.java` + +**每Repository:** 继承 ReactiveCrudRepository + +**示例:** +```java +package cn.novalon.manage.sys.infrastructure.db.repository; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysDictTypeEntity; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SysDictTypeRepository extends ReactiveCrudRepository { +} +``` + +--- + +## 第二阶段:领域层(Domain + Converter) + +### Task 5: 更新Domain模型 + +**Files:** +- Modify: `core/domain/SysDictType.java` - 添加dictDataList字段 +- Modify: `core/domain/SysDictData.java` - 确保字段完整 +- Modify: `core/domain/SysConfig.java` - 确保字段完整 +- Modify: `core/domain/SysLoginLog.java` - 确保字段完整 +- Create: `core/domain/SysExceptionLog.java` +- Create: `core/domain/SysUserMessage.java` + +--- + +### Task 6: 创建Converter转换器 + +**Files:** +- Create: `infrastructure/db/converter/SysDictTypeConverter.java` +- Create: `infrastructure/db/converter/SysDictDataConverter.java` +- Create: `infrastructure/db/converter/SysConfigConverter.java` +- Create: `infrastructure/db/converter/SysLoginLogConverter.java` +- Create: `infrastructure/db/converter/SysExceptionLogConverter.java` +- Create: `infrastructure/db/converter/SysNoticeConverter.java` +- Create: `infrastructure/db/converter/SysFileConverter.java` + +--- + +## 第三阶段:服务层(Service) + +### Task 7: 创建Service接口和实现 + +**Files:** +- Create: `core/service/ISysDictTypeService.java` + `impl/SysDictTypeServiceImpl.java` +- Create: `core/service/ISysDictDataService.java` + `impl/SysDictDataServiceImpl.java` +- Create: `core/service/ISysConfigService.java` + `impl/SysConfigServiceImpl.java` +- Create: `core/service/ISysLoginLogService.java` + `impl/SysLoginLogServiceImpl.java` +- Create: `core/service/ISysExceptionLogService.java` + `impl/SysExceptionLogServiceImpl.java` +- Create: `core/service/ISysNoticeService.java` + `impl/SysNoticeServiceImpl.java` +- Create: `core/service/ISysFileService.java` + `impl/SysFileServiceImpl.java` +- Create: `core/service/ISysUserMessageService.java` + `impl/SysUserMessageServiceImpl.java` + +**核心方法:** +- CRUD操作 +- 字典: 根据类型查询数据列表 +- 配置: 根据key查询value +- 日志: 分页查询、按条件筛选 +- 消息: 查询用户未读消息 + +--- + +## 第四阶段:Handler层(API接口) + +### Task 8: 重构Handler接入数据库 + +**Files:** +- Modify: `handler/sys/SysDictHandler.java` - 注入Service替换内存Map +- Modify: `handler/sys/SysConfigHandler.java` - 注入Service替换内存Map +- Modify: `handler/sys/SysLogHandler.java` - 添加登录日志和异常日志查询 +- Modify: `handler/sys/SysNoticeHandler.java` - 注入Service替换内存Map +- Modify: `handler/sys/SysFileHandler.java` - 完善文件预览功能 + +--- + +## 第五阶段:消息推送(WebSocket) + +### Task 9: WebSocket配置 + +**Files:** +- Create: `config/WebSocketConfig.java` +- Create: `handler/websocket/WebSocketHandler.java` +- Create: `service/impl/WebSocketService.java` + +```java +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler(), "/ws") + .setAllowedOrigins("*"); + } + + @Bean + public WebSocketHandler webSocketHandler() { + return new WebSocketHandler(); + } +} +``` + +--- + +### Task 10: 消息推送Service + +**Files:** +- Create: `core/service/IWebSocketService.java` +- Create: `core/service/impl/WebSocketServiceImpl.java` + +**功能:** +- 发送消息给指定用户 +- 发送消息给所有在线用户 +- 用户上线/下线跟踪 + +--- + +## 第六阶段:完善文件预览 + +### Task 11: 文件预览支持 + +**Files:** +- Modify: `handler/sys/SysFileHandler.java` - 添加预览接口 +- 创建DTO: `dto/response/FilePreviewResponse.java` + +**预览支持:** +- 图片: 返回Base64或直接流 +- PDF: 返回PDF流 +- 文本: 返回文本内容 + +--- + +## 第七阶段:异常日志自动记录 + +### Task 12: 全局异常处理器 + +**Files:** +- Create: `handler/GlobalExceptionHandler.java` +- Create: `config/GlobalExceptionHandlerConfig.java` + +**功能:** +- 捕获所有Controller异常 +- 自动记录到sys_exception_log表 +- 返回统一格式的错误响应 + +--- + +## 第八阶段:测试 + +### Task 13: 单元测试 + +**Files:** +- Create: `test/service/SysDictTypeServiceTest.java` +- Create: `test/service/SysConfigServiceTest.java` +- Create: `test/service/SysLoginLogServiceTest.java` +- Create: `test/handler/SysDictHandlerTest.java` +- Create: `test/handler/SysNoticeHandlerTest.java` + +**测试覆盖:** +- Service层CRUD操作 +- Handler层API响应 +- 异常场景处理 + +--- + +## 实施顺序 + +1. Task 1: SQL脚本 +2. Task 2-4: Entity + Repository +3. Task 5-6: Domain + Converter +4. Task 7: Service层 +5. Task 8: Handler层重构 +6. Task 9-10: WebSocket消息推送 +7. Task 11: 文件预览 +8. Task 12: 异常日志 +9. Task 13: 测试 diff --git a/docs/sql/init.sql b/docs/sql/init.sql new file mode 100644 index 0000000..9bf3cb0 --- /dev/null +++ b/docs/sql/init.sql @@ -0,0 +1,147 @@ +-- 系统配置与审计通知中心数据库表脚本 +-- 数据库: H2/PostgreSQL + +-- 字典类型表 +CREATE TABLE IF NOT EXISTS sys_dict_type ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + dict_name VARCHAR(100) NOT NULL COMMENT '字典名称', + dict_type VARCHAR(100) NOT NULL UNIQUE COMMENT '字典类型', + status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', + remark VARCHAR(500) COMMENT '备注', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 字典数据表 +CREATE TABLE IF NOT EXISTS sys_dict_data ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + dict_sort INT DEFAULT 0 COMMENT '字典排序', + dict_label VARCHAR(100) NOT NULL COMMENT '字典标签', + dict_value VARCHAR(100) NOT NULL COMMENT '字典键值', + dict_type VARCHAR(100) NOT NULL COMMENT '字典类型', + css_class VARCHAR(100) COMMENT '样式属性', + list_class VARCHAR(100) COMMENT '表格回显样式', + is_default VARCHAR(1) DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + status VARCHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 系统配置表 +CREATE TABLE IF NOT EXISTS sys_config ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + config_name VARCHAR(100) NOT NULL COMMENT '配置名称', + config_key VARCHAR(100) NOT NULL UNIQUE COMMENT '配置键名', + config_value VARCHAR(500) NOT NULL COMMENT '配置值', + config_type VARCHAR(1) DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 登录日志表 +CREATE TABLE IF NOT EXISTS sys_login_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(50) COMMENT '用户名', + ip VARCHAR(50) COMMENT 'IP地址', + location VARCHAR(255) COMMENT '登录位置', + browser VARCHAR(50) COMMENT '浏览器类型', + os VARCHAR(50) COMMENT '操作系统', + status VARCHAR(1) COMMENT '登录状态(0成功 1失败)', + message VARCHAR(255) COMMENT '提示消息', + login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 异常日志表 +CREATE TABLE IF NOT EXISTS sys_exception_log ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(50) COMMENT '用户名', + title VARCHAR(100) COMMENT '异常标题', + exception_name VARCHAR(100) COMMENT '异常名称', + method_name VARCHAR(100) COMMENT '方法名称', + method_params TEXT COMMENT '方法参数', + exception_msg TEXT COMMENT '异常信息', + exception_stack TEXT COMMENT '堆栈信息', + ip VARCHAR(50) COMMENT 'IP地址', + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 系统公告表 +CREATE TABLE IF NOT EXISTS sys_notice ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + notice_title VARCHAR(100) NOT NULL COMMENT '公告标题', + notice_type VARCHAR(1) DEFAULT '1' COMMENT '公告类型(1通知 2公告)', + notice_content TEXT COMMENT '公告内容', + status VARCHAR(1) DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 文件管理表 +CREATE TABLE IF NOT EXISTS sys_file ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + file_name VARCHAR(255) NOT NULL COMMENT '文件名', + file_path VARCHAR(500) NOT NULL COMMENT '文件路径', + file_size VARCHAR(50) COMMENT '文件大小', + file_type VARCHAR(50) COMMENT '文件类型', + storage_type VARCHAR(20) DEFAULT 'local' COMMENT '存储类型(local/oss/s3)', + create_by VARCHAR(50) COMMENT '创建者', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 用户消息表(消息推送用) +CREATE TABLE IF NOT EXISTS sys_user_message ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL COMMENT '接收用户ID', + title VARCHAR(100) COMMENT '消息标题', + content TEXT COMMENT '消息内容', + message_type VARCHAR(1) DEFAULT '1' COMMENT '消息类型(1系统 2通知)', + is_read VARCHAR(1) DEFAULT '0' COMMENT '是否已读(0未读 1已读)', + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 初始化默认系统配置数据 +INSERT INTO sys_config (config_name, config_key, config_value, config_type) VALUES +('系统名称', 'sys.system.name', 'Novalon管理系统', 'Y'), +('系统版本', 'sys.system.version', '1.0.0', 'Y'), +('文件上传最大大小', 'sys.file.maxSize', '10485760', 'Y'), +('文件上传允许类型', 'sys.file.allowedTypes', 'jpg,jpeg,png,pdf,doc,docx,xls,xlsx', 'Y'), +('会话超时时间(分钟)', 'sys.session.timeout', '30', 'Y'), +('密码最小长度', 'sys.password.minLength', '6', 'Y'); + +-- 初始化默认字典类型 +INSERT INTO sys_dict_type (dict_name, dict_type, status, remark) VALUES +('用户性别', 'sys_user_sex', '0', '用户性别列表'), +('菜单状态', 'sys_show_hide', '0', '菜单显示状态'), +('系统开关', 'sys_normal_disable', '0', '系统开关状态'), +('任务状态', 'sys_job_status', '0', '定时任务状态'), +('任务分组', 'sys_job_group', '0', '定时任务分组'), +('系统是否', 'sys_yes_no', '0', '系统是否列表'); + +-- 初始化默认字典数据 +INSERT INTO sys_dict_data (dict_label, dict_value, dict_type, dict_sort, is_default, status) VALUES +('男', '0', 'sys_user_sex', 1, 'Y', '0'), +('女', '1', 'sys_user_sex', 2, 'N', '0'), +('未知', '2', 'sys_user_sex', 3, 'N', '0'), +('显示', '0', 'sys_show_hide', 1, 'Y', '0'), +('隐藏', '1', 'sys_show_hide', 2, 'N', '0'), +('正常', '0', 'sys_normal_disable', 1, 'Y', '0'), +('停用', '1', 'sys_normal_disable', 2, 'N', '0'), +('是', 'Y', 'sys_yes_no', 1, 'Y', '0'), +('否', 'N', 'sys_yes_no', 2, 'N', '0'); + +-- 创建索引 +CREATE INDEX idx_sys_dict_type_dict_type ON sys_dict_type(dict_type); +CREATE INDEX idx_sys_dict_data_dict_type ON sys_dict_data(dict_type); +CREATE INDEX idx_sys_config_config_key ON sys_config(config_key); +CREATE INDEX idx_sys_login_log_username ON sys_login_log(username); +CREATE INDEX idx_sys_login_log_login_time ON sys_login_log(login_time); +CREATE INDEX idx_sys_exception_log_create_time ON sys_exception_log(create_time); +CREATE INDEX idx_sys_notice_status ON sys_notice(status); +CREATE INDEX idx_sys_file_create_by ON sys_file(create_by); +CREATE INDEX idx_sys_user_message_user_id ON sys_user_message(user_id); +CREATE INDEX idx_sys_user_message_is_read ON sys_user_message(is_read); diff --git a/e2e_tests/.env.example b/e2e_tests/.env.example new file mode 100644 index 0000000..f1f4ed1 --- /dev/null +++ b/e2e_tests/.env.example @@ -0,0 +1,22 @@ +# E2E测试环境配置 + +# API配置 +API_BASE_URL=http://localhost:8080 + +# 数据库配置 +DATABASE_HOST=localhost +DATABASE_PORT=5432 +DATABASE_NAME=manage_system +DATABASE_USERNAME=postgres +DATABASE_PASSWORD=postgres + +# 测试用户凭证 +TEST_USERNAME=admin +TEST_PASSWORD=admin123 + +# 浏览器配置 +HEADLESS_BROWSER=true +BROWSER_TYPE=chromium + +# 超时配置(毫秒) +REQUEST_TIMEOUT=30000 diff --git a/e2e_tests/.gitignore b/e2e_tests/.gitignore new file mode 100644 index 0000000..41570c4 --- /dev/null +++ b/e2e_tests/.gitignore @@ -0,0 +1,55 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ +ENV/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Pytest +.pytest_cache/ +.coverage +htmlcov/ +*.cover +.hypothesis/ + +# Allure +allure-results/ +allure-report/ + +# Logs +*.log + +# Environment variables +.env + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Playwright +.playwright/ diff --git a/e2e_tests/README.md b/e2e_tests/README.md new file mode 100644 index 0000000..d6473ff --- /dev/null +++ b/e2e_tests/README.md @@ -0,0 +1,104 @@ +# E2E测试项目 + +## 项目概述 + +本项目使用Python + Playwright框架对Novalon管理系统进行端到端测试。 + +## 技术栈 + +- **Python**: 3.9+ +- **Playwright**: 1.40+ +- **Pytest**: 7.0+ +- **Allure**: 测试报告 + +## 项目结构 + +``` +e2e_tests/ +├── __init__.py +├── conftest.py # Pytest配置和fixtures +├── pytest.ini # Pytest配置文件 +├── requirements.txt # Python依赖 +├── config/ +│ ├── __init__.py +│ └── settings.py # 配置管理 +├── pages/ +│ ├── __init__.py +│ ├── base_page.py # 基础页面类 +│ ├── auth_page.py # 认证相关页面 +│ ├── user_page.py # 用户管理页面 +│ ├── role_page.py # 角色管理页面 +│ └── dictionary_page.py # 字典管理页面 +├── api/ +│ ├── __init__.py +│ ├── base_api.py # 基础API类 +│ ├── auth_api.py # 认证API +│ ├── user_api.py # 用户API +│ ├── role_api.py # 角色API +│ └── dictionary_api.py # 字典API +├── tests/ +│ ├── __init__.py +│ ├── test_auth.py # 认证测试 +│ ├── test_user.py # 用户管理测试 +│ ├── test_role.py # 角色管理测试 +│ ├── test_dictionary.py # 字典管理测试 +│ └── test_oauth2.py # OAuth2测试 +├── utils/ +│ ├── __init__.py +│ ├── data_generator.py # 测试数据生成器 +│ ├── assertions.py # 断言工具 +│ └── logger.py # 日志工具 +└── reports/ # 测试报告目录 +``` + +## 安装依赖 + +```bash +# 安装Python依赖 +pip install -r requirements.txt + +# 安装Playwright浏览器 +playwright install +``` + +## 运行测试 + +```bash +# 运行所有测试 +pytest + +# 运行特定测试文件 +pytest tests/test_auth.py + +# 运行特定测试用例 +pytest tests/test_auth.py::test_login_success + +# 生成Allure报告 +pytest --alluredir=allure-results +allure serve allure-results + +# 并发运行测试 +pytest -n auto +``` + +## 配置说明 + +在 `config/settings.py` 中配置: +- API基础URL +- 测试数据库连接 +- 测试用户凭证 +- 超时设置 + +## 测试数据管理 + +测试数据自动准备和清理: +- 每个测试用例独立运行 +- 使用fixture自动创建和清理测试数据 +- 支持数据回滚 + +## 持续集成 + +测试可在CI/CD流程中自动运行: +- GitHub Actions +- GitLab CI +- Jenkins diff --git a/e2e_tests/__init__.py b/e2e_tests/__init__.py new file mode 100644 index 0000000..89e6c1d --- /dev/null +++ b/e2e_tests/__init__.py @@ -0,0 +1,6 @@ +""" +E2E测试项目 - Novalon管理系统 +使用Playwright进行端到端测试 +""" + +__version__ = "1.0.0" diff --git a/e2e_tests/api/__init__.py b/e2e_tests/api/__init__.py new file mode 100644 index 0000000..c057860 --- /dev/null +++ b/e2e_tests/api/__init__.py @@ -0,0 +1 @@ +"""API模块""" diff --git a/e2e_tests/api/auth_api.py b/e2e_tests/api/auth_api.py new file mode 100644 index 0000000..46912da --- /dev/null +++ b/e2e_tests/api/auth_api.py @@ -0,0 +1,33 @@ +""" +认证API +""" + +from typing import Dict, Any +from httpx import AsyncClient, Response +from .base_api import BaseAPI + + +class AuthAPI(BaseAPI): + """认证API""" + + def __init__(self, client: AsyncClient): + super().__init__(client, "/api/auth") + + async def login(self, username: str, password: str) -> Response: + """用户登录""" + return await self.post("/login", json={ + "username": username, + "password": password + }) + + async def refresh_token(self, refresh_token: str) -> Response: + """刷新token""" + return await self.post("/refresh", json={ + "refreshToken": refresh_token + }) + + async def logout(self, token: str) -> Response: + """用户登出""" + return await self.post("/logout", headers={ + "Authorization": f"Bearer {token}" + }) diff --git a/e2e_tests/api/base_api.py b/e2e_tests/api/base_api.py new file mode 100644 index 0000000..e8e7684 --- /dev/null +++ b/e2e_tests/api/base_api.py @@ -0,0 +1,58 @@ +""" +基础API类 +""" + +from typing import Optional, Dict, Any +from httpx import AsyncClient, Response +from loguru import logger + + +class BaseAPI: + """基础API类""" + + def __init__(self, client: AsyncClient, base_url: str = ""): + self.client = client + self.base_url = base_url + + async def get(self, endpoint: str, params: Optional[Dict[str, Any]] = None, **kwargs) -> Response: + """GET请求""" + url = f"{self.base_url}{endpoint}" + logger.info(f"GET {url} - Params: {params}") + response = await self.client.get(url, params=params, **kwargs) + logger.info(f"Response: {response.status_code}") + return response + + async def post(self, endpoint: str, data: Optional[Dict[str, Any]] = None, json: Optional[Dict[str, Any]] = None, **kwargs) -> Response: + """POST请求""" + url = f"{self.base_url}{endpoint}" + logger.info(f"POST {url} - Data: {data} - JSON: {json}") + response = await self.client.post(url, data=data, json=json, **kwargs) + logger.info(f"Response: {response.status_code}") + return response + + async def put(self, endpoint: str, data: Optional[Dict[str, Any]] = None, json: Optional[Dict[str, Any]] = None, **kwargs) -> Response: + """PUT请求""" + url = f"{self.base_url}{endpoint}" + logger.info(f"PUT {url} - Data: {data} - JSON: {json}") + response = await self.client.put(url, data=data, json=json, **kwargs) + logger.info(f"Response: {response.status_code}") + return response + + async def delete(self, endpoint: str, **kwargs) -> Response: + """DELETE请求""" + url = f"{self.base_url}{endpoint}" + logger.info(f"DELETE {url}") + response = await self.client.delete(url, **kwargs) + logger.info(f"Response: {response.status_code}") + return response + + async def assert_status_code(self, response: Response, expected_status: int): + """断言状态码""" + assert response.status_code == expected_status, f"Expected {expected_status}, got {response.status_code}. Response: {response.text}" + + async def assert_response_contains(self, response: Response, key: str, value: Any = None): + """断言响应包含指定字段""" + data = response.json() + assert key in data, f"Response does not contain key '{key}'" + if value is not None: + assert data[key] == value, f"Expected {value}, got {data[key]}" diff --git a/e2e_tests/api/dictionary_api.py b/e2e_tests/api/dictionary_api.py new file mode 100644 index 0000000..4e5fc95 --- /dev/null +++ b/e2e_tests/api/dictionary_api.py @@ -0,0 +1,42 @@ +""" +字典管理API +""" + +from typing import Dict, Any +from httpx import AsyncClient, Response +from .base_api import BaseAPI + + +class DictionaryAPI(BaseAPI): + """字典管理API""" + + def __init__(self, client: AsyncClient): + super().__init__(client, "/api/dictionaries") + + async def create_dictionary(self, dict_data: Dict[str, Any]) -> Response: + """创建字典""" + return await self.post("", json=dict_data) + + async def get_dictionary_by_id(self, dict_id: int) -> Response: + """根据ID获取字典""" + return await self.get(f"/{dict_id}") + + async def get_dictionaries_by_type(self, dict_type: str) -> Response: + """根据类型获取字典""" + return await self.get(f"/type/{dict_type}") + + async def get_all_dictionaries(self) -> Response: + """获取所有字典""" + return await self.get("") + + async def update_dictionary(self, dict_id: int, dict_data: Dict[str, Any]) -> Response: + """更新字典""" + return await self.put(f"/{dict_id}", json=dict_data) + + async def delete_dictionary(self, dict_id: int) -> Response: + """删除字典""" + return await self.delete(f"/{dict_id}") + + async def check_type_and_code_exists(self, dict_type: str, code: str) -> Response: + """检查类型和编码是否存在""" + return await self.get("/check/exists", params={"type": dict_type, "code": code}) diff --git a/e2e_tests/api/role_api.py b/e2e_tests/api/role_api.py new file mode 100644 index 0000000..8904194 --- /dev/null +++ b/e2e_tests/api/role_api.py @@ -0,0 +1,58 @@ +""" +角色管理API +""" + +from typing import Dict, Any, List +from httpx import AsyncClient, Response +from .base_api import BaseAPI + + +class RoleAPI(BaseAPI): + """角色管理API""" + + def __init__(self, client: AsyncClient): + super().__init__(client, "/api/roles") + + async def create_role(self, role_data: Dict[str, Any]) -> Response: + """创建角色""" + return await self.post("", json=role_data) + + async def get_role_by_id(self, role_id: int) -> Response: + """根据ID获取角色""" + return await self.get(f"/{role_id}") + + async def get_role_by_name(self, role_name: str) -> Response: + """根据名称获取角色""" + return await self.get(f"/name/{role_name}") + + async def get_all_roles(self, include_deleted: bool = False) -> Response: + """获取所有角色""" + return await self.get("", params={"includeDeleted": include_deleted}) + + async def update_role(self, role_id: int, role_data: Dict[str, Any]) -> Response: + """更新角色""" + return await self.put(f"/{role_id}", json=role_data) + + async def delete_role(self, role_id: int) -> Response: + """删除角色""" + return await self.delete(f"/{role_id}") + + async def logical_delete_role(self, role_id: int) -> Response: + """逻辑删除角色""" + return await self.delete(f"/{role_id}/logical") + + async def logical_delete_roles(self, role_ids: List[int]) -> Response: + """批量逻辑删除角色""" + return await self.post("/logical-delete", json=role_ids) + + async def restore_role(self, role_id: int) -> Response: + """恢复角色""" + return await self.post(f"/{role_id}/restore") + + async def restore_roles(self, role_ids: List[int]) -> Response: + """批量恢复角色""" + return await self.post("/restore", json=role_ids) + + async def check_name_exists(self, role_name: str) -> Response: + """检查角色名是否存在""" + return await self.get("/check/name", params={"name": role_name}) diff --git a/e2e_tests/api/user_api.py b/e2e_tests/api/user_api.py new file mode 100644 index 0000000..0e348fe --- /dev/null +++ b/e2e_tests/api/user_api.py @@ -0,0 +1,58 @@ +""" +用户管理API +""" + +from typing import Dict, Any, List +from httpx import AsyncClient, Response +from .base_api import BaseAPI + + +class UserAPI(BaseAPI): + """用户管理API""" + + def __init__(self, client: AsyncClient): + super().__init__(client, "/api/users") + + async def create_user(self, user_data: Dict[str, Any]) -> Response: + """创建用户""" + return await self.post("", json=user_data) + + async def get_user_by_id(self, user_id: int) -> Response: + """根据ID获取用户""" + return await self.get(f"/{user_id}") + + async def get_all_users(self, include_deleted: bool = False) -> Response: + """获取所有用户""" + return await self.get("", params={"includeDeleted": include_deleted}) + + async def update_user(self, user_id: int, user_data: Dict[str, Any]) -> Response: + """更新用户""" + return await self.put(f"/{user_id}", json=user_data) + + async def delete_user(self, user_id: int) -> Response: + """删除用户""" + return await self.delete(f"/{user_id}") + + async def logical_delete_user(self, user_id: int) -> Response: + """逻辑删除用户""" + return await self.delete(f"/{user_id}/logical") + + async def logical_delete_users(self, user_ids: List[int]) -> Response: + """批量逻辑删除用户""" + return await self.post("/logical-delete", json=user_ids) + + async def restore_user(self, user_id: int) -> Response: + """恢复用户""" + return await self.post(f"/{user_id}/restore") + + async def restore_users(self, user_ids: List[int]) -> Response: + """批量恢复用户""" + return await self.post("/restore", json=user_ids) + + async def check_username_exists(self, username: str) -> Response: + """检查用户名是否存在""" + return await self.get("/check/username", params={"username": username}) + + async def check_email_exists(self, email: str) -> Response: + """检查邮箱是否存在""" + return await self.get("/check/email", params={"email": email}) diff --git a/e2e_tests/config/__init__.py b/e2e_tests/config/__init__.py new file mode 100644 index 0000000..439b927 --- /dev/null +++ b/e2e_tests/config/__init__.py @@ -0,0 +1 @@ +"""配置模块""" diff --git a/e2e_tests/config/settings.py b/e2e_tests/config/settings.py new file mode 100644 index 0000000..0311082 --- /dev/null +++ b/e2e_tests/config/settings.py @@ -0,0 +1,74 @@ +""" +配置管理模块 +""" + +import os +from typing import Optional +from pydantic_settings import BaseSettings +from pydantic import Field + + +class Settings(BaseSettings): + """应用配置""" + + API_BASE_URL: str = Field( + default="http://localhost:8080", + description="API基础URL" + ) + + DATABASE_HOST: str = Field( + default="localhost", + description="数据库主机" + ) + + DATABASE_PORT: int = Field( + default=55432, + description="数据库端口" + ) + + DATABASE_NAME: str = Field( + default="manage_system", + description="数据库名称" + ) + + DATABASE_USERNAME: str = Field( + default="postgres", + description="数据库用户名" + ) + + DATABASE_PASSWORD: str = Field( + default="postgres", + description="数据库密码" + ) + + TEST_USERNAME: str = Field( + default="admin", + description="测试用户名" + ) + + TEST_PASSWORD: str = Field( + default="admin123", + description="测试用户密码" + ) + + REQUEST_TIMEOUT: int = Field( + default=30000, + description="请求超时时间(毫秒)" + ) + + HEADLESS_BROWSER: bool = Field( + default=True, + description="无头浏览器模式" + ) + + BROWSER_TYPE: str = Field( + default="chromium", + description="浏览器类型" + ) + + class Config: + env_file = ".env" + env_file_encoding = "utf-8" + + +settings = Settings() diff --git a/e2e_tests/conftest.py b/e2e_tests/conftest.py new file mode 100644 index 0000000..b4a7d6c --- /dev/null +++ b/e2e_tests/conftest.py @@ -0,0 +1,161 @@ +""" +Pytest配置和fixtures +""" + +import asyncio +import pytest +from typing import AsyncGenerator, Generator +from playwright.async_api import async_playwright, Browser, BrowserContext, Page +from httpx import AsyncClient + +from config.settings import settings + + +@pytest.fixture(scope="session") +def event_loop(): + """创建事件循环""" + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + loop.close() + + +@pytest.fixture(scope="session") +async def browser() -> AsyncGenerator[Browser, None]: + """浏览器fixture""" + async with async_playwright() as p: + browser = await p.launch( + headless=settings.HEADLESS_BROWSER, + browser_type=settings.BROWSER_TYPE + ) + yield browser + await browser.close() + + +@pytest.fixture +async def context(browser: Browser) -> AsyncGenerator[BrowserContext, None]: + """浏览器上下文fixture""" + context = await browser.new_context() + yield context + await context.close() + + +@pytest.fixture +async def page(context: BrowserContext) -> AsyncGenerator[Page, None]: + """页面fixture""" + page = await context.new_page() + page.set_default_timeout(settings.REQUEST_TIMEOUT) + yield page + await page.close() + + +@pytest.fixture +async def http_client() -> AsyncGenerator[AsyncClient, None]: + """HTTP客户端fixture""" + async with AsyncClient( + base_url=settings.API_BASE_URL, + timeout=settings.REQUEST_TIMEOUT / 1000 + ) as client: + yield client + + +@pytest.fixture +async def auth_token(http_client: AsyncClient) -> str: + """获取认证token""" + response = await http_client.post( + "/api/auth/login", + json={ + "username": settings.TEST_USERNAME, + "password": settings.TEST_PASSWORD + } + ) + assert response.status_code == 200 + data = response.json() + return data.get("accessToken") + + +@pytest.fixture +async def authenticated_client(http_client: AsyncClient, auth_token: str) -> AsyncClient: + """已认证的HTTP客户端""" + http_client.headers.update({"Authorization": f"Bearer {auth_token}"}) + return http_client + + +@pytest.fixture +def test_user_data(): + """测试用户数据""" + import time + timestamp = int(time.time() * 1000) + return { + "username": f"testuser_{timestamp}", + "password": "password123", + "email": f"test_{timestamp}@example.com", + "roleId": 2, + "status": 1 + } + + +@pytest.fixture +def test_role_data(): + """测试角色数据""" + import time + timestamp = int(time.time() * 1000) + return { + "name": f"TEST_ROLE_{timestamp}", + "description": "测试角色", + "permissions": "READ,WRITE" + } + + +@pytest.fixture +def test_dictionary_data(): + """测试字典数据""" + return { + "type": "USER_STATUS", + "code": "ACTIVE", + "name": "激活", + "value": "1", + "remark": "用户激活状态", + "sort": 1 + } + + +@pytest.fixture +async def cleanup_user(authenticated_client: AsyncClient): + """清理测试用户""" + user_ids = [] + + yield user_ids + + for user_id in user_ids: + try: + await authenticated_client.delete(f"/api/users/{user_id}") + except Exception: + pass + + +@pytest.fixture +async def cleanup_role(authenticated_client: AsyncClient): + """清理测试角色""" + role_ids = [] + + yield role_ids + + for role_id in role_ids: + try: + await authenticated_client.delete(f"/api/roles/{role_id}") + except Exception: + pass + + +@pytest.fixture +async def cleanup_dictionary(authenticated_client: AsyncClient): + """清理测试字典""" + dict_ids = [] + + yield dict_ids + + for dict_id in dict_ids: + try: + await authenticated_client.delete(f"/api/dictionaries/{dict_id}") + except Exception: + pass diff --git a/e2e_tests/pytest.ini b/e2e_tests/pytest.ini new file mode 100644 index 0000000..96c0250 --- /dev/null +++ b/e2e_tests/pytest.ini @@ -0,0 +1,23 @@ +[pytest] +testpaths = tests +python_files = test_*.py +python_classes = Test* +python_functions = test_* +addopts = + -v + --strict-markers + --tb=short + --cov=. + --cov-report=html + --cov-report=term-missing + --alluredir=allure-results +markers = + auth: 认证相关测试 + user: 用户管理测试 + role: 角色管理测试 + dictionary: 字典管理测试 + oauth2: OAuth2相关测试 + smoke: 冒烟测试 + regression: 回归测试 + slow: 慢速测试 +asyncio_mode = auto diff --git a/e2e_tests/requirements.txt b/e2e_tests/requirements.txt new file mode 100644 index 0000000..6ad86da --- /dev/null +++ b/e2e_tests/requirements.txt @@ -0,0 +1,29 @@ +# Python依赖包 + +# 测试框架 +pytest==7.4.3 +pytest-asyncio==0.21.1 +pytest-cov==4.1.0 +pytest-xdist==3.5.0 + +# Playwright +playwright==1.40.0 + +# HTTP客户端 +httpx==0.25.2 +requests==2.31.0 + +# 数据处理 +pydantic==2.5.2 +pydantic-settings==2.1.0 +faker==20.1.0 + +# 配置管理 +python-dotenv==1.0.0 +pyyaml==6.0.1 + +# 测试报告 +allure-pytest==2.13.2 + +# 工具库 +loguru==0.7.2 diff --git a/e2e_tests/tests/__init__.py b/e2e_tests/tests/__init__.py new file mode 100644 index 0000000..412ecbc --- /dev/null +++ b/e2e_tests/tests/__init__.py @@ -0,0 +1 @@ +"""测试模块""" diff --git a/e2e_tests/tests/test_auth.py b/e2e_tests/tests/test_auth.py new file mode 100644 index 0000000..3e9534b --- /dev/null +++ b/e2e_tests/tests/test_auth.py @@ -0,0 +1,83 @@ +""" +认证测试用例 +""" + +import pytest +from api.auth_api import AuthAPI +from config.settings import settings + + +@pytest.mark.auth +@pytest.mark.smoke +class TestAuth: + """认证测试类""" + + @pytest.mark.asyncio + async def test_login_success(self, http_client): + """测试成功登录""" + auth_api = AuthAPI(http_client) + response = await auth_api.login(settings.TEST_USERNAME, settings.TEST_PASSWORD) + + assert response.status_code == 200 + data = response.json() + assert "accessToken" in data + assert "refreshToken" in data + assert isinstance(data["accessToken"], str) + assert isinstance(data["refreshToken"], str) + + @pytest.mark.asyncio + async def test_login_invalid_credentials(self, http_client): + """测试无效凭证登录""" + auth_api = AuthAPI(http_client) + response = await auth_api.login("invalid_user", "invalid_password") + + assert response.status_code == 401 + + @pytest.mark.asyncio + async def test_login_missing_fields(self, http_client): + """测试缺少必填字段""" + auth_api = AuthAPI(http_client) + response = await http_client.post("/api/auth/login", json={ + "username": "test" + }) + + assert response.status_code == 400 + + @pytest.mark.asyncio + async def test_refresh_token_success(self, http_client, auth_token): + """测试刷新token成功""" + auth_api = AuthAPI(http_client) + + login_response = await auth_api.login(settings.TEST_USERNAME, settings.TEST_PASSWORD) + refresh_token = login_response.json().get("refreshToken") + + response = await auth_api.refresh_token(refresh_token) + + assert response.status_code == 200 + data = response.json() + assert "accessToken" in data + assert "refreshToken" in data + + @pytest.mark.asyncio + async def test_refresh_token_invalid(self, http_client): + """测试无效刷新token""" + auth_api = AuthAPI(http_client) + response = await auth_api.refresh_token("invalid_refresh_token") + + assert response.status_code == 401 + + @pytest.mark.asyncio + async def test_logout_success(self, http_client, auth_token): + """测试登出成功""" + auth_api = AuthAPI(http_client) + response = await auth_api.logout(auth_token) + + assert response.status_code == 200 + + @pytest.mark.asyncio + async def test_logout_without_token(self, http_client): + """测试无token登出""" + auth_api = AuthAPI(http_client) + response = await http_client.post("/api/auth/logout") + + assert response.status_code == 400 diff --git a/e2e_tests/tests/test_dictionary.py b/e2e_tests/tests/test_dictionary.py new file mode 100644 index 0000000..bfdfaac --- /dev/null +++ b/e2e_tests/tests/test_dictionary.py @@ -0,0 +1,149 @@ +""" +字典管理测试用例 +""" + +import pytest +from api.dictionary_api import DictionaryAPI + + +@pytest.mark.dictionary +@pytest.mark.regression +class TestDictionary: + """字典管理测试类""" + + @pytest.mark.asyncio + async def test_create_dictionary_success(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试创建字典成功""" + dict_api = DictionaryAPI(authenticated_client) + response = await dict_api.create_dictionary(test_dictionary_data) + + assert response.status_code == 201 + data = response.json() + assert "id" in data + assert data["type"] == test_dictionary_data["type"] + assert data["code"] == test_dictionary_data["code"] + assert data["name"] == test_dictionary_data["name"] + + cleanup_dictionary.append(data["id"]) + + @pytest.mark.asyncio + async def test_create_dictionary_duplicate_type_code(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试创建重复类型和编码""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + response = await dict_api.create_dictionary(test_dictionary_data) + + assert response.status_code in [400, 409] + + cleanup_dictionary.append(dict_id) + + @pytest.mark.asyncio + async def test_get_dictionary_by_id_success(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试根据ID获取字典成功""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + response = await dict_api.get_dictionary_by_id(dict_id) + + assert response.status_code == 200 + data = response.json() + assert data["id"] == dict_id + assert data["type"] == test_dictionary_data["type"] + + cleanup_dictionary.append(dict_id) + + @pytest.mark.asyncio + async def test_get_dictionary_by_id_not_found(self, authenticated_client): + """测试获取不存在的字典""" + dict_api = DictionaryAPI(authenticated_client) + response = await dict_api.get_dictionary_by_id(999999) + + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_get_dictionaries_by_type_success(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试根据类型获取字典成功""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + response = await dict_api.get_dictionaries_by_type(test_dictionary_data["type"]) + + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + assert any(d["id"] == dict_id for d in data) + + cleanup_dictionary.append(dict_id) + + @pytest.mark.asyncio + async def test_get_all_dictionaries_success(self, authenticated_client): + """测试获取所有字典成功""" + dict_api = DictionaryAPI(authenticated_client) + response = await dict_api.get_all_dictionaries() + + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + + @pytest.mark.asyncio + async def test_update_dictionary_success(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试更新字典成功""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + update_data = {"name": "Updated name"} + response = await dict_api.update_dictionary(dict_id, update_data) + + assert response.status_code == 200 + data = response.json() + assert data["name"] == "Updated name" + + cleanup_dictionary.append(dict_id) + + @pytest.mark.asyncio + async def test_delete_dictionary_success(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试删除字典成功""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + response = await dict_api.delete_dictionary(dict_id) + + assert response.status_code == 204 + + @pytest.mark.asyncio + async def test_check_type_and_code_exists_true(self, authenticated_client, test_dictionary_data, cleanup_dictionary): + """测试检查类型和编码存在-返回true""" + dict_api = DictionaryAPI(authenticated_client) + + create_response = await dict_api.create_dictionary(test_dictionary_data) + dict_id = create_response.json()["id"] + + response = await dict_api.check_type_and_code_exists( + test_dictionary_data["type"], + test_dictionary_data["code"] + ) + + assert response.status_code == 200 + assert response.json() is True + + cleanup_dictionary.append(dict_id) + + @pytest.mark.asyncio + async def test_check_type_and_code_exists_false(self, authenticated_client): + """测试检查类型和编码存在-返回false""" + dict_api = DictionaryAPI(authenticated_client) + response = await dict_api.check_type_and_code_exists("NONEXISTENT_TYPE", "NONEXISTENT_CODE") + + assert response.status_code == 200 + assert response.json() is False diff --git a/e2e_tests/tests/test_oauth2.py b/e2e_tests/tests/test_oauth2.py new file mode 100644 index 0000000..676bdd1 --- /dev/null +++ b/e2e_tests/tests/test_oauth2.py @@ -0,0 +1,127 @@ +""" +OAuth2客户端管理测试用例 +""" + +import pytest +from httpx import AsyncClient + + +@pytest.mark.oauth2 +@pytest.mark.regression +class TestOAuth2: + """OAuth2客户端管理测试类""" + + @pytest.fixture + def test_oauth2_client_data(self): + """测试OAuth2客户端数据""" + import time + timestamp = int(time.time() * 1000) + return { + "clientId": f"test-client-{timestamp}", + "clientSecret": "secret123", + "clientName": "Test Client", + "webServerRedirectUri": "http://localhost:8080/callback", + "scope": "read,write", + "authorizedGrantTypes": "authorization_code,refresh_token", + "accessTokenValiditySeconds": 7200, + "refreshTokenValiditySeconds": 2592000, + "autoApprove": False, + "enabled": True + } + + @pytest.fixture + async def cleanup_oauth2_client(self, authenticated_client: AsyncClient): + """清理测试OAuth2客户端""" + client_ids = [] + + yield client_ids + + for client_id in client_ids: + try: + await authenticated_client.delete(f"/api/oauth2/clients/{client_id}") + except Exception: + pass + + @pytest.mark.asyncio + async def test_create_oauth2_client_success(self, authenticated_client, test_oauth2_client_data, cleanup_oauth2_client): + """测试创建OAuth2客户端成功""" + response = await authenticated_client.post("/api/oauth2/clients", json=test_oauth2_client_data) + + assert response.status_code == 201 + data = response.json() + assert "id" in data + assert data["clientId"] == test_oauth2_client_data["clientId"] + assert data["clientName"] == test_oauth2_client_data["clientName"] + assert "clientSecret" not in data or data["clientSecret"] != test_oauth2_client_data["clientSecret"] + + cleanup_oauth2_client.append(data["id"]) + + @pytest.mark.asyncio + async def test_get_oauth2_client_by_id_success(self, authenticated_client, test_oauth2_client_data, cleanup_oauth2_client): + """测试根据ID获取OAuth2客户端成功""" + create_response = await authenticated_client.post("/api/oauth2/clients", json=test_oauth2_client_data) + client_id = create_response.json()["id"] + + response = await authenticated_client.get(f"/api/oauth2/clients/{client_id}") + + assert response.status_code == 200 + data = response.json() + assert data["id"] == client_id + assert data["clientId"] == test_oauth2_client_data["clientId"] + + cleanup_oauth2_client.append(client_id) + + @pytest.mark.asyncio + async def test_get_oauth2_client_by_id_not_found(self, authenticated_client): + """测试获取不存在的OAuth2客户端""" + response = await authenticated_client.get("/api/oauth2/clients/999999") + + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_get_oauth2_client_by_client_id_success(self, authenticated_client, test_oauth2_client_data, cleanup_oauth2_client): + """测试根据clientId获取OAuth2客户端成功""" + create_response = await authenticated_client.post("/api/oauth2/clients", json=test_oauth2_client_data) + client_id = create_response.json()["id"] + + response = await authenticated_client.get(f"/api/oauth2/clients/client-id/{test_oauth2_client_data['clientId']}") + + assert response.status_code == 200 + data = response.json() + assert data["clientId"] == test_oauth2_client_data["clientId"] + + cleanup_oauth2_client.append(client_id) + + @pytest.mark.asyncio + async def test_get_all_oauth2_clients_success(self, authenticated_client): + """测试获取所有OAuth2客户端成功""" + response = await authenticated_client.get("/api/oauth2/clients") + + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + + @pytest.mark.asyncio + async def test_update_oauth2_client_success(self, authenticated_client, test_oauth2_client_data, cleanup_oauth2_client): + """测试更新OAuth2客户端成功""" + create_response = await authenticated_client.post("/api/oauth2/clients", json=test_oauth2_client_data) + client_id = create_response.json()["id"] + + update_data = {"clientName": "Updated Client Name"} + response = await authenticated_client.put(f"/api/oauth2/clients/{client_id}", json=update_data) + + assert response.status_code == 200 + data = response.json() + assert data["clientName"] == "Updated Client Name" + + cleanup_oauth2_client.append(client_id) + + @pytest.mark.asyncio + async def test_delete_oauth2_client_success(self, authenticated_client, test_oauth2_client_data, cleanup_oauth2_client): + """测试删除OAuth2客户端成功""" + create_response = await authenticated_client.post("/api/oauth2/clients", json=test_oauth2_client_data) + client_id = create_response.json()["id"] + + response = await authenticated_client.delete(f"/api/oauth2/clients/{client_id}") + + assert response.status_code == 204 diff --git a/e2e_tests/tests/test_role.py b/e2e_tests/tests/test_role.py new file mode 100644 index 0000000..386d3a2 --- /dev/null +++ b/e2e_tests/tests/test_role.py @@ -0,0 +1,185 @@ +""" +角色管理测试用例 +""" + +import pytest +from api.role_api import RoleAPI + + +@pytest.mark.role +@pytest.mark.regression +class TestRole: + """角色管理测试类""" + + @pytest.mark.asyncio + async def test_create_role_success(self, authenticated_client, test_role_data, cleanup_role): + """测试创建角色成功""" + role_api = RoleAPI(authenticated_client) + response = await role_api.create_role(test_role_data) + + assert response.status_code == 201 + data = response.json() + assert "id" in data + assert data["name"] == test_role_data["name"] + assert data["description"] == test_role_data["description"] + assert data["permissions"] == test_role_data["permissions"] + + cleanup_role.append(data["id"]) + + @pytest.mark.asyncio + async def test_create_role_duplicate_name(self, authenticated_client, test_role_data, cleanup_role): + """测试创建重复角色名""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.create_role(test_role_data) + + assert response.status_code in [400, 409] + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_get_role_by_id_success(self, authenticated_client, test_role_data, cleanup_role): + """测试根据ID获取角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.get_role_by_id(role_id) + + assert response.status_code == 200 + data = response.json() + assert data["id"] == role_id + assert data["name"] == test_role_data["name"] + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_get_role_by_id_not_found(self, authenticated_client): + """测试获取不存在的角色""" + role_api = RoleAPI(authenticated_client) + response = await role_api.get_role_by_id(999999) + + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_get_role_by_name_success(self, authenticated_client, test_role_data, cleanup_role): + """测试根据名称获取角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.get_role_by_name(test_role_data["name"]) + + assert response.status_code == 200 + data = response.json() + assert data["name"] == test_role_data["name"] + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_get_all_roles_success(self, authenticated_client): + """测试获取所有角色成功""" + role_api = RoleAPI(authenticated_client) + response = await role_api.get_all_roles() + + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + + @pytest.mark.asyncio + async def test_update_role_success(self, authenticated_client, test_role_data, cleanup_role): + """测试更新角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + update_data = {"description": "Updated description"} + response = await role_api.update_role(role_id, update_data) + + assert response.status_code == 200 + data = response.json() + assert data["description"] == "Updated description" + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_delete_role_success(self, authenticated_client, test_role_data, cleanup_role): + """测试删除角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.delete_role(role_id) + + assert response.status_code == 204 + + @pytest.mark.asyncio + async def test_logical_delete_role_success(self, authenticated_client, test_role_data, cleanup_role): + """测试逻辑删除角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.logical_delete_role(role_id) + + assert response.status_code == 200 + + get_response = await role_api.get_role_by_id(role_id) + assert get_response.status_code == 404 + + get_deleted_response = await role_api.get_all_roles(include_deleted=True) + deleted_roles = get_deleted_response.json() + assert any(r["id"] == role_id for r in deleted_roles) + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_restore_role_success(self, authenticated_client, test_role_data, cleanup_role): + """测试恢复角色成功""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + await role_api.logical_delete_role(role_id) + + response = await role_api.restore_role(role_id) + + assert response.status_code == 200 + + get_response = await role_api.get_role_by_id(role_id) + assert get_response.status_code == 200 + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_check_name_exists_true(self, authenticated_client, test_role_data, cleanup_role): + """测试检查角色名存在-返回true""" + role_api = RoleAPI(authenticated_client) + + create_response = await role_api.create_role(test_role_data) + role_id = create_response.json()["id"] + + response = await role_api.check_name_exists(test_role_data["name"]) + + assert response.status_code == 200 + assert response.json() is True + + cleanup_role.append(role_id) + + @pytest.mark.asyncio + async def test_check_name_exists_false(self, authenticated_client): + """测试检查角色名存在-返回false""" + role_api = RoleAPI(authenticated_client) + response = await role_api.check_name_exists("NONEXISTENT_ROLE") + + assert response.status_code == 200 + assert response.json() is False diff --git a/e2e_tests/tests/test_user.py b/e2e_tests/tests/test_user.py new file mode 100644 index 0000000..3b6f44e --- /dev/null +++ b/e2e_tests/tests/test_user.py @@ -0,0 +1,193 @@ +""" +用户管理测试用例 +""" + +import pytest +from api.user_api import UserAPI +from config.settings import settings + + +@pytest.mark.user +@pytest.mark.regression +class TestUser: + """用户管理测试类""" + + @pytest.mark.asyncio + async def test_create_user_success(self, authenticated_client, test_user_data, cleanup_user): + """测试创建用户成功""" + user_api = UserAPI(authenticated_client) + response = await user_api.create_user(test_user_data) + + print(f"Response status: {response.status_code}") + print(f"Response text: {response.text}") + + assert response.status_code == 201 + data = response.json() + assert "id" in data + assert data["username"] == test_user_data["username"] + assert data["email"] == test_user_data["email"] + assert "password" not in data or data["password"] != test_user_data["password"] + + cleanup_user.append(data["id"]) + + @pytest.mark.asyncio + async def test_create_user_duplicate_username(self, authenticated_client, test_user_data, cleanup_user): + """测试创建重复用户名""" + user_api = UserAPI(authenticated_client) + + await user_api.create_user(test_user_data) + response = await user_api.create_user(test_user_data) + + assert response.status_code in [400, 409] + + @pytest.mark.asyncio + async def test_get_user_by_id_success(self, authenticated_client, test_user_data, cleanup_user): + """测试根据ID获取用户成功""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + response = await user_api.get_user_by_id(user_id) + + assert response.status_code == 200 + data = response.json() + assert data["id"] == user_id + assert data["username"] == test_user_data["username"] + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_get_user_by_id_not_found(self, authenticated_client): + """测试获取不存在的用户""" + user_api = UserAPI(authenticated_client) + response = await user_api.get_user_by_id(999999) + + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_get_all_users_success(self, authenticated_client): + """测试获取所有用户成功""" + user_api = UserAPI(authenticated_client) + response = await user_api.get_all_users() + + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + + @pytest.mark.asyncio + async def test_update_user_success(self, authenticated_client, test_user_data, cleanup_user): + """测试更新用户成功""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + update_data = {"email": "updated@example.com"} + response = await user_api.update_user(user_id, update_data) + + assert response.status_code == 200 + data = response.json() + assert data["email"] == "updated@example.com" + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_delete_user_success(self, authenticated_client, test_user_data, cleanup_user): + """测试删除用户成功""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + response = await user_api.delete_user(user_id) + + assert response.status_code == 204 + + @pytest.mark.asyncio + async def test_logical_delete_user_success(self, authenticated_client, test_user_data, cleanup_user): + """测试逻辑删除用户成功""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + response = await user_api.logical_delete_user(user_id) + + assert response.status_code == 200 + + get_response = await user_api.get_user_by_id(user_id) + assert get_response.status_code == 404 + + get_deleted_response = await user_api.get_all_users(include_deleted=True) + deleted_users = get_deleted_response.json() + assert any(u["id"] == user_id for u in deleted_users) + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_restore_user_success(self, authenticated_client, test_user_data, cleanup_user): + """测试恢复用户成功""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + await user_api.logical_delete_user(user_id) + + response = await user_api.restore_user(user_id) + + assert response.status_code == 200 + + get_response = await user_api.get_user_by_id(user_id) + assert get_response.status_code == 200 + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_check_username_exists_true(self, authenticated_client, test_user_data, cleanup_user): + """测试检查用户名存在-返回true""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + response = await user_api.check_username_exists(test_user_data["username"]) + + assert response.status_code == 200 + assert response.json() is True + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_check_username_exists_false(self, authenticated_client): + """测试检查用户名存在-返回false""" + user_api = UserAPI(authenticated_client) + response = await user_api.check_username_exists("nonexistent_user") + + assert response.status_code == 200 + assert response.json() is False + + @pytest.mark.asyncio + async def test_check_email_exists_true(self, authenticated_client, test_user_data, cleanup_user): + """测试检查邮箱存在-返回true""" + user_api = UserAPI(authenticated_client) + + create_response = await user_api.create_user(test_user_data) + user_id = create_response.json()["id"] + + response = await user_api.check_email_exists(test_user_data["email"]) + + assert response.status_code == 200 + assert response.json() is True + + cleanup_user.append(user_id) + + @pytest.mark.asyncio + async def test_check_email_exists_false(self, authenticated_client): + """测试检查邮箱存在-返回false""" + user_api = UserAPI(authenticated_client) + response = await user_api.check_email_exists("nonexistent@example.com") + + assert response.status_code == 200 + assert response.json() is False diff --git a/e2e_tests/utils/__init__.py b/e2e_tests/utils/__init__.py new file mode 100644 index 0000000..548e274 --- /dev/null +++ b/e2e_tests/utils/__init__.py @@ -0,0 +1,3 @@ +""" +工具模块 +""" diff --git a/e2e_tests/utils/assertions.py b/e2e_tests/utils/assertions.py new file mode 100644 index 0000000..8458a6f --- /dev/null +++ b/e2e_tests/utils/assertions.py @@ -0,0 +1,83 @@ +""" +断言工具 +""" + +from typing import Any, Dict, List +from httpx import Response + + +class Assertions: + """断言工具类""" + + @staticmethod + def assert_status_code(response: Response, expected_status: int): + """断言状态码""" + assert response.status_code == expected_status, \ + f"Expected status code {expected_status}, got {response.status_code}. Response: {response.text}" + + @staticmethod + def assert_response_contains(response: Response, key: str, value: Any = None): + """断言响应包含指定字段""" + data = response.json() + assert key in data, f"Response does not contain key '{key}'. Response: {data}" + if value is not None: + assert data[key] == value, \ + f"Expected {value} for key '{key}', got {data[key]}" + + @staticmethod + def assert_response_is_list(response: Response): + """断言响应是列表""" + data = response.json() + assert isinstance(data, list), f"Expected list, got {type(data)}. Response: {data}" + + @staticmethod + def assert_response_not_empty(response: Response): + """断言响应不为空""" + data = response.json() + assert data, f"Response is empty. Response: {data}" + + @staticmethod + def assert_response_field_type(response: Response, field: str, expected_type: type): + """断言响应字段类型""" + data = response.json() + assert field in data, f"Response does not contain field '{field}'" + assert isinstance(data[field], expected_type), \ + f"Expected field '{field}' to be {expected_type}, got {type(data[field])}" + + @staticmethod + def assert_response_fields_present(response: Response, fields: List[str]): + """断言响应包含所有指定字段""" + data = response.json() + missing_fields = [field for field in fields if field not in data] + assert not missing_fields, \ + f"Response is missing fields: {missing_fields}. Response: {data}" + + @staticmethod + def assert_response_field_length(response: Response, field: str, min_length: int = None, max_length: int = None): + """断言响应字段长度""" + data = response.json() + assert field in data, f"Response does not contain field '{field}'" + field_value = data[field] + + if isinstance(field_value, (str, list, dict)): + length = len(field_value) + if min_length is not None: + assert length >= min_length, \ + f"Field '{field}' length {length} is less than minimum {min_length}" + if max_length is not None: + assert length <= max_length, \ + f"Field '{field}' length {length} is greater than maximum {max_length}" + else: + raise AssertionError(f"Field '{field}' is not a string, list, or dict") + + @staticmethod + def assert_error_response(response: Response, expected_message: str = None): + """断言错误响应""" + Assertions.assert_status_code(response, 400) + if expected_message: + data = response.json() + assert expected_message in str(data), \ + f"Expected error message '{expected_message}' not found in response: {data}" + + +assertions = Assertions() diff --git a/e2e_tests/utils/data_generator.py b/e2e_tests/utils/data_generator.py new file mode 100644 index 0000000..16fd57d --- /dev/null +++ b/e2e_tests/utils/data_generator.py @@ -0,0 +1,72 @@ +""" +测试数据生成器 +""" + +import random +import string +from faker import Faker + + +class DataGenerator: + """测试数据生成器""" + + def __init__(self, locale: str = "zh_CN"): + self.faker = Faker(locale) + + def generate_username(self) -> str: + """生成用户名""" + return f"testuser_{''.join(random.choices(string.ascii_lowercase + string.digits, k=8))}" + + def generate_password(self, length: int = 12) -> str: + """生成密码""" + chars = string.ascii_letters + string.digits + "!@#$%^&*" + return ''.join(random.choices(chars, k=length)) + + def generate_email(self) -> str: + """生成邮箱""" + return self.faker.email() + + def generate_phone(self) -> str: + """生成手机号""" + return self.faker.phone_number() + + def generate_name(self) -> str: + """生成姓名""" + return self.faker.name() + + def generate_role_name(self) -> str: + """生成角色名""" + return f"ROLE_{''.join(random.choices(string.ascii_uppercase, k=6))}" + + def generate_dict_type(self) -> str: + """生成字典类型""" + return f"DICT_TYPE_{''.join(random.choices(string.ascii_uppercase, k=4))}" + + def generate_dict_code(self) -> str: + """生成字典编码""" + return f"CODE_{''.join(random.choices(string.ascii_uppercase + string.digits, k=6))}" + + def generate_url(self) -> str: + """生成URL""" + return self.faker.url() + + def generate_company_name(self) -> str: + """生成公司名""" + return self.faker.company() + + def generate_address(self) -> str: + """生成地址""" + return self.faker.address() + + def generate_description(self) -> str: + """生成描述""" + return self.faker.text(max_nb_chars=200) + + def generate_permissions(self) -> str: + """生成权限字符串""" + permissions = ["READ", "WRITE", "DELETE", "ADMIN", "MANAGE"] + selected = random.sample(permissions, random.randint(1, len(permissions))) + return ",".join(selected) + + +data_generator = DataGenerator() diff --git a/e2e_tests/utils/logger.py b/e2e_tests/utils/logger.py new file mode 100644 index 0000000..7ed0d6b --- /dev/null +++ b/e2e_tests/utils/logger.py @@ -0,0 +1,33 @@ +""" +日志工具 +""" + +import sys +from loguru import logger +from pathlib import Path + + +def setup_logger(log_file: str = "e2e_tests.log", log_level: str = "INFO"): + """配置日志""" + logger.remove() + + logger.add( + sys.stdout, + format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}", + level=log_level, + colorize=True + ) + + logger.add( + log_file, + format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}", + level=log_level, + rotation="10 MB", + retention="7 days", + compression="zip" + ) + + return logger + + +setup_logger() diff --git a/novalon-manage-api/manage-sys/pom.xml b/novalon-manage-api/manage-sys/pom.xml new file mode 100644 index 0000000..6ddde54 --- /dev/null +++ b/novalon-manage-api/manage-sys/pom.xml @@ -0,0 +1,96 @@ + + + 4.0.0 + + + cn.novalon.manage + novalon-manage-api + 1.0.0 + + + manage-sys + jar + + Manage Sys + System Management Module + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-data-r2dbc + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-config + + + com.google.guava + guava + + + com.github.ben-manes.caffeine + caffeine + + + org.apache.commons + commons-lang3 + + + io.jsonwebtoken + jjwt-api + + + io.jsonwebtoken + jjwt-impl + runtime + + + io.jsonwebtoken + jjwt-jackson + runtime + + + org.postgresql + postgresql + + + org.postgresql + r2dbc-postgresql + + + org.flywaydb + flyway-core + + + org.flywaydb + flyway-database-postgresql + + + org.springdoc + springdoc-openapi-starter-webflux-ui + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java new file mode 100644 index 0000000..9f1c48a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java @@ -0,0 +1,11 @@ +package cn.novalon.manage.sys; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ManageSysApplication { + public static void main(String[] args) { + SpringApplication.run(ManageSysApplication.class, args); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java new file mode 100644 index 0000000..c98b6db --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java @@ -0,0 +1,31 @@ +package cn.novalon.manage.sys.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@Configuration +@EnableWebFluxSecurity +public class SecurityConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { + return http + .csrf(ServerHttpSecurity.CsrfSpec::disable) + .authorizeExchange(exchanges -> exchanges + .pathMatchers("/api/auth/**").permitAll() + .pathMatchers("/api/public/**").permitAll() + .anyExchange().authenticated() + ) + .build(); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SystemWebSocketHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SystemWebSocketHandler.java new file mode 100644 index 0000000..88a5d0c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/SystemWebSocketHandler.java @@ -0,0 +1,54 @@ +package cn.novalon.manage.sys.config; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class SystemWebSocketHandler extends TextWebSocketHandler { + + private final Map sessions = new ConcurrentHashMap<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + sessions.put(session.getId(), session); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { + sessions.remove(session.getId()); + } + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + // Handle incoming messages if needed + } + + public void sendMessageToUser(String userId, String message) { + sessions.values().forEach(session -> { + try { + if (session.isOpen()) { + session.sendMessage(new TextMessage(message)); + } + } catch (IOException e) { + } + }); + } + + public void broadcast(String message) { + sessions.values().forEach(session -> { + try { + if (session.isOpen()) { + session.sendMessage(new TextMessage(message)); + } + } catch (IOException e) { + } + }); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java new file mode 100644 index 0000000..e6bb529 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java @@ -0,0 +1,23 @@ +package cn.novalon.manage.sys.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer { + + private final SystemWebSocketHandler webSocketHandler; + + public WebSocketConfig(SystemWebSocketHandler webSocketHandler) { + this.webSocketHandler = webSocketHandler; + } + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler, "/ws") + .setAllowedOrigins("*"); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/BaseDomain.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/BaseDomain.java new file mode 100644 index 0000000..2845ad2 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/BaseDomain.java @@ -0,0 +1,43 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +public abstract class BaseDomain { + + private Long id; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private LocalDateTime deletedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/OperationLog.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/OperationLog.java new file mode 100644 index 0000000..a812863 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/OperationLog.java @@ -0,0 +1,86 @@ +package cn.novalon.manage.sys.core.domain; + +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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysConfig.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysConfig.java new file mode 100644 index 0000000..fa2cd57 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysConfig.java @@ -0,0 +1,35 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; + + 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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictData.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictData.java new file mode 100644 index 0000000..160de93 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictData.java @@ -0,0 +1,50 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; + + 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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictType.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictType.java new file mode 100644 index 0000000..72aa0d2 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysDictType.java @@ -0,0 +1,35 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; + + 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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysExceptionLog.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysExceptionLog.java new file mode 100644 index 0000000..8c060f0 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysExceptionLog.java @@ -0,0 +1,38 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysFile.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysFile.java new file mode 100644 index 0000000..a9bb329 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysFile.java @@ -0,0 +1,32 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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 LocalDateTime createdAt; + + 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 LocalDateTime getCreatedAt() { return createdAt; } + public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysLoginLog.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysLoginLog.java new file mode 100644 index 0000000..10cd230 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysLoginLog.java @@ -0,0 +1,35 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysMenu.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysMenu.java new file mode 100644 index 0000000..7a795fe --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysMenu.java @@ -0,0 +1,79 @@ +package cn.novalon.manage.sys.core.domain; + +import java.util.List; + +public class SysMenu extends BaseDomain { + + private String menuName; + private Long parentId; + private Integer orderNum; + private String menuType; + private String perms; + private String component; + private String status; + private List 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 String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysNotice.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysNotice.java new file mode 100644 index 0000000..fd7480b --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysNotice.java @@ -0,0 +1,35 @@ +package cn.novalon.manage.sys.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; + + 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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysRole.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysRole.java new file mode 100644 index 0000000..233edda --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysRole.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.core.domain; + +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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUser.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUser.java new file mode 100644 index 0000000..1fc364e --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUser.java @@ -0,0 +1,50 @@ +package cn.novalon.manage.sys.core.domain; + +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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUserMessage.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUserMessage.java new file mode 100644 index 0000000..4eebbe2 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/domain/SysUserMessage.java @@ -0,0 +1,29 @@ +package cn.novalon.manage.sys.core.domain; + +import java.time.LocalDateTime; + +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; } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/IOperationLogRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/IOperationLogRepository.java new file mode 100644 index 0000000..53add00 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/IOperationLogRepository.java @@ -0,0 +1,18 @@ +package cn.novalon.manage.sys.core.repository; + +import cn.novalon.manage.sys.core.domain.OperationLog; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface IOperationLogRepository { + + Mono findById(Long id); + + Mono save(OperationLog operationLog); + + Mono deleteById(Long id); + + Flux findAll(); + + Flux findByUsername(String username); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysMenuRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysMenuRepository.java new file mode 100644 index 0000000..9ae903c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysMenuRepository.java @@ -0,0 +1,18 @@ +package cn.novalon.manage.sys.core.repository; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysMenuRepository { + + Mono findById(Long id); + + Flux findAll(); + + Flux findByParentId(Long parentId); + + Mono save(SysMenu sysMenu); + + Mono deleteById(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysRoleRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysRoleRepository.java new file mode 100644 index 0000000..2000308 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysRoleRepository.java @@ -0,0 +1,16 @@ +package cn.novalon.manage.sys.core.repository; + +import cn.novalon.manage.sys.core.domain.SysRole; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysRoleRepository { + + Mono findById(Long id); + + Mono save(SysRole sysRole); + + Mono deleteById(Long id); + + Flux findAll(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysUserRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysUserRepository.java new file mode 100644 index 0000000..bb71503 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysUserRepository.java @@ -0,0 +1,18 @@ +package cn.novalon.manage.sys.core.repository; + +import cn.novalon.manage.sys.core.domain.SysUser; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysUserRepository { + + Mono findByUsername(String username); + + Mono findById(Long id); + + Mono save(SysUser sysUser); + + Mono deleteById(Long id); + + Flux findAll(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/IOperationLogService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/IOperationLogService.java new file mode 100644 index 0000000..3c515ee --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/IOperationLogService.java @@ -0,0 +1,11 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.OperationLog; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface IOperationLogService { + Mono save(OperationLog log); + Flux findAll(); + Flux findByUsername(String username); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysConfigService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysConfigService.java new file mode 100644 index 0000000..e9924b0 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysConfigService.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysConfig; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysConfigService { + Flux findAll(); + Mono findById(Long id); + Mono findByConfigKey(String configKey); + Mono save(SysConfig config); + Mono deleteById(Long id); + Mono getConfigValue(String configKey); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictDataService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictDataService.java new file mode 100644 index 0000000..f229997 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictDataService.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysDictData; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysDictDataService { + Flux findAll(); + Flux findByDictType(String dictType); + Flux findByDictTypeAndStatus(String dictType, String status); + Mono findById(Long id); + Mono save(SysDictData dictData); + Mono deleteById(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictTypeService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictTypeService.java new file mode 100644 index 0000000..802fd01 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysDictTypeService.java @@ -0,0 +1,13 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysDictType; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysDictTypeService { + Flux findAll(); + Mono findById(Long id); + Mono findByDictType(String dictType); + Mono save(SysDictType dictType); + Mono deleteById(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysExceptionLogService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysExceptionLogService.java new file mode 100644 index 0000000..9b2e25f --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysExceptionLogService.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysExceptionLog; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +public interface ISysExceptionLogService { + Flux findAll(); + Flux findByUsername(String username); + Flux findByCreateTimeBetween(LocalDateTime startTime, LocalDateTime endTime); + Mono save(SysExceptionLog exceptionLog); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysFileService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysFileService.java new file mode 100644 index 0000000..7b47959 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysFileService.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysFile; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import org.springframework.web.multipart.MultipartFile; + +public interface ISysFileService { + Flux findAll(); + Flux findByCreateBy(String createBy); + Mono findById(Long id); + Mono upload(MultipartFile file, String createBy); + Mono deleteById(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysLoginLogService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysLoginLogService.java new file mode 100644 index 0000000..551b56c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysLoginLogService.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysLoginLog; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +public interface ISysLoginLogService { + Flux findAll(); + Flux findByUsername(String username); + Flux findByLoginTimeBetween(LocalDateTime startTime, LocalDateTime endTime); + Mono save(SysLoginLog loginLog); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysMenuService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysMenuService.java new file mode 100644 index 0000000..1750028 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysMenuService.java @@ -0,0 +1,15 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysMenuService { + Mono findById(Long id); + Flux findAll(); + Flux findByParentId(Long parentId); + Mono createMenu(SysMenu menu); + Mono updateMenu(SysMenu menu); + Mono deleteMenu(Long id); + Flux buildMenuTree(Flux menus); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysNoticeService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysNoticeService.java new file mode 100644 index 0000000..1050438 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysNoticeService.java @@ -0,0 +1,13 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysNotice; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysNoticeService { + Flux findAll(); + Flux findByStatus(String status); + Mono findById(Long id); + Mono save(SysNotice notice); + Mono deleteById(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysRoleService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysRoleService.java new file mode 100644 index 0000000..0cf4c0e --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysRoleService.java @@ -0,0 +1,13 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysRole; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysRoleService { + Mono findById(Long id); + Flux findAll(); + Mono createRole(SysRole role); + Mono updateRole(SysRole role); + Mono deleteRole(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserMessageService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserMessageService.java new file mode 100644 index 0000000..648a380 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserMessageService.java @@ -0,0 +1,13 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysUserMessage; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface ISysUserMessageService { + Flux findByUserId(Long userId); + Flux findByUserIdAndIsRead(Long userId, String isRead); + Mono countUnread(Long userId); + Mono save(SysUserMessage message); + Mono markAsRead(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserService.java new file mode 100644 index 0000000..71e9d13 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysUserService.java @@ -0,0 +1,13 @@ +package cn.novalon.manage.sys.core.service; + +import cn.novalon.manage.sys.core.domain.SysUser; +import reactor.core.publisher.Mono; + +public interface ISysUserService { + Mono findById(Long id); + Mono findByUsername(String username); + Mono createUser(SysUser user); + Mono updateUser(SysUser user); + Mono deleteUser(Long id); + Mono changePassword(Long userId, String oldPassword, String newPassword); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java new file mode 100644 index 0000000..7dbe61e --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java @@ -0,0 +1,36 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.OperationLog; +import cn.novalon.manage.sys.core.repository.IOperationLogRepository; +import cn.novalon.manage.sys.core.service.IOperationLogService; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Service +public class OperationLogService implements IOperationLogService { + + private final IOperationLogRepository logRepository; + + public OperationLogService(IOperationLogRepository logRepository) { + this.logRepository = logRepository; + } + + @Override + public Mono save(OperationLog log) { + log.setCreatedAt(LocalDateTime.now()); + return logRepository.save(log); + } + + @Override + public Flux findAll() { + return logRepository.findAll(); + } + + @Override + public Flux findByUsername(String username) { + return logRepository.findByUsername(username); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..047467f --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,56 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysConfig; +import cn.novalon.manage.sys.core.service.ISysConfigService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysConfigConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysConfigDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +public class SysConfigServiceImpl implements ISysConfigService { + + private final SysConfigDao dao; + private final SysConfigConverter converter; + + public SysConfigServiceImpl(SysConfigDao dao, SysConfigConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono findByConfigKey(String configKey) { + return dao.findByConfigKeyAndDeletedAtIsNull(configKey) + .map(converter::toDomain); + } + + @Override + public Mono save(SysConfig config) { + return dao.save(converter.toEntity(config)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.deleteByIdAndDeletedAtIsNull(id); + } + + @Override + public Mono getConfigValue(String configKey) { + return findByConfigKey(configKey) + .map(SysConfig::getConfigValue); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictDataServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..3da65a1 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,56 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysDictData; +import cn.novalon.manage.sys.core.service.ISysDictDataService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysDictDataConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysDictDataDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +public class SysDictDataServiceImpl implements ISysDictDataService { + + private final SysDictDataDao dao; + private final SysDictDataConverter converter; + + public SysDictDataServiceImpl(SysDictDataDao dao, SysDictDataConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Flux findByDictType(String dictType) { + return dao.findByDictTypeAndDeletedAtIsNull(dictType) + .map(converter::toDomain); + } + + @Override + public Flux findByDictTypeAndStatus(String dictType, String status) { + return dao.findByDictTypeAndStatusAndDeletedAtIsNull(dictType, status) + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono save(SysDictData dictData) { + return dao.save(converter.toEntity(dictData)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.deleteByIdAndDeletedAtIsNull(id); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictTypeServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..424dbfc --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,50 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysDictType; +import cn.novalon.manage.sys.core.service.ISysDictTypeService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysDictTypeConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysDictTypeDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService { + + private final SysDictTypeDao dao; + private final SysDictTypeConverter converter; + + public SysDictTypeServiceImpl(SysDictTypeDao dao, SysDictTypeConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono findByDictType(String dictType) { + return dao.findByDictTypeAndDeletedAtIsNull(dictType) + .map(converter::toDomain); + } + + @Override + public Mono save(SysDictType dictType) { + return dao.save(converter.toEntity(dictType)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.deleteByIdAndDeletedAtIsNull(id); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogServiceImpl.java new file mode 100644 index 0000000..da815f5 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogServiceImpl.java @@ -0,0 +1,47 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysExceptionLog; +import cn.novalon.manage.sys.core.service.ISysExceptionLogService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysExceptionLogConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysExceptionLogDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Service +public class SysExceptionLogServiceImpl implements ISysExceptionLogService { + + private final SysExceptionLogDao dao; + private final SysExceptionLogConverter converter; + + public SysExceptionLogServiceImpl(SysExceptionLogDao dao, SysExceptionLogConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findAllByOrderByCreateTimeDesc() + .map(converter::toDomain); + } + + @Override + public Flux findByUsername(String username) { + return dao.findByUsernameOrderByCreateTimeDesc(username) + .map(converter::toDomain); + } + + @Override + public Flux findByCreateTimeBetween(LocalDateTime startTime, LocalDateTime endTime) { + return dao.findByCreateTimeBetweenOrderByCreateTimeDesc(startTime, endTime) + .map(converter::toDomain); + } + + @Override + public Mono save(SysExceptionLog exceptionLog) { + return dao.save(converter.toEntity(exceptionLog)) + .map(converter::toDomain); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.java new file mode 100644 index 0000000..d08cf51 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.java @@ -0,0 +1,78 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysFile; +import cn.novalon.manage.sys.core.service.ISysFileService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysFileConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysFileDao; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.util.UUID; + +@Service +public class SysFileServiceImpl implements ISysFileService { + + private final SysFileDao dao; + private final SysFileConverter converter; + private final Path uploadPath = Paths.get("./uploads"); + + public SysFileServiceImpl(SysFileDao dao, SysFileConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNullOrderByCreatedAtDesc() + .map(converter::toDomain); + } + + @Override + public Flux findByCreateBy(String createBy) { + return dao.findByCreateByOrderByCreatedAtDesc(createBy) + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono upload(MultipartFile file, String createBy) { + try { + if (!Files.exists(uploadPath)) { + Files.createDirectories(uploadPath); + } + String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); + Path filePath = uploadPath.resolve(fileName); + Files.copy(file.getInputStream(), filePath); + + SysFile sysFile = new SysFile(); + sysFile.setFileName(file.getOriginalFilename()); + sysFile.setFilePath("/api/files/download/" + fileName); + sysFile.setFileSize(String.valueOf(file.getSize())); + sysFile.setFileType(file.getContentType()); + sysFile.setStorageType("local"); + sysFile.setCreateBy(createBy); + sysFile.setCreatedAt(LocalDateTime.now()); + + return dao.save(converter.toEntity(sysFile)) + .map(converter::toDomain); + } catch (Exception e) { + return Mono.error(new RuntimeException("文件上传失败: " + e.getMessage())); + } + } + + @Override + public Mono deleteById(Long id) { + return dao.deleteByIdAndDeletedAtIsNull(id); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.java new file mode 100644 index 0000000..c0f899b --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.java @@ -0,0 +1,47 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysLoginLog; +import cn.novalon.manage.sys.core.service.ISysLoginLogService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysLoginLogConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysLoginLogDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Service +public class SysLoginLogServiceImpl implements ISysLoginLogService { + + private final SysLoginLogDao dao; + private final SysLoginLogConverter converter; + + public SysLoginLogServiceImpl(SysLoginLogDao dao, SysLoginLogConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findAllByOrderByLoginTimeDesc() + .map(converter::toDomain); + } + + @Override + public Flux findByUsername(String username) { + return dao.findByUsernameOrderByLoginTimeDesc(username) + .map(converter::toDomain); + } + + @Override + public Flux findByLoginTimeBetween(LocalDateTime startTime, LocalDateTime endTime) { + return dao.findByLoginTimeBetweenOrderByLoginTimeDesc(startTime, endTime) + .map(converter::toDomain); + } + + @Override + public Mono save(SysLoginLog loginLog) { + return dao.save(converter.toEntity(loginLog)) + .map(converter::toDomain); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysMenuService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysMenuService.java new file mode 100644 index 0000000..233fe33 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysMenuService.java @@ -0,0 +1,69 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import cn.novalon.manage.sys.core.repository.ISysMenuRepository; +import cn.novalon.manage.sys.core.service.ISysMenuService; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class SysMenuService implements ISysMenuService { + + private final ISysMenuRepository menuRepository; + + public SysMenuService(ISysMenuRepository menuRepository) { + this.menuRepository = menuRepository; + } + + @Override + public Mono findById(Long id) { + return menuRepository.findById(id); + } + + @Override + public Flux findAll() { + return menuRepository.findAll(); + } + + @Override + public Flux findByParentId(Long parentId) { + return menuRepository.findByParentId(parentId); + } + + @Override + public Mono createMenu(SysMenu menu) { + menu.setCreatedAt(LocalDateTime.now()); + menu.setStatus("0"); + return menuRepository.save(menu); + } + + @Override + public Mono updateMenu(SysMenu menu) { + menu.setUpdatedAt(LocalDateTime.now()); + return menuRepository.save(menu); + } + + @Override + public Mono deleteMenu(Long id) { + return menuRepository.deleteById(id); + } + + @Override + public Flux buildMenuTree(Flux menus) { + return menus.collectList() + .map(list -> buildTree(list, 0L)) + .flatMapMany(Flux::fromIterable); + } + + private List buildTree(List menus, Long parentId) { + return menus.stream() + .filter(m -> m.getParentId().equals(parentId)) + .peek(m -> m.setChildren(buildTree(menus, m.getId()))) + .collect(Collectors.toList()); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..3a2d3a2 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,50 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysNotice; +import cn.novalon.manage.sys.core.service.ISysNoticeService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysNoticeConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysNoticeDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +public class SysNoticeServiceImpl implements ISysNoticeService { + + private final SysNoticeDao dao; + private final SysNoticeConverter converter; + + public SysNoticeServiceImpl(SysNoticeDao dao, SysNoticeConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Flux findByStatus(String status) { + return dao.findByStatusAndDeletedAtIsNull(status) + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono save(SysNotice notice) { + return dao.save(converter.toEntity(notice)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.deleteByIdAndDeletedAtIsNull(id); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysRoleService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysRoleService.java new file mode 100644 index 0000000..de5ddf3 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysRoleService.java @@ -0,0 +1,48 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysRole; +import cn.novalon.manage.sys.core.repository.ISysRoleRepository; +import cn.novalon.manage.sys.core.service.ISysRoleService; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Service +public class SysRoleService implements ISysRoleService { + + private final ISysRoleRepository roleRepository; + + public SysRoleService(ISysRoleRepository roleRepository) { + this.roleRepository = roleRepository; + } + + @Override + public Mono findById(Long id) { + return roleRepository.findById(id); + } + + @Override + public Flux findAll() { + return roleRepository.findAll(); + } + + @Override + public Mono createRole(SysRole role) { + role.setCreatedAt(LocalDateTime.now()); + role.setStatus(1); + return roleRepository.save(role); + } + + @Override + public Mono updateRole(SysRole role) { + role.setUpdatedAt(LocalDateTime.now()); + return roleRepository.save(role); + } + + @Override + public Mono deleteRole(Long id) { + return roleRepository.deleteById(id); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageServiceImpl.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageServiceImpl.java new file mode 100644 index 0000000..fce71a3 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageServiceImpl.java @@ -0,0 +1,54 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysUserMessage; +import cn.novalon.manage.sys.core.service.ISysUserMessageService; +import cn.novalon.manage.sys.infrastructure.db.converter.SysUserMessageConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysUserMessageDao; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +public class SysUserMessageServiceImpl implements ISysUserMessageService { + + private final SysUserMessageDao dao; + private final SysUserMessageConverter converter; + + public SysUserMessageServiceImpl(SysUserMessageDao dao, SysUserMessageConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Flux findByUserId(Long userId) { + return dao.findByUserIdOrderByCreateTimeDesc(userId) + .map(converter::toDomain); + } + + @Override + public Flux findByUserIdAndIsRead(Long userId, String isRead) { + return dao.findByUserIdAndIsReadOrderByCreateTimeDesc(userId, isRead) + .map(converter::toDomain); + } + + @Override + public Mono countUnread(Long userId) { + return dao.countByUserIdAndIsRead(userId, "0"); + } + + @Override + public Mono save(SysUserMessage message) { + return dao.save(converter.toEntity(message)) + .map(converter::toDomain); + } + + @Override + public Mono markAsRead(Long id) { + return dao.findById(id) + .flatMap(entity -> { + entity.setIsRead("1"); + return dao.save(entity); + }) + .then(); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserService.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserService.java new file mode 100644 index 0000000..9f35c5f --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserService.java @@ -0,0 +1,64 @@ +package cn.novalon.manage.sys.core.service.impl; + +import cn.novalon.manage.sys.core.domain.SysUser; +import cn.novalon.manage.sys.core.repository.ISysUserRepository; +import cn.novalon.manage.sys.core.service.ISysUserService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Service +public class SysUserService implements ISysUserService { + + private final ISysUserRepository userRepository; + private final PasswordEncoder passwordEncoder; + + public SysUserService(ISysUserRepository userRepository, PasswordEncoder passwordEncoder) { + this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + } + + @Override + public Mono findById(Long id) { + return userRepository.findById(id); + } + + @Override + public Mono findByUsername(String username) { + return userRepository.findByUsername(username); + } + + @Override + public Mono createUser(SysUser user) { + user.setPassword(passwordEncoder.encode(user.getPassword())); + user.setCreatedAt(LocalDateTime.now()); + user.setStatus(1); + return userRepository.save(user); + } + + @Override + public Mono updateUser(SysUser user) { + user.setUpdatedAt(LocalDateTime.now()); + return userRepository.save(user); + } + + @Override + public Mono deleteUser(Long id) { + return userRepository.deleteById(id); + } + + @Override + public Mono changePassword(Long userId, String oldPassword, String newPassword) { + return userRepository.findById(userId) + .flatMap(user -> { + if (!passwordEncoder.matches(oldPassword, user.getPassword())) { + return Mono.error(new RuntimeException("旧密码不正确")); + } + user.setPassword(passwordEncoder.encode(newPassword)); + user.setUpdatedAt(LocalDateTime.now()); + return userRepository.save(user); + }); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/LoginRequest.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/LoginRequest.java new file mode 100644 index 0000000..c1cddfd --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/LoginRequest.java @@ -0,0 +1,28 @@ +package cn.novalon.manage.sys.dto.request; + +import jakarta.validation.constraints.NotBlank; + +public class LoginRequest { + + @NotBlank(message = "用户名不能为空") + private String username; + + @NotBlank(message = "密码不能为空") + private String password; + + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.java new file mode 100644 index 0000000..25a39d4 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.java @@ -0,0 +1,28 @@ +package cn.novalon.manage.sys.dto.request; + +import jakarta.validation.constraints.NotBlank; + +public class PasswordChangeRequest { + + @NotBlank(message = "旧密码不能为空") + private String oldPassword; + + @NotBlank(message = "新密码不能为空") + private String newPassword; + + public String getOldPassword() { + return oldPassword; + } + + public void setOldPassword(String oldPassword) { + this.oldPassword = oldPassword; + } + + public String getNewPassword() { + return newPassword; + } + + public void setNewPassword(String newPassword) { + this.newPassword = newPassword; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserRegisterRequest.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserRegisterRequest.java new file mode 100644 index 0000000..c40a770 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserRegisterRequest.java @@ -0,0 +1,43 @@ +package cn.novalon.manage.sys.dto.request; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public class UserRegisterRequest { + + @NotBlank(message = "用户名不能为空") + @Size(min = 3, max = 50, message = "用户名长度必须在3-50之间") + private String username; + + @NotBlank(message = "密码不能为空") + @Size(min = 6, max = 100, message = "密码长度必须在6-100之间") + private String password; + + @Email(message = "邮箱格式不正确") + private String email; + + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserUpdateRequest.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserUpdateRequest.java new file mode 100644 index 0000000..b9f7346 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/request/UserUpdateRequest.java @@ -0,0 +1,37 @@ +package cn.novalon.manage.sys.dto.request; + +import jakarta.validation.constraints.Email; + +public class UserUpdateRequest { + + private String email; + + private Integer status; + + private Long roleId; + + @Email(message = "邮箱格式不正确") + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Long getRoleId() { + return roleId; + } + + public void setRoleId(Long roleId) { + this.roleId = roleId; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/AuthResponse.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/AuthResponse.java new file mode 100644 index 0000000..5641e9b --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/AuthResponse.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.dto.response; + +public class AuthResponse { + + private String token; + private Long userId; + private String username; + + public AuthResponse() { + } + + public AuthResponse(String token, Long userId, String username) { + this.token = token; + this.userId = userId; + this.username = username; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/UserResponse.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/UserResponse.java new file mode 100644 index 0000000..de2d4c9 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/dto/response/UserResponse.java @@ -0,0 +1,82 @@ +package cn.novalon.manage.sys.dto.response; + +import java.time.LocalDateTime; + +public class UserResponse { + + private Long id; + private String username; + private String email; + private Long roleId; + private Integer status; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + + 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 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 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 static UserResponse fromDomain(cn.novalon.manage.sys.core.domain.SysUser user) { + UserResponse response = new UserResponse(); + response.setId(user.getId()); + response.setUsername(user.getUsername()); + response.setEmail(user.getEmail()); + response.setRoleId(user.getRoleId()); + response.setStatus(user.getStatus()); + response.setCreatedAt(user.getCreatedAt()); + response.setUpdatedAt(user.getUpdatedAt()); + return response; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/GlobalExceptionHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..8d180a5 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/GlobalExceptionHandler.java @@ -0,0 +1,78 @@ +package cn.novalon.manage.sys.handler; + +import cn.novalon.manage.sys.core.domain.SysExceptionLog; +import cn.novalon.manage.sys.core.service.ISysExceptionLogService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + private final ISysExceptionLogService exceptionLogService; + + public GlobalExceptionHandler(ISysExceptionLogService exceptionLogService) { + this.exceptionLogService = exceptionLogService; + } + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleException(Exception ex, WebRequest request) { + logger.error("Exception occurred: ", ex); + + SysExceptionLog exceptionLog = new SysExceptionLog(); + exceptionLog.setTitle("System Exception"); + exceptionLog.setExceptionName(ex.getClass().getSimpleName()); + exceptionLog.setExceptionMsg(ex.getMessage()); + exceptionLog.setMethodName(request.getDescription(false)); + exceptionLog.setIp(getClientIp(request)); + exceptionLog.setCreateTime(LocalDateTime.now()); + + StringBuilder stackTrace = new StringBuilder(); + for (StackTraceElement element : ex.getStackTrace()) { + stackTrace.append(element.toString()).append("\n"); + } + exceptionLog.setExceptionStack(stackTrace.toString()); + + exceptionLogService.save(exceptionLog).subscribe(); + + Map response = new HashMap<>(); + response.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("message", ex.getMessage()); + response.put("timestamp", LocalDateTime.now()); + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) { + logger.warn("Illegal argument: ", ex); + + Map response = new HashMap<>(); + response.put("code", HttpStatus.BAD_REQUEST.value()); + response.put("message", ex.getMessage()); + response.put("timestamp", LocalDateTime.now()); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + private String getClientIp(WebRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = "127.0.0.1"; + } + return ip; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/auth/SysAuthHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/auth/SysAuthHandler.java new file mode 100644 index 0000000..360e997 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/auth/SysAuthHandler.java @@ -0,0 +1,59 @@ +package cn.novalon.manage.sys.handler.auth; + +import cn.novalon.manage.sys.dto.request.LoginRequest; +import cn.novalon.manage.sys.dto.request.UserRegisterRequest; +import cn.novalon.manage.sys.dto.response.AuthResponse; +import cn.novalon.manage.sys.security.JwtTokenProvider; +import cn.novalon.manage.sys.core.domain.SysUser; +import cn.novalon.manage.sys.core.service.ISysUserService; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/api/auth") +public class SysAuthHandler { + + private final ISysUserService userService; + private final PasswordEncoder passwordEncoder; + private final JwtTokenProvider jwtTokenProvider; + + public SysAuthHandler(ISysUserService userService, PasswordEncoder passwordEncoder, JwtTokenProvider jwtTokenProvider) { + this.userService = userService; + this.passwordEncoder = passwordEncoder; + this.jwtTokenProvider = jwtTokenProvider; + } + + @PostMapping("/login") + public Mono> login(@Valid @RequestBody LoginRequest request) { + return userService.findByUsername(request.getUsername()) + .filter(user -> passwordEncoder.matches(request.getPassword(), user.getPassword())) + .filter(user -> 1 == user.getStatus()) + .map(user -> { + String token = jwtTokenProvider.generateToken(user.getUsername(), user.getId()); + AuthResponse response = new AuthResponse(token, user.getId(), user.getUsername()); + return ResponseEntity.ok(response); + }) + .defaultIfEmpty(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()); + } + + @PostMapping("/register") + public Mono> register(@Valid @RequestBody UserRegisterRequest request) { + SysUser user = new SysUser(); + user.setUsername(request.getUsername()); + user.setPassword(request.getPassword()); + user.setEmail(request.getEmail()); + return userService.findByUsername(request.getUsername()) + .flatMap(existing -> Mono.>error(new RuntimeException("用户名已存在"))) + .switchIfEmpty(userService.createUser(user) + .map(u -> ResponseEntity.status(HttpStatus.CREATED).body(u))); + } + + @PostMapping("/logout") + public Mono> logout() { + return Mono.just(ResponseEntity.ok().build()); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysConfigHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysConfigHandler.java new file mode 100644 index 0000000..eb41875 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysConfigHandler.java @@ -0,0 +1,62 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysConfig; +import cn.novalon.manage.sys.core.service.ISysConfigService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@RestController +@RequestMapping("/api/config") +public class SysConfigHandler { + + private final ISysConfigService configService; + + public SysConfigHandler(ISysConfigService configService) { + this.configService = configService; + } + + @GetMapping + public Flux getAllConfigs() { + return configService.findAll(); + } + + @GetMapping("/{id}") + public Mono> getConfigById(@PathVariable Long id) { + return configService.findById(id) + .map(config -> ResponseEntity.ok(config)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/key/{configKey}") + public Mono> getConfigByKey(@PathVariable String configKey) { + return configService.findByConfigKey(configKey) + .map(config -> ResponseEntity.ok(config)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping + public Mono> createConfig(@RequestBody SysConfig config) { + config.setConfigType("N"); + config.setCreatedAt(LocalDateTime.now()); + return configService.save(config) + .map(saved -> ResponseEntity.ok(saved)); + } + + @PutMapping("/{id}") + public Mono> updateConfig(@PathVariable Long id, @RequestBody SysConfig config) { + config.setId(id); + config.setUpdatedAt(LocalDateTime.now()); + return configService.save(config) + .map(saved -> ResponseEntity.ok(saved)); + } + + @DeleteMapping("/{id}") + public Mono> deleteConfig(@PathVariable Long id) { + return configService.deleteById(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysDictHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysDictHandler.java new file mode 100644 index 0000000..8e2f810 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysDictHandler.java @@ -0,0 +1,62 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysDictType; +import cn.novalon.manage.sys.core.service.ISysDictTypeService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@RestController +@RequestMapping("/api/dict") +public class SysDictHandler { + + private final ISysDictTypeService dictTypeService; + + public SysDictHandler(ISysDictTypeService dictTypeService) { + this.dictTypeService = dictTypeService; + } + + @GetMapping("/types") + public Flux getAllDictTypes() { + return dictTypeService.findAll(); + } + + @GetMapping("/types/{id}") + public Mono> getDictTypeById(@PathVariable Long id) { + return dictTypeService.findById(id) + .map(dictType -> ResponseEntity.ok(dictType)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/types/type/{dictType}") + public Mono> getDictTypeByDictType(@PathVariable String dictType) { + return dictTypeService.findByDictType(dictType) + .map(dictTypeResult -> ResponseEntity.ok(dictTypeResult)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping("/types") + public Mono> createDictType(@RequestBody SysDictType dictType) { + dictType.setStatus("0"); + dictType.setCreatedAt(LocalDateTime.now()); + return dictTypeService.save(dictType) + .map(saved -> ResponseEntity.ok(saved)); + } + + @PutMapping("/types/{id}") + public Mono> updateDictType(@PathVariable Long id, @RequestBody SysDictType dictType) { + dictType.setId(id); + dictType.setUpdatedAt(LocalDateTime.now()); + return dictTypeService.save(dictType) + .map(saved -> ResponseEntity.ok(saved)); + } + + @DeleteMapping("/types/{id}") + public Mono> deleteDictType(@PathVariable Long id) { + return dictTypeService.deleteById(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysFileHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysFileHandler.java new file mode 100644 index 0000000..b7c3229 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysFileHandler.java @@ -0,0 +1,88 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysFile; +import cn.novalon.manage.sys.core.service.ISysFileService; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.net.MalformedURLException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +@RestController +@RequestMapping("/api/files") +public class SysFileHandler { + + private final ISysFileService fileService; + private final Path uploadPath = Paths.get("./uploads"); + + public SysFileHandler(ISysFileService fileService) { + this.fileService = fileService; + } + + @GetMapping + public Flux getAllFiles() { + return fileService.findAll(); + } + + @GetMapping("/{id}") + public Mono> getFileById(@PathVariable Long id) { + return fileService.findById(id) + .map(file -> ResponseEntity.ok(file)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping("/upload") + public Mono> uploadFile(@RequestParam("file") MultipartFile file, + @RequestParam(value = "createBy", required = false, defaultValue = "anonymous") String createBy) { + return fileService.upload(file, createBy) + .map(saved -> ResponseEntity.ok(saved)); + } + + @GetMapping("/download/{fileName}") + public Mono downloadFile(@PathVariable String fileName) throws MalformedURLException { + Path filePath = uploadPath.resolve(fileName); + Resource resource = new UrlResource(filePath.toUri()); + return Mono.just(resource); + } + + @GetMapping("/preview/{fileName}") + public Mono> previewFile(@PathVariable String fileName) throws MalformedURLException { + return Mono.fromCallable(() -> { + Path filePath = uploadPath.resolve(fileName); + byte[] data = Files.readAllBytes(filePath); + return data; + }).map(data -> { + String contentType = "application/octet-stream"; + try { + contentType = Files.probeContentType(uploadPath.resolve(fileName)); + } catch (Exception e) { + } + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType(contentType)) + .body(data); + }); + } + + @DeleteMapping("/{id}") + public Mono> deleteFile(@PathVariable Long id) { + return fileService.findById(id) + .flatMap(file -> { + try { + String fileName = file.getFilePath().substring(file.getFilePath().lastIndexOf("/") + 1); + Files.deleteIfExists(uploadPath.resolve(fileName)); + } catch (Exception e) { + } + return fileService.deleteById(id); + }) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysLogHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysLogHandler.java new file mode 100644 index 0000000..7e05846 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysLogHandler.java @@ -0,0 +1,77 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysLoginLog; +import cn.novalon.manage.sys.core.domain.SysExceptionLog; +import cn.novalon.manage.sys.core.service.ISysLoginLogService; +import cn.novalon.manage.sys.core.service.ISysExceptionLogService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@RestController +@RequestMapping("/api/logs") +public class SysLogHandler { + + private final ISysLoginLogService loginLogService; + private final ISysExceptionLogService exceptionLogService; + + public SysLogHandler(ISysLoginLogService loginLogService, ISysExceptionLogService exceptionLogService) { + this.loginLogService = loginLogService; + this.exceptionLogService = exceptionLogService; + } + + @GetMapping("/login") + public Flux getLoginLogs() { + return loginLogService.findAll(); + } + + @GetMapping("/login/{id}") + public Mono> getLoginLogById(@PathVariable Long id) { + return loginLogService.findAll() + .filter(log -> log.getId().equals(id)) + .next() + .map(log -> ResponseEntity.ok(log)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping("/login") + public Mono> createLoginLog(@RequestBody SysLoginLog log) { + log.setLoginTime(LocalDateTime.now()); + return loginLogService.save(log) + .map(saved -> ResponseEntity.ok(saved)); + } + + @GetMapping("/login/user/{username}") + public Flux getLoginLogsByUsername(@PathVariable String username) { + return loginLogService.findByUsername(username); + } + + @GetMapping("/exception") + public Flux getExceptionLogs() { + return exceptionLogService.findAll(); + } + + @GetMapping("/exception/{id}") + public Mono> getExceptionLogById(@PathVariable Long id) { + return exceptionLogService.findAll() + .filter(log -> log.getId().equals(id)) + .next() + .map(log -> ResponseEntity.ok(log)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/exception/user/{username}") + public Flux getExceptionLogsByUsername(@PathVariable String username) { + return exceptionLogService.findByUsername(username); + } + + @PostMapping("/exception") + public Mono> createExceptionLog(@RequestBody SysExceptionLog log) { + log.setCreateTime(LocalDateTime.now()); + return exceptionLogService.save(log) + .map(saved -> ResponseEntity.ok(saved)); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMenuHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMenuHandler.java new file mode 100644 index 0000000..e458c92 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMenuHandler.java @@ -0,0 +1,56 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import cn.novalon.manage.sys.core.service.ISysMenuService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/api/menus") +public class SysMenuHandler { + + private final ISysMenuService menuService; + + public SysMenuHandler(ISysMenuService menuService) { + this.menuService = menuService; + } + + @GetMapping + public Flux getAllMenus() { + return menuService.findAll(); + } + + @GetMapping("/tree") + public Flux getMenuTree() { + return menuService.buildMenuTree(menuService.findAll()); + } + + @GetMapping("/{id}") + public Mono> getMenuById(@PathVariable Long id) { + return menuService.findById(id) + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping + public Mono> createMenu(@RequestBody SysMenu menu) { + return menuService.createMenu(menu) + .map(m -> ResponseEntity.status(HttpStatus.CREATED).body(m)); + } + + @PutMapping("/{id}") + public Mono> updateMenu(@PathVariable Long id, @RequestBody SysMenu menu) { + menu.setId(id); + return menuService.updateMenu(menu) + .map(ResponseEntity::ok); + } + + @DeleteMapping("/{id}") + public Mono> deleteMenu(@PathVariable Long id) { + return menuService.deleteMenu(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMessageHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMessageHandler.java new file mode 100644 index 0000000..0d67f90 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysMessageHandler.java @@ -0,0 +1,47 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysUserMessage; +import cn.novalon.manage.sys.core.service.ISysUserMessageService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/api/messages") +public class SysMessageHandler { + + private final ISysUserMessageService messageService; + + public SysMessageHandler(ISysUserMessageService messageService) { + this.messageService = messageService; + } + + @GetMapping("/user/{userId}") + public Flux getMessagesByUserId(@PathVariable Long userId) { + return messageService.findByUserId(userId); + } + + @GetMapping("/user/{userId}/unread") + public Mono getUnreadCount(@PathVariable Long userId) { + return messageService.countUnread(userId); + } + + @GetMapping("/user/{userId}/unread/list") + public Flux getUnreadMessages(@PathVariable Long userId) { + return messageService.findByUserIdAndIsRead(userId, "0"); + } + + @PostMapping + public Mono> createMessage(@RequestBody SysUserMessage message) { + message.setIsRead("0"); + return messageService.save(message) + .map(saved -> ResponseEntity.ok(saved)); + } + + @PutMapping("/{id}/read") + public Mono> markAsRead(@PathVariable Long id) { + return messageService.markAsRead(id) + .then(Mono.just(ResponseEntity.ok().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.java new file mode 100644 index 0000000..0cd44a3 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.java @@ -0,0 +1,60 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysNotice; +import cn.novalon.manage.sys.core.service.ISysNoticeService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@RestController +@RequestMapping("/api/notices") +public class SysNoticeHandler { + + private final ISysNoticeService noticeService; + + public SysNoticeHandler(ISysNoticeService noticeService) { + this.noticeService = noticeService; + } + + @GetMapping + public Flux getAllNotices() { + return noticeService.findAll(); + } + + @GetMapping("/{id}") + public Mono> getNoticeById(@PathVariable Long id) { + return noticeService.findById(id) + .map(notice -> ResponseEntity.ok(notice)) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/status/{status}") + public Flux getNoticesByStatus(@PathVariable String status) { + return noticeService.findByStatus(status); + } + + @PostMapping + public Mono> createNotice(@RequestBody SysNotice notice) { + notice.setStatus("0"); + notice.setCreatedAt(LocalDateTime.now()); + return noticeService.save(notice) + .map(saved -> ResponseEntity.ok(saved)); + } + + @PutMapping("/{id}") + public Mono> updateNotice(@PathVariable Long id, @RequestBody SysNotice notice) { + notice.setId(id); + notice.setUpdatedAt(LocalDateTime.now()); + return noticeService.save(notice) + .map(saved -> ResponseEntity.ok(saved)); + } + + @DeleteMapping("/{id}") + public Mono> deleteNotice(@PathVariable Long id) { + return noticeService.deleteById(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysRoleHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysRoleHandler.java new file mode 100644 index 0000000..65ba0d0 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/sys/SysRoleHandler.java @@ -0,0 +1,51 @@ +package cn.novalon.manage.sys.handler.sys; + +import cn.novalon.manage.sys.core.domain.SysRole; +import cn.novalon.manage.sys.core.service.ISysRoleService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/api/roles") +public class SysRoleHandler { + + private final ISysRoleService roleService; + + public SysRoleHandler(ISysRoleService roleService) { + this.roleService = roleService; + } + + @GetMapping + public Flux getAllRoles() { + return roleService.findAll(); + } + + @GetMapping("/{id}") + public Mono> getRoleById(@PathVariable Long id) { + return roleService.findById(id) + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping + public Mono> createRole(@RequestBody SysRole role) { + return roleService.createRole(role) + .map(r -> ResponseEntity.status(HttpStatus.CREATED).body(r)); + } + + @PutMapping("/{id}") + public Mono> updateRole(@PathVariable Long id, @RequestBody SysRole role) { + role.setId(id); + return roleService.updateRole(role) + .map(ResponseEntity::ok); + } + + @DeleteMapping("/{id}") + public Mono> deleteRole(@PathVariable Long id) { + return roleService.deleteRole(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/user/SysUserHandler.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/user/SysUserHandler.java new file mode 100644 index 0000000..b8f579a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/user/SysUserHandler.java @@ -0,0 +1,75 @@ +package cn.novalon.manage.sys.handler.user; + +import cn.novalon.manage.sys.core.domain.SysUser; +import cn.novalon.manage.sys.core.service.ISysUserService; +import cn.novalon.manage.sys.dto.request.PasswordChangeRequest; +import cn.novalon.manage.sys.dto.request.UserUpdateRequest; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/api/users") +public class SysUserHandler { + + private final ISysUserService userService; + + public SysUserHandler(ISysUserService userService) { + this.userService = userService; + } + + @GetMapping("/{id}") + public Mono> getUserById(@PathVariable Long id) { + return userService.findById(id) + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/username/{username}") + public Mono> getUserByUsername(@PathVariable String username) { + return userService.findByUsername(username) + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @PostMapping + public Mono> createUser(@RequestBody SysUser user) { + return userService.createUser(user) + .map(u -> ResponseEntity.status(HttpStatus.CREATED).body(u)); + } + + @PutMapping("/{id}") + public Mono> updateUser(@PathVariable Long id, @Valid @RequestBody UserUpdateRequest request) { + return userService.findById(id) + .flatMap(existing -> { + if (request.getEmail() != null) { + existing.setEmail(request.getEmail()); + } + if (request.getStatus() != null) { + existing.setStatus(request.getStatus()); + } + if (request.getRoleId() != null) { + existing.setRoleId(request.getRoleId()); + } + return userService.updateUser(existing); + }) + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @DeleteMapping("/{id}") + public Mono> deleteUser(@PathVariable Long id) { + return userService.deleteUser(id) + .then(Mono.just(ResponseEntity.noContent().build())); + } + + @PostMapping("/{id}/password") + public Mono> changePassword( + @PathVariable Long id, + @Valid @RequestBody PasswordChangeRequest request) { + return userService.changePassword(id, request.getOldPassword(), request.getNewPassword()) + .map(ResponseEntity::ok); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.java new file mode 100644 index 0000000..189748d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.java @@ -0,0 +1,49 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.OperationLog; +import cn.novalon.manage.sys.infrastructure.db.entity.OperationLogEntity; + +public class OperationLogConverter { + + public OperationLog toDomain(OperationLogEntity entity) { + if (entity == null) { + return null; + } + OperationLog domain = new OperationLog(); + domain.setId(entity.getId()); + domain.setUsername(entity.getUsername()); + domain.setOperation(entity.getOperation()); + domain.setMethod(entity.getMethod()); + domain.setParams(entity.getParams()); + domain.setResult(entity.getResult()); + domain.setIp(entity.getIp()); + domain.setDuration(entity.getDuration()); + domain.setStatus(entity.getStatus()); + domain.setErrorMsg(entity.getErrorMsg()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + domain.setDeletedAt(entity.getDeletedAt()); + return domain; + } + + public OperationLogEntity toEntity(OperationLog domain) { + if (domain == null) { + return null; + } + OperationLogEntity entity = new OperationLogEntity(); + entity.setId(domain.getId()); + entity.setUsername(domain.getUsername()); + entity.setOperation(domain.getOperation()); + entity.setMethod(domain.getMethod()); + entity.setParams(domain.getParams()); + entity.setResult(domain.getResult()); + entity.setIp(domain.getIp()); + entity.setDuration(domain.getDuration()); + entity.setStatus(domain.getStatus()); + entity.setErrorMsg(domain.getErrorMsg()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + entity.setDeletedAt(domain.getDeletedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.java new file mode 100644 index 0000000..3122a45 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysConfig; +import cn.novalon.manage.sys.infrastructure.db.entity.SysConfigEntity; + +public class SysConfigConverter { + + public SysConfig toDomain(SysConfigEntity entity) { + if (entity == null) { + return null; + } + SysConfig domain = new SysConfig(); + domain.setId(entity.getId()); + domain.setConfigName(entity.getConfigName()); + domain.setConfigKey(entity.getConfigKey()); + domain.setConfigValue(entity.getConfigValue()); + domain.setConfigType(entity.getConfigType()); + domain.setCreateBy(entity.getCreateBy()); + domain.setUpdateBy(entity.getUpdateBy()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + return domain; + } + + public SysConfigEntity toEntity(SysConfig domain) { + if (domain == null) { + return null; + } + SysConfigEntity entity = new SysConfigEntity(); + entity.setId(domain.getId()); + entity.setConfigName(domain.getConfigName()); + 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()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictDataConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictDataConverter.java new file mode 100644 index 0000000..1e915ff --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictDataConverter.java @@ -0,0 +1,49 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysDictData; +import cn.novalon.manage.sys.infrastructure.db.entity.SysDictDataEntity; + +public class SysDictDataConverter { + + public SysDictData toDomain(SysDictDataEntity entity) { + if (entity == null) { + return null; + } + SysDictData domain = new SysDictData(); + domain.setId(entity.getId()); + domain.setDictSort(entity.getDictSort()); + domain.setDictLabel(entity.getDictLabel()); + domain.setDictValue(entity.getDictValue()); + domain.setDictType(entity.getDictType()); + domain.setCssClass(entity.getCssClass()); + domain.setListClass(entity.getListClass()); + domain.setIsDefault(entity.getIsDefault()); + domain.setStatus(entity.getStatus()); + domain.setCreateBy(entity.getCreateBy()); + domain.setUpdateBy(entity.getUpdateBy()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + return domain; + } + + public SysDictDataEntity toEntity(SysDictData domain) { + if (domain == null) { + return null; + } + SysDictDataEntity entity = new SysDictDataEntity(); + entity.setId(domain.getId()); + entity.setDictSort(domain.getDictSort()); + entity.setDictLabel(domain.getDictLabel()); + entity.setDictValue(domain.getDictValue()); + entity.setDictType(domain.getDictType()); + entity.setCssClass(domain.getCssClass()); + entity.setListClass(domain.getListClass()); + entity.setIsDefault(domain.getIsDefault()); + entity.setStatus(domain.getStatus()); + entity.setCreateBy(domain.getCreateBy()); + entity.setUpdateBy(domain.getUpdateBy()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.java new file mode 100644 index 0000000..50ccff6 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysDictType; +import cn.novalon.manage.sys.infrastructure.db.entity.SysDictTypeEntity; + +public class SysDictTypeConverter { + + public SysDictType toDomain(SysDictTypeEntity entity) { + if (entity == null) { + return null; + } + SysDictType domain = new SysDictType(); + domain.setId(entity.getId()); + domain.setDictName(entity.getDictName()); + domain.setDictType(entity.getDictType()); + domain.setStatus(entity.getStatus()); + domain.setRemark(entity.getRemark()); + domain.setCreateBy(entity.getCreateBy()); + domain.setUpdateBy(entity.getUpdateBy()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + return domain; + } + + public SysDictTypeEntity toEntity(SysDictType domain) { + if (domain == null) { + return null; + } + SysDictTypeEntity entity = new SysDictTypeEntity(); + entity.setId(domain.getId()); + entity.setDictName(domain.getDictName()); + entity.setDictType(domain.getDictType()); + entity.setStatus(domain.getStatus()); + entity.setRemark(domain.getRemark()); + entity.setCreateBy(domain.getCreateBy()); + entity.setUpdateBy(domain.getUpdateBy()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysExceptionLogConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysExceptionLogConverter.java new file mode 100644 index 0000000..5bb7137 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysExceptionLogConverter.java @@ -0,0 +1,43 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysExceptionLog; +import cn.novalon.manage.sys.infrastructure.db.entity.SysExceptionLogEntity; + +public class SysExceptionLogConverter { + + public SysExceptionLog toDomain(SysExceptionLogEntity entity) { + if (entity == null) { + return null; + } + SysExceptionLog domain = new SysExceptionLog(); + domain.setId(entity.getId()); + domain.setUsername(entity.getUsername()); + domain.setTitle(entity.getTitle()); + domain.setExceptionName(entity.getExceptionName()); + domain.setMethodName(entity.getMethodName()); + domain.setMethodParams(entity.getMethodParams()); + domain.setExceptionMsg(entity.getExceptionMsg()); + domain.setExceptionStack(entity.getExceptionStack()); + domain.setIp(entity.getIp()); + domain.setCreateTime(entity.getCreateTime()); + return domain; + } + + public SysExceptionLogEntity toEntity(SysExceptionLog domain) { + if (domain == null) { + return null; + } + SysExceptionLogEntity entity = new SysExceptionLogEntity(); + entity.setId(domain.getId()); + entity.setUsername(domain.getUsername()); + entity.setTitle(domain.getTitle()); + entity.setExceptionName(domain.getExceptionName()); + entity.setMethodName(domain.getMethodName()); + entity.setMethodParams(domain.getMethodParams()); + entity.setExceptionMsg(domain.getExceptionMsg()); + entity.setExceptionStack(domain.getExceptionStack()); + entity.setIp(domain.getIp()); + entity.setCreateTime(domain.getCreateTime()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysFileConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysFileConverter.java new file mode 100644 index 0000000..b60647a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysFileConverter.java @@ -0,0 +1,39 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysFile; +import cn.novalon.manage.sys.infrastructure.db.entity.SysFileEntity; + +public class SysFileConverter { + + public SysFile toDomain(SysFileEntity entity) { + if (entity == null) { + return null; + } + SysFile domain = new SysFile(); + domain.setId(entity.getId()); + domain.setFileName(entity.getFileName()); + domain.setFilePath(entity.getFilePath()); + domain.setFileSize(entity.getFileSize()); + domain.setFileType(entity.getFileType()); + domain.setStorageType(entity.getStorageType()); + domain.setCreateBy(entity.getCreateBy()); + domain.setCreatedAt(entity.getCreatedAt()); + return domain; + } + + public SysFileEntity toEntity(SysFile domain) { + if (domain == null) { + return null; + } + SysFileEntity entity = new SysFileEntity(); + entity.setId(domain.getId()); + entity.setFileName(domain.getFileName()); + entity.setFilePath(domain.getFilePath()); + entity.setFileSize(domain.getFileSize()); + entity.setFileType(domain.getFileType()); + entity.setStorageType(domain.getStorageType()); + entity.setCreateBy(domain.getCreateBy()); + entity.setCreatedAt(domain.getCreatedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysLoginLogConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysLoginLogConverter.java new file mode 100644 index 0000000..9227273 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysLoginLogConverter.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysLoginLog; +import cn.novalon.manage.sys.infrastructure.db.entity.SysLoginLogEntity; + +public class SysLoginLogConverter { + + public SysLoginLog toDomain(SysLoginLogEntity entity) { + if (entity == null) { + return null; + } + SysLoginLog domain = new SysLoginLog(); + domain.setId(entity.getId()); + domain.setUsername(entity.getUsername()); + domain.setIp(entity.getIp()); + domain.setLocation(entity.getLocation()); + domain.setBrowser(entity.getBrowser()); + domain.setOs(entity.getOs()); + domain.setStatus(entity.getStatus()); + domain.setMessage(entity.getMessage()); + domain.setLoginTime(entity.getLoginTime()); + return domain; + } + + public SysLoginLogEntity toEntity(SysLoginLog domain) { + if (domain == null) { + return null; + } + SysLoginLogEntity entity = new SysLoginLogEntity(); + entity.setId(domain.getId()); + entity.setUsername(domain.getUsername()); + entity.setIp(domain.getIp()); + entity.setLocation(domain.getLocation()); + entity.setBrowser(domain.getBrowser()); + entity.setOs(domain.getOs()); + entity.setStatus(domain.getStatus()); + entity.setMessage(domain.getMessage()); + entity.setLoginTime(domain.getLoginTime()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.java new file mode 100644 index 0000000..e82c900 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.java @@ -0,0 +1,45 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import cn.novalon.manage.sys.infrastructure.db.entity.SysMenuEntity; + +public class SysMenuConverter { + + public SysMenu toDomain(SysMenuEntity entity) { + if (entity == null) { + return null; + } + SysMenu domain = new SysMenu(); + domain.setId(entity.getId()); + domain.setMenuName(entity.getMenuName()); + domain.setParentId(entity.getParentId()); + domain.setOrderNum(entity.getOrderNum()); + domain.setMenuType(entity.getMenuType()); + domain.setPerms(entity.getPerms()); + domain.setComponent(entity.getComponent()); + domain.setStatus(entity.getStatus()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + domain.setDeletedAt(entity.getDeletedAt()); + return domain; + } + + public SysMenuEntity toEntity(SysMenu domain) { + if (domain == null) { + return null; + } + SysMenuEntity entity = new SysMenuEntity(); + entity.setId(domain.getId()); + entity.setMenuName(domain.getMenuName()); + entity.setParentId(domain.getParentId()); + entity.setOrderNum(domain.getOrderNum()); + entity.setMenuType(domain.getMenuType()); + entity.setPerms(domain.getPerms()); + entity.setComponent(domain.getComponent()); + entity.setStatus(domain.getStatus()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + entity.setDeletedAt(domain.getDeletedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.java new file mode 100644 index 0000000..be40fb6 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysNotice; +import cn.novalon.manage.sys.infrastructure.db.entity.SysNoticeEntity; + +public class SysNoticeConverter { + + public SysNotice toDomain(SysNoticeEntity entity) { + if (entity == null) { + return null; + } + SysNotice domain = new SysNotice(); + domain.setId(entity.getId()); + domain.setNoticeTitle(entity.getNoticeTitle()); + domain.setNoticeType(entity.getNoticeType()); + domain.setNoticeContent(entity.getNoticeContent()); + domain.setStatus(entity.getStatus()); + domain.setCreateBy(entity.getCreateBy()); + domain.setUpdateBy(entity.getUpdateBy()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + return domain; + } + + public SysNoticeEntity toEntity(SysNotice domain) { + if (domain == null) { + return null; + } + SysNoticeEntity entity = new SysNoticeEntity(); + entity.setId(domain.getId()); + entity.setNoticeTitle(domain.getNoticeTitle()); + entity.setNoticeType(domain.getNoticeType()); + entity.setNoticeContent(domain.getNoticeContent()); + entity.setStatus(domain.getStatus()); + entity.setCreateBy(domain.getCreateBy()); + entity.setUpdateBy(domain.getUpdateBy()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.java new file mode 100644 index 0000000..8f6862d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.java @@ -0,0 +1,39 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysRole; +import cn.novalon.manage.sys.infrastructure.db.entity.SysRoleEntity; + +public class SysRoleConverter { + + public SysRole toDomain(SysRoleEntity entity) { + if (entity == null) { + return null; + } + SysRole domain = new SysRole(); + domain.setId(entity.getId()); + domain.setRoleName(entity.getRoleName()); + domain.setRoleKey(entity.getRoleKey()); + domain.setRoleSort(entity.getRoleSort()); + domain.setStatus(entity.getStatus()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + domain.setDeletedAt(entity.getDeletedAt()); + return domain; + } + + public SysRoleEntity toEntity(SysRole domain) { + if (domain == null) { + return null; + } + SysRoleEntity entity = new SysRoleEntity(); + entity.setId(domain.getId()); + entity.setRoleName(domain.getRoleName()); + entity.setRoleKey(domain.getRoleKey()); + entity.setRoleSort(domain.getRoleSort()); + entity.setStatus(domain.getStatus()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + entity.setDeletedAt(domain.getDeletedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.java new file mode 100644 index 0000000..914c8db --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.java @@ -0,0 +1,41 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysUser; +import cn.novalon.manage.sys.infrastructure.db.entity.SysUserEntity; + +public class SysUserConverter { + + public SysUser toDomain(SysUserEntity entity) { + if (entity == null) { + return null; + } + SysUser domain = new SysUser(); + domain.setId(entity.getId()); + domain.setUsername(entity.getUsername()); + domain.setPassword(entity.getPassword()); + domain.setEmail(entity.getEmail()); + domain.setRoleId(entity.getRoleId()); + domain.setStatus(entity.getStatus()); + domain.setCreatedAt(entity.getCreatedAt()); + domain.setUpdatedAt(entity.getUpdatedAt()); + domain.setDeletedAt(entity.getDeletedAt()); + return domain; + } + + public SysUserEntity toEntity(SysUser domain) { + if (domain == null) { + return null; + } + SysUserEntity entity = new SysUserEntity(); + entity.setId(domain.getId()); + entity.setUsername(domain.getUsername()); + entity.setPassword(domain.getPassword()); + entity.setEmail(domain.getEmail()); + entity.setRoleId(domain.getRoleId()); + entity.setStatus(domain.getStatus()); + entity.setCreatedAt(domain.getCreatedAt()); + entity.setUpdatedAt(domain.getUpdatedAt()); + entity.setDeletedAt(domain.getDeletedAt()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserMessageConverter.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserMessageConverter.java new file mode 100644 index 0000000..79fb62c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/converter/SysUserMessageConverter.java @@ -0,0 +1,37 @@ +package cn.novalon.manage.sys.infrastructure.db.converter; + +import cn.novalon.manage.sys.core.domain.SysUserMessage; +import cn.novalon.manage.sys.infrastructure.db.entity.SysUserMessageEntity; + +public class SysUserMessageConverter { + + public SysUserMessage toDomain(SysUserMessageEntity entity) { + if (entity == null) { + return null; + } + SysUserMessage domain = new SysUserMessage(); + domain.setId(entity.getId()); + domain.setUserId(entity.getUserId()); + domain.setTitle(entity.getTitle()); + domain.setContent(entity.getContent()); + domain.setMessageType(entity.getMessageType()); + domain.setIsRead(entity.getIsRead()); + domain.setCreateTime(entity.getCreateTime()); + return domain; + } + + public SysUserMessageEntity toEntity(SysUserMessage domain) { + if (domain == null) { + return null; + } + SysUserMessageEntity entity = new SysUserMessageEntity(); + entity.setId(domain.getId()); + entity.setUserId(domain.getUserId()); + entity.setTitle(domain.getTitle()); + entity.setContent(domain.getContent()); + entity.setMessageType(domain.getMessageType()); + entity.setIsRead(domain.getIsRead()); + entity.setCreateTime(domain.getCreateTime()); + return entity; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.java new file mode 100644 index 0000000..832b97c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.java @@ -0,0 +1,14 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.OperationLogEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; + +@Repository +public interface OperationLogDao extends R2dbcRepository { + + Flux findByUsernameAndDeletedAtIsNull(String username); + + Flux findByDeletedAtIsNull(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.java new file mode 100644 index 0000000..894a99a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysConfigEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysConfigDao extends R2dbcRepository { + + Mono findByConfigKeyAndDeletedAtIsNull(String configKey); + + Flux findByDeletedAtIsNull(); + + Mono deleteByIdAndDeletedAtIsNull(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.java new file mode 100644 index 0000000..fc22e1f --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.java @@ -0,0 +1,19 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysDictDataEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysDictDataDao extends R2dbcRepository { + + Flux findByDictTypeAndStatusAndDeletedAtIsNull(String dictType, String status); + + Flux findByDictTypeAndDeletedAtIsNull(String dictType); + + Flux findByDeletedAtIsNull(); + + Mono deleteByIdAndDeletedAtIsNull(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.java new file mode 100644 index 0000000..c75f2e0 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysDictTypeEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysDictTypeDao extends R2dbcRepository { + + Mono findByDictTypeAndDeletedAtIsNull(String dictType); + + Flux findByDeletedAtIsNull(); + + Mono deleteByIdAndDeletedAtIsNull(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.java new file mode 100644 index 0000000..e5d691c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.java @@ -0,0 +1,18 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysExceptionLogEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; + +import java.time.LocalDateTime; + +@Repository +public interface SysExceptionLogDao extends R2dbcRepository { + + Flux findByUsernameOrderByCreateTimeDesc(String username); + + Flux findByCreateTimeBetweenOrderByCreateTimeDesc(LocalDateTime startTime, LocalDateTime endTime); + + Flux findAllByOrderByCreateTimeDesc(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.java new file mode 100644 index 0000000..cc12096 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysFileEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysFileDao extends R2dbcRepository { + + Flux findByCreateByOrderByCreatedAtDesc(String createBy); + + Flux findByDeletedAtIsNullOrderByCreatedAtDesc(); + + Mono deleteByIdAndDeletedAtIsNull(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.java new file mode 100644 index 0000000..2d5fdfd --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.java @@ -0,0 +1,18 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysLoginLogEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; + +import java.time.LocalDateTime; + +@Repository +public interface SysLoginLogDao extends R2dbcRepository { + + Flux findByUsernameOrderByLoginTimeDesc(String username); + + Flux findByLoginTimeBetweenOrderByLoginTimeDesc(LocalDateTime startTime, LocalDateTime endTime); + + Flux findAllByOrderByLoginTimeDesc(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.java new file mode 100644 index 0000000..c3a68d4 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysMenuEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysMenuDao extends R2dbcRepository { + + Mono findByIdAndDeletedAtIsNull(Long id); + + Flux findByParentIdAndDeletedAtIsNull(Long parentId); + + Flux findByDeletedAtIsNull(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysNoticeDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysNoticeDao.java new file mode 100644 index 0000000..3a9771c --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysNoticeDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysNoticeEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysNoticeDao extends R2dbcRepository { + + Flux findByStatusAndDeletedAtIsNull(String status); + + Flux findByDeletedAtIsNull(); + + Mono deleteByIdAndDeletedAtIsNull(Long id); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysRoleDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysRoleDao.java new file mode 100644 index 0000000..973c68a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysRoleDao.java @@ -0,0 +1,15 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysRoleEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysRoleDao extends R2dbcRepository { + + Mono findByRoleKeyAndDeletedAtIsNull(String roleKey); + + Flux findByDeletedAtIsNull(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.java new file mode 100644 index 0000000..6467fcc --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.java @@ -0,0 +1,15 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysUserEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysUserDao extends R2dbcRepository { + + Mono findByUsernameAndDeletedAtIsNull(String username); + + Flux findByDeletedAtIsNull(); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.java new file mode 100644 index 0000000..4694ef1 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.java @@ -0,0 +1,17 @@ +package cn.novalon.manage.sys.infrastructure.db.dao; + +import cn.novalon.manage.sys.infrastructure.db.entity.SysUserMessageEntity; +import org.springframework.data.r2dbc.repository.R2dbcRepository; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public interface SysUserMessageDao extends R2dbcRepository { + + Flux findByUserIdAndIsReadOrderByCreateTimeDesc(Long userId, String isRead); + + Flux findByUserIdOrderByCreateTimeDesc(Long userId); + + Mono countByUserIdAndIsRead(Long userId, String isRead); +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java new file mode 100644 index 0000000..f82996d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.java @@ -0,0 +1,57 @@ +package cn.novalon.manage.sys.infrastructure.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; + +public abstract class BaseEntity { + + @Id + private Long id; + + @CreatedDate + @Column("created_at") + private LocalDateTime createdAt; + + @LastModifiedDate + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + private LocalDateTime deletedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.java new file mode 100644 index 0000000..176b763 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.java @@ -0,0 +1,107 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table("operation_log") +public class OperationLogEntity extends BaseEntity { + + @Column("username") + private String username; + + @Column("operation") + private String operation; + + @Column("method") + private String method; + + @Column("params") + private String params; + + @Column("result") + private String result; + + @Column("ip") + private String ip; + + @Column("duration") + private Long duration; + + @Column("status") + private String status; + + @Column("error_msg") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysConfigEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysConfigEntity.java new file mode 100644 index 0000000..5358bd1 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysConfigEntity.java @@ -0,0 +1,121 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_config") +public class SysConfigEntity { + + @Id + private Long id; + + @Column("config_name") + private String configName; + + @Column("config_key") + private String configKey; + + @Column("config_value") + private String configValue; + + @Column("config_type") + private String configType; + + @Column("create_by") + private String createBy; + + @Column("update_by") + private String updateBy; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictDataEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictDataEntity.java new file mode 100644 index 0000000..88a6938 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictDataEntity.java @@ -0,0 +1,165 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_dict_data") +public class SysDictDataEntity { + + @Id + private Long id; + + @Column("dict_sort") + private Integer dictSort; + + @Column("dict_label") + private String dictLabel; + + @Column("dict_value") + private String dictValue; + + @Column("dict_type") + private String dictType; + + @Column("css_class") + private String cssClass; + + @Column("list_class") + private String listClass; + + @Column("is_default") + private String isDefault; + + @Column("status") + private String status; + + @Column("create_by") + private String createBy; + + @Column("update_by") + private String updateBy; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + private LocalDateTime deletedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getDictSort() { + return dictSort; + } + + public void setDictSort(Integer dictSort) { + this.dictSort = dictSort; + } + + 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 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java new file mode 100644 index 0000000..d2b9155 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.java @@ -0,0 +1,121 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_dict_type") +public class SysDictTypeEntity { + + @Id + private Long id; + + @Column("dict_name") + private String dictName; + + @Column("dict_type") + private String dictType; + + @Column("status") + private String status; + + @Column("remark") + private String remark; + + @Column("create_by") + private String createBy; + + @Column("update_by") + private String updateBy; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysExceptionLogEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysExceptionLogEntity.java new file mode 100644 index 0000000..2bc9a21 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysExceptionLogEntity.java @@ -0,0 +1,121 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_exception_log") +public class SysExceptionLogEntity { + + @Id + private Long id; + + @Column("username") + private String username; + + @Column("title") + private String title; + + @Column("exception_name") + private String exceptionName; + + @Column("method_name") + private String methodName; + + @Column("method_params") + private String methodParams; + + @Column("exception_msg") + private String exceptionMsg; + + @Column("exception_stack") + private String exceptionStack; + + @Column("ip") + private String ip; + + @Column("create_time") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysFileEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysFileEntity.java new file mode 100644 index 0000000..f30b3d4 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysFileEntity.java @@ -0,0 +1,110 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_file") +public class SysFileEntity { + + @Id + private Long id; + + @Column("file_name") + private String fileName; + + @Column("file_path") + private String filePath; + + @Column("file_size") + private String fileSize; + + @Column("file_type") + private String fileType; + + @Column("storage_type") + private String storageType; + + @Column("create_by") + private String createBy; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("deleted_at") + 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 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.java new file mode 100644 index 0000000..2ca3754 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.java @@ -0,0 +1,110 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_login_log") +public class SysLoginLogEntity { + + @Id + private Long id; + + @Column("username") + private String username; + + @Column("ip") + private String ip; + + @Column("location") + private String location; + + @Column("browser") + private String browser; + + @Column("os") + private String os; + + @Column("status") + private String status; + + @Column("message") + private String message; + + @Column("login_time") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.java new file mode 100644 index 0000000..e29a1ef --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.java @@ -0,0 +1,85 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table("sys_menu") +public class SysMenuEntity extends BaseEntity { + + @Column("menu_name") + private String menuName; + + @Column("parent_id") + private Long parentId; + + @Column("order_num") + private Integer orderNum; + + @Column("menu_type") + private String menuType; + + @Column("perms") + private String perms; + + @Column("component") + private String component; + + @Column("status") + private String status; + + 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 String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysNoticeEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysNoticeEntity.java new file mode 100644 index 0000000..2de0d9d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysNoticeEntity.java @@ -0,0 +1,121 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_notice") +public class SysNoticeEntity { + + @Id + private Long id; + + @Column("notice_title") + private String noticeTitle; + + @Column("notice_type") + private String noticeType; + + @Column("notice_content") + private String noticeContent; + + @Column("status") + private String status; + + @Column("create_by") + private String createBy; + + @Column("update_by") + private String updateBy; + + @Column("created_at") + private LocalDateTime createdAt; + + @Column("updated_at") + private LocalDateTime updatedAt; + + @Column("deleted_at") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysRoleEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysRoleEntity.java new file mode 100644 index 0000000..ab7d360 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysRoleEntity.java @@ -0,0 +1,52 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table("roles") +public class SysRoleEntity extends BaseEntity { + + @Column("role_name") + private String roleName; + + @Column("role_key") + private String roleKey; + + @Column("role_sort") + private Integer roleSort; + + @Column("status") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserEntity.java new file mode 100644 index 0000000..ffaed9a --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserEntity.java @@ -0,0 +1,63 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table("users") +public class SysUserEntity extends BaseEntity { + + @Column("username") + private String username; + + @Column("password") + private String password; + + @Column("email") + private String email; + + @Column("role_id") + private Long roleId; + + @Column("status") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.java new file mode 100644 index 0000000..f713494 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.java @@ -0,0 +1,88 @@ +package cn.novalon.manage.sys.infrastructure.db.entity; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; + +@Table("sys_user_message") +public class SysUserMessageEntity { + + @Id + private Long id; + + @Column("user_id") + private Long userId; + + @Column("title") + private String title; + + @Column("content") + private String content; + + @Column("message_type") + private String messageType; + + @Column("is_read") + private String isRead; + + @Column("create_time") + 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; + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.java new file mode 100644 index 0000000..9f166a4 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.java @@ -0,0 +1,57 @@ +package cn.novalon.manage.sys.infrastructure.db.repository; + +import cn.novalon.manage.sys.core.domain.OperationLog; +import cn.novalon.manage.sys.core.repository.IOperationLogRepository; +import cn.novalon.manage.sys.infrastructure.db.converter.OperationLogConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.OperationLogDao; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Repository +public class OperationLogRepository implements IOperationLogRepository { + + private final OperationLogDao dao; + private final OperationLogConverter converter; + + public OperationLogRepository(OperationLogDao dao, OperationLogConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono save(OperationLog operationLog) { + return dao.save(converter.toEntity(operationLog)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.findById(id) + .flatMap(entity -> { + entity.setDeletedAt(LocalDateTime.now()); + return dao.save(entity); + }) + .then(); + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Flux findByUsername(String username) { + return dao.findByUsernameAndDeletedAtIsNull(username) + .map(converter::toDomain); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.java new file mode 100644 index 0000000..6e39b83 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.java @@ -0,0 +1,57 @@ +package cn.novalon.manage.sys.infrastructure.db.repository; + +import cn.novalon.manage.sys.core.domain.SysMenu; +import cn.novalon.manage.sys.core.repository.ISysMenuRepository; +import cn.novalon.manage.sys.infrastructure.db.converter.SysMenuConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysMenuDao; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Repository +public class SysMenuRepository implements ISysMenuRepository { + + private final SysMenuDao dao; + private final SysMenuConverter converter; + + public SysMenuRepository(SysMenuDao dao, SysMenuConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Mono findById(Long id) { + return dao.findByIdAndDeletedAtIsNull(id) + .map(converter::toDomain); + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } + + @Override + public Flux findByParentId(Long parentId) { + return dao.findByParentIdAndDeletedAtIsNull(parentId) + .map(converter::toDomain); + } + + @Override + public Mono save(SysMenu sysMenu) { + return dao.save(converter.toEntity(sysMenu)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.findByIdAndDeletedAtIsNull(id) + .flatMap(entity -> { + entity.setDeletedAt(LocalDateTime.now()); + return dao.save(entity); + }) + .then(); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.java new file mode 100644 index 0000000..48ff0b6 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.java @@ -0,0 +1,51 @@ +package cn.novalon.manage.sys.infrastructure.db.repository; + +import cn.novalon.manage.sys.core.domain.SysRole; +import cn.novalon.manage.sys.core.repository.ISysRoleRepository; +import cn.novalon.manage.sys.infrastructure.db.converter.SysRoleConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysRoleDao; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Repository +public class SysRoleRepository implements ISysRoleRepository { + + private final SysRoleDao dao; + private final SysRoleConverter converter; + + public SysRoleRepository(SysRoleDao dao, SysRoleConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono save(SysRole sysRole) { + return dao.save(converter.toEntity(sysRole)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.findById(id) + .flatMap(entity -> { + entity.setDeletedAt(LocalDateTime.now()); + return dao.save(entity); + }) + .then(); + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.java new file mode 100644 index 0000000..9d5ee4d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.java @@ -0,0 +1,57 @@ +package cn.novalon.manage.sys.infrastructure.db.repository; + +import cn.novalon.manage.sys.core.domain.SysUser; +import cn.novalon.manage.sys.core.repository.ISysUserRepository; +import cn.novalon.manage.sys.infrastructure.db.converter.SysUserConverter; +import cn.novalon.manage.sys.infrastructure.db.dao.SysUserDao; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.LocalDateTime; + +@Repository +public class SysUserRepository implements ISysUserRepository { + + private final SysUserDao dao; + private final SysUserConverter converter; + + public SysUserRepository(SysUserDao dao, SysUserConverter converter) { + this.dao = dao; + this.converter = converter; + } + + @Override + public Mono findByUsername(String username) { + return dao.findByUsernameAndDeletedAtIsNull(username) + .map(converter::toDomain); + } + + @Override + public Mono findById(Long id) { + return dao.findById(id) + .map(converter::toDomain); + } + + @Override + public Mono save(SysUser sysUser) { + return dao.save(converter.toEntity(sysUser)) + .map(converter::toDomain); + } + + @Override + public Mono deleteById(Long id) { + return dao.findById(id) + .flatMap(entity -> { + entity.setDeletedAt(LocalDateTime.now()); + return dao.save(entity); + }) + .then(); + } + + @Override + public Flux findAll() { + return dao.findByDeletedAtIsNull() + .map(converter::toDomain); + } +} diff --git a/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/security/JwtTokenProvider.java b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/security/JwtTokenProvider.java new file mode 100644 index 0000000..3adca6d --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/security/JwtTokenProvider.java @@ -0,0 +1,66 @@ +package cn.novalon.manage.sys.security; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class JwtTokenProvider { + + @Value("${jwt.secret}") + private String jwtSecret; + + @Value("${jwt.expiration}") + private long jwtExpiration; + + private SecretKey getSigningKey() { + return Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8)); + } + + public String generateToken(String username, Long userId) { + Map claims = new HashMap<>(); + claims.put("userId", userId); + claims.put("username", username); + + return Jwts.builder() + .setClaims(claims) + .setSubject(username) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration)) + .signWith(getSigningKey()) + .compact(); + } + + public Claims getClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } + + public String getUsernameFromToken(String token) { + return getClaimsFromToken(token).getSubject(); + } + + public Long getUserIdFromToken(String token) { + return getClaimsFromToken(token).get("userId", Long.class); + } + + public boolean validateToken(String token) { + try { + getClaimsFromToken(token); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/novalon-manage-api/manage-sys/src/main/resources/application.yml b/novalon-manage-api/manage-sys/src/main/resources/application.yml new file mode 100644 index 0000000..a8ea9c0 --- /dev/null +++ b/novalon-manage-api/manage-sys/src/main/resources/application.yml @@ -0,0 +1,25 @@ +server: + port: 8080 + +spring: + application: + name: novalon-manage-api + datasource: + url: jdbc:postgresql://localhost:55432/manage_system + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + r2dbc: + url: r2dbc:pool:postgresql://localhost:55432/manage_system + username: postgres + password: postgres + flyway: + enabled: false + +jwt: + secret: novalon-manage-secret-key-change-in-production + expiration: 86400000 + +logging: + level: + cn.novalon.manage: DEBUG diff --git a/novalon-manage-api/manage-sys/target/classes/application.yml b/novalon-manage-api/manage-sys/target/classes/application.yml new file mode 100644 index 0000000..a8ea9c0 --- /dev/null +++ b/novalon-manage-api/manage-sys/target/classes/application.yml @@ -0,0 +1,25 @@ +server: + port: 8080 + +spring: + application: + name: novalon-manage-api + datasource: + url: jdbc:postgresql://localhost:55432/manage_system + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + r2dbc: + url: r2dbc:pool:postgresql://localhost:55432/manage_system + username: postgres + password: postgres + flyway: + enabled: false + +jwt: + secret: novalon-manage-secret-key-change-in-production + expiration: 86400000 + +logging: + level: + cn.novalon.manage: DEBUG diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/ManageSysApplication.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/ManageSysApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c405f10678c993050101b0fdf865635eab3750 GIT binary patch literal 758 zcma)4O-~y!5Pc2_8@A!2q2-$cw-8nJt(R0tG*VAXi%1m?oV<(K7*eET_0)<3 zKcGLV>UfL99`?Y&Gxp5*&6{Wc`TO_;;28S>S`5QPb8T)#W;D-*7OCXLL%~m~?c||2 zp3gIt2&aq=&}LY>7Po?DLZ|$Dd@U2lu=rVN<&GE@28UCI_Sjs?5DQr9p@T(+)ktai zt;}O-e~37f4E@L?BAW`U{P{W9b~9Ble28ApXhhv|p)|wB;39fqHgQ(zbaXfk@fPa= z`ZTApDKF+eeq}{2?~J|Su`!NMs$gx-9^TX!T6&TR%v*B;7oxj`=djvfu2=o0A5nznjaDdm;BD)W{SNM;>FT5HlZgK;$3;TKI$U?%%NAf>3iEIsd; z;}#Zdg9p0;cgH8Pj=QaUW!JQ~w_I6LT;J8b=r+3H9+Z7YuM6rc%^Ik5_)*37&5~L( zJ(CF2w(a=RHyyhMu$6K$=Bs^QmoK*J^Ge#O7%mb~D~aQ9@-r zW!6>xo@x2Y%@n0+3;aBO%8f&NK2v$J;O;4xrVW}!-!IpVoH~WICgIR8nqj1pbgUr_ z!+1-e$EbL|Q!;;|xo1x`NC+=e7jaW@T*0*%t_q}2=I#s^)9^OlpZ<$^w~J;3ACwB}LqY6&ZvT9gqRhZOKx;AV)tGcycy!n@}I;YBYVEnOs>J zsfo21^rrli^Mm;A2G7-WSvK{6QhjnVj+^*6hK~f+&+R*{!DzUJPk3rs`o$&b8^szA z*T*-rN7*q%$Dlfz3KJ$%!lwdHUlX*^v|%XEi(?Kc4Y%<*L$R#flIf={OJMUfhdPTl zwN5ayRsaHI(=yw-^8#YFmmL} zroHFvDm_~ZeQuOnRO`408Xh4>TQfP-rv&~UZ-|0OGE}}O?SiGe(X8X_R?4Y{ZBhI* z%rptE9+Xw%_OmaBN1iO(7`2h+jI^wr>8n&<7aj@>G+rqR?1{AmzK!ECzKdZ);KBJr zJj0R|WIqj?cp?xhm|pmTT6h)Flj`fly1??QNZNIz%+m=xt?|GZ*D#G45+)OvVZOX? z+kCQEd~PW(hHZhdmmI26FmMqT|4y1HNJ8o(f79oMx%$u`OlOdaA)po+_fya3ygD#nf!5Aq(M0>Mo^7(zd; z;u6OJ=)q7ybP!cx0+ZZ1#kEes0TS`RWSk1n=cy_{KRwy;J8o>WCqKwlG5aUxs`xCL zxpOpA#oa2tJYp+JQu!dHrs3dCh%sDlxa~B)!Xno@aG(D+JgD6_&feD?XZbDh3jnW@ oi#2?YA8NfHVW0rTwGqm0p@s z@7X`F(ju|%{3yhkNt%W-?Os#~@sM$BAAdf#?;L;p^w$RfOIY-fW4IHlKLOu`FGwZbBE#6+ z^>v2)vTg|vN9ej8Wmb&Qrho}HHnXOTusYflEkD$8S4P~Cc7E6BW+YZ zQ_f6Gkjjy+Q2DWy-b zX*6$z+)__2)pgH=;uo1P_-uARuO$3on0e7tPR3$gT1f<7O8Q;eF)3y@YSbQsUF|WT z$AJ+#X%E3NHCU~LazyIsr;6SWR?@a|Poyy1gqKXbeUno_9w+Eq?n_}BCuzoT3a9DhOuA2{YlxMjl|I(F46LaPtc!Hw z5W|HO)+fcYU=vgNu(KJkr}uy@=2FleL{xbrs@;2j}|Q=bqe;BmesS?FWD@JoHdtcpR%x=`K&S3RA9lQ-ro>!&s{$ z*$h95dQHbC!fofiha$u5G4Jv);i?(Fs~?Nl(b4Gux64%{5r*MuG?BR0vreQ#`hM6Z zL+Pbd(!FAMzVS~Cj}94%+qxk)2!OIk*axQcq&e{IjK^;Rhu^^h`CbQ1$7Y&NdIs2j^b3s zu(MW`6&$=vvY;R42=0q%cy}?4EEf-FVNlDLP?@W5wjj z3o}Ibi=w-=jcD|AP%33x#tOry$wJC>bP>hmZZVY4GBZ5}zot7T7O!R2k;Nh5*}$q< zCmB}vJIcvayir|gCG~166J;)IDrGJj5e0Q)r5|xP2LCJ~&4(kJ&z=M)zPK>gdrln= zM3Z|&y7Wd7%90+0a=TI(ZsJzY!(E1jk;F5ldAQH8JiHhY6hmcCT1)CUAgNlcgW(dr zTqFxjp+vg^?LCyqPLub9ZVP1n@9;m*SH9xv&m1#H-x48#B1Hm~eD7lci{vfQnqowl v5nsdgv1H3*$QCXpyOD8XmA(bs#2VS`|F_8A?(YM#>$HFev`U1#gL{7fxb&;i literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/BaseDomain.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/BaseDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..374c4b11a2d2d4feca4db5fb0a6f94bfe9c40485 GIT binary patch literal 1304 zcmb7?-EPxB5QWb=e~ocTn$kep21uYKNm2a(ph~3?5>oh)XnVi0SE;MSt{kTlZv_$v zi3=WpheFJ3;so671vfk1oilU3o%OHZKYju@#z6^|z;iEj!{}O$qtKnmP>z&4{WNvG zC|0f?O=J+dujEwq^=Aorf$F8amhM=FBlrFAQhAAh75H>MSS1EgIC>#a_F^RyX75&pz6ws^lW_Kgd{4=w2~_IMnxKHJP2Xy( zSh>v;2j#TQGBMZn(~-08nFBl3EfWIv$7mLN>UF?luB`rvLw@yqiwbk}TjgQ#Q0U8I zXdTH_N9szEE$H!RU8kK(QBW-OzT@r}EvwR6oF8I?zFA5F)UZiW;2ySU{kQll>YpiT zVO6|tEPj9nskr!vqD8UTJNSnB%G%ba8`_ZV>vPq@p3(Sz0^5`;(Bo4O*uk!WshMTk zGBQ2FWAeDc)XXw9$ZT78xXHw`UNV(5Q_INI&N4NPOi#^B?JQG^nA*26@w+dX%9?4< i$h4nj+A}hB%uM@PrY9mfhYZDEnpC{8(6E-3|ScDI%<_%RVnEQB4}b#T6&)A z9s5eAaV>({Suv8n8wUFUY!iY zXsd7(BZE~$4^>2`R75{i#FeXvi%}8LRK)fehp-|ZLVOP5n}v~KOw9d+p>Ikyg3qLy zjKe67c_@JUFotgo9>7C<-cJ4w<6pJpoH2P49^ncoc^hL4V{&f(2aMme&Z^mATGp!=it1e7*Zz86wVp=vbt>{eaMy8i$rWKuO6PdQUFwq^3n0gh{DlXvey<5|n zc8yHy@CNVEoqM;YGZm5PunQCYPa-C+nBE$F+R&Na8=1DuK5ghsC1g78!bJbJh^bF8 kZ5x?(bfyy{)1H}WM`t=irt>aL^q-BG`W4eYK4Wn35A9AVnE(I) literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysConfig.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..a325a79c714df2f97d4d26e1b9df5f3de8811600 GIT binary patch literal 2379 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 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysExceptionLog.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysExceptionLog.class new file mode 100644 index 0000000000000000000000000000000000000000..8f72432ad991dbc7421c37b79adbe756b101eb20 GIT binary patch literal 2610 zcmb7^TT|0O6vxjNN=r#;DJ}Q=MOzReA}Uu!E{Ya(rpS9pcS^8Lm^3i*t#n4m86W%r zekjLtHf;zyn+IQVvb+Ct_P6Jp-9LYS{RV(tC?_DsV8yg`+qp67j;%Kg+o*B9dE3-Y z$K`s}X&9ERS8kgJUrc`GS&m(HY6<9Mki9f+483mHHT}c+B{w|=F{_I6<-3KlW7jqr zB(Iy?wT%X6kPEF=Jl7KIanJJVxR~bcO-_V3)!^QRQ}qX$Klo_4Mx)6<3$(}08iU?o zSn&+=GqGGTNSQ7-Jbr4?*2DhR9uD-fV;c4S))EqSZCSSE?J(#lmd+S-?m1PSf({ta zAP4;nGG)u=C)bU0?w%Uw#F`T!&J5S0aci>EyReXLwfx^HMTU5ddqJAwbwPt}a!sPEm_!a-4_bx_NV;VWQl!hG?%pDn9`!zYTl_?W9ulWfe7Az7 z2$X&+P~c}8Xr#>q+IE|eI@k(3h144wq}%H78iT&DS~L>rcQoiFeP0;6)n=k-SEPEa zL55VKKG=J7qP{PTwW##$9nxKSZe73bPD`JqKknU^l=GF?TO z#^@b*;ZqQ!7Q(+6m0DP=o3L0HVKL>xVmgJzL_|4-;N6XO0 z7k)zFn~)9Sx67Y|A^g``|HCkXBL<@|hTr?n-(mc#xEdGFT zdFy`RJ>VScD|p`FHwN$j0Wg4RL;wH) literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysFile.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysFile.class new file mode 100644 index 0000000000000000000000000000000000000000..ecf4eebecc583059e2fe3afed4cb7effac9e46a9 GIT binary patch literal 2154 zcma)+ZBG+H5XWZ=eLhNQc`gr%542P{6%_?U0b^oPk)(w8+jcES+Bj?G@;o1NXg|IGe&X6OF={q-9F4&X2i2?n*cZQ9Ni?>V;F=Qi&Ob1)p3 zZO0X6$LVv+Hk-r2JF6$sFwUTO!LPX4<965l*t!sHk3quf;C|!!L&LGVy9_d)(CL`> z1%p!LYtwVB>+dJrI}fBy>kCSy*Xi&xPV)oLaS_O0W!kRbo;Vyb$okXH0iM3#hxV+# zFdI&r_uiuD6jw-)+OurS+h;IVt(`F#KXN)E2V*d8KoO=GOg1cA9AEZZ!ae1!o&=>3 zXWX@D9c+$!=hlEhz470v!n2cI;l0Pil&ZDJgij4HNLWDR$S0rfC@4M&Ul=ekia6S5 zU|>XlCErD5lo`#-pdhadD8MAT;b{@Kr65BZFG^Id>0G*PK?Ok9pfNV->BDUdI);sv zfdrKnX9+5Sw3tk3F3P;wo|zaP zdJ7>>R`P6UdFm?9td{4Yo~N$z%*F7~n+$n!l4n!PW2!v!TAs&x9#iF6h~c5$2zm07 z=ZThQOXXSA@;uY?Y^gkz7#`};kjIcb&$T?;D$kOZ=cS%!Tjg1f;h}#;$TJ~%c3>B` j)c)F2c~-PM`|w)VUwbOgY77tkvqGMNtJe+ESpj9HpuhN~KWVox}=8iH&TBihtEgtt$1Q zKcGLV>de|PVYPnf%g*lX9N*5)?w`NEegnV(yw8BfV7=xTj(cM^UB_sdj@hsb|JFBZ zu4fr_w`JOnQMvWYZo_tP$UrZH+?9D_8cow_7-!Whs}?ZO>^kbpcN=BbY3wrSYx|bx zm@SJzzH7G}xb?x-~PfU57!Y>bYOg1tYpXgR~!*K^rHTmgW1%#z1cp%DGJ; zC&Q2dE{rn9Xdat^MO&CTy=Oaiu+N~Uw0yy!_sFeVS?GaL4#SXVFjTf3>tnlBwY+n) z+7y5k;==T7T1U#>;L^tYM)|+Wg!xkqEBJs#$(NS94lc@~1A`e3DM+K4ADR_PvK3M1 zPOae5t$#8-EMZ`INYamSKgUHKxfeYuE5(1nAp?DAj`8ozN4v8`)|5xUUX$N42c7%` z7v2q}qtep#(Ed7yY$t9<&mfCdhvChU(Gw2+WR%6^kvhzA=F|3b4!o1&43DIvcST$@ z?Y`nLK)X6RhuSdyY1jc|@|we7Cw`=6zy)dC8`GW2D7u4U9C8?f9J*l|(cNK76{89% zyr@vwire;T)`?9Glk0jI8`S!+fPs7Pap|DZ_2NvUYY-C4DkPRqNUV^MSPCKW&_d$L zghV=&1&oOOiemv+21H?)Oq1O7Fs}7N}i``o=ur&DuIXINX*kOc%CVFwq%}ZCC>{r&z8(nOyHrn8uM_$ z^HRyPE%VGMd3Mx1+cM8=0uTKeG0%YD*;VrF$vksPo_#gXp3F0!z(apm%rhu>-oRT_ j$^XxR%(I~6If7%=dq0qQ787{r4~=<-1kXDhH8}YP)66XY literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysMenu.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysMenu.class new file mode 100644 index 0000000000000000000000000000000000000000..8560f06ace53d90ddaa9c905fbe3213b8ab5b2a7 GIT binary patch literal 2528 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 Ml43fbGleJr0Ay0`mH+?% literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysUserMessage.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/domain/SysUserMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..58d223f80d3e902abbcc8de3575d069903601aff GIT binary patch literal 1953 zcmb7^T~8B16o$_f+S0Pn(((-|sAwt5B7UHPCI(|dQq)N0e%VgSl6KeZE+qUbO)w^2 z_yhb=#`nywrJYPKyxFrm^S)=Eb7p3L|M~fgh~ChvJY@uJxxVcO7fvVe?XKfHZD~iB zk?jVdv|B;f@qGK}GWs0J@K8n(rt>r^sC?#JICjVJ+xCZ(GwH^HGF}Vgjq8a<;J0@L z<<8+fz+5)=;*Jzl>C+s=p{G=NH}GTWBhPp@S*LmV1>&3+eUc8`MK_dAESp{zqYFuj z7$0^caGlQEbc)y8^L#IUEoh{+ek^EoKWND!jZoF15|ss&8lErTpLb7W*mO=3AWm`Y zgdTsVgQM}O7YW*K{BM7NkZsGDE3VYm`)XDFD3G8fi?Wo1EJ|e6nyzB-@}Z1RgVskU zbh#YGaVK*2~B!5c*|I4TQttPN$C2fk^&CYhO+FjMHb7rfMitA1h3e) z(@X!VFzhwwcy7@IO~S`WeZJ+iB7;p8b`+e4u6*b5{#OSN_$D7=T1D~^+!I_9-YvXk zxZNtEeJY|EDxz2wQH_cqLM$NzP8^<7__7fNVz&N+D&LfB8qZuZNHci1()U@K!mUZxu$X7fwL3}UXn@tqd+rOV1an_eQ2oLwZ$CFn)cj&I6KWjQq)yQ+7YNr0I={(azc=!zTc*YdZx{;@@ z^UN4|9+-LRI?wD79zKgbo}%J;Xyn<{dFG5fTV|e3oo9Xs58sI%&$!}wWaQb_c@~U3 zPs}{qI?v(|9=@AB9!v2&rDqtL!u$2*yrLbQXUWL(LftDi58SUEoo9In5C0>2JQIp% J7tajs{RPfk6^#G@ literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/IOperationLogRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/IOperationLogRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..947e26cb2c6c49929da6d86e6b3d4bb4d7802228 GIT binary patch literal 1113 zcmb_bO;5r=5S^`jiHP|95fiU?apM^^!2=0N2`bV1(ynF6vO~5lk)wahgFnC@W!zFJ zy?`n4xH~g%-kX{C_5JY)08Kb6f<@rgQB>iCNmO*i6!SRsr#^L1bE^3meG#CZ(sp;u zH46kP8@;FGzX&-3wIQ1@Dw*p%enC>bX zcYy$b4P#`0yzyWj3SdFeyeud|Ir=q5g2QTeQFC!VmDHjJGWm z69dU4E@#etoO|xMU*8{}0MLPR2TBC4Jw=tCF{u@uFvS8+!z84hHk=wh)uD*ANoa47 zgnh2!r{c?jGJ(dJ%@~zT1@vJ!=3Ydg_9~Qrm-KuBwB;^wSF50X=^D;Fte7{L#zQH> z5jV82m2MN*9Ed=%C^nqHi(U4OyJiw!Pnb}2K1BN#Ta^SdZ1j0F(*7eeY{DaMLIO_8 zzau4qi`GiIT^YY)4R?KnEv4ODI%LCDWGUdBk%ee!hAqR|wBS|_*$lUI-?GqsrJnQk zzx`V=+rb<(ed=!lb)QSLLhj&>tp}HWf7Zg!j8-4$*m%4vB+AwNdq`JlPL%+G4ZKT$ z3f@%(s!#$4UnQtPJ^jVwfb`_HU>ieoXb0cBuvdgO7NPrD=m8uS(9r@q&Y+WD4VnuG L8(`_vtn1ki?MFam literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/ISysRoleRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/repository/ISysRoleRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..59122118c5783292a1e1f60972000ada479995c4 GIT binary patch literal 864 zcmb_a%TB{E5L}0}DdAP#N3P|9uSi8m;ZUh46{wXsad8uqx^nHxP73)o4txL~h1fK- zMM4xs;^fD8XFNOm{_*+-00EqM;1IZs6jgf0q*ipo6iYa@xuuadoEkpWR;1eGv^&Uc zUrXL!UU}dWXpY&8QOQ(7?}lR@r34yJLd7?EHzq(^;R+A6O4{e4;VeSNQec`5rLZGz zXiqEMCa^gWiDGGHIDyA%)mPyfC$XL|q3D;1_BBd50)N=-@pPo)duG^#r`%Wqu4OY+ zzin0E`^(nzzmZjS>0y{fZUp?8OSD)f6IAW(D#r&c;&}tTBIrO$0%xsX8_<#23pP7k z|DviZf1ooH@s22ro&KE7i{iU=0t7a2)B#)^)f&{n0S`|OG{DEThVzCPfi2ixLOTm+ acMk1+t7pWlV;4EJMl+nYL(u&4nM}M;UKh zDI`X;iMyFO_s%)zKHfiG-vFQuM+OuKoZFI0HD#WXbj&1kIrSr-+Ddb(`9%35P&%SL zEAsDru5Ys^1BwLdBQ|B!W74J9gAum_0<|Y0olX=7OE%^N&YI>t$_liQZtKLUfu zz_pKP>Zj)rpo>aO^#>mh`7-h&ZRV@{2n|FnWooakvrqft% znE-(m+)aQI?p6uPPyhpO1*kwZe#OOrcG}e@#J;A*m&}QF~I|g$r3ahf56bKOG#--x4VI(f6IeEz#nBC zMA3tgKs>e6zIpRz=DoeYyaGT6P68+~xDtjNTcEavkI`T%c{a=dBeoLOoY%jdJ<|3JiDGaWMn8Lsy;CM#J?$@HV$+64aqVXO)}+b8qg#9zhph`xH0fU^_@dwy__TT^j literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysConfigService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysConfigService.class new file mode 100644 index 0000000000000000000000000000000000000000..a4c969f18bdeb0f8dbb3b8aa67fdcae05596b39b GIT binary patch literal 1192 zcmb`G%Sr<=6oyY~?M{(5w3%_aXwtu26nUN&>r$J;!k7McP=e$M{}~@PQlJmhn@Q zK-m?6Vo_{3fy?QykDMuxzV0)j=mfEOjOL{g$jPwd6QB*}3)ImnX#Plcp_RtZx7mJV zr^^ZCs$KBtLHpOtus)Bt2?;D(YFp}aJ|u9EMsXt}{(yg%^-uN$%3d-J31U8E18kww z$ke3Ydhq;@cG>eQ*!&1od@iv$c9L4@!u~!S7C7?)yC3NA}zzpL|Pq7Yl&1(8Lp2dYq*gz+#E}2h(KEj(DnxtNMq6f literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysDictDataService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysDictDataService.class new file mode 100644 index 0000000000000000000000000000000000000000..451d84ccdf9a25e79ac802717b9d6a7b6905900f GIT binary patch literal 1347 zcmb`HOHaZ;5XWaxDc}pA`1XnyH(tD8Oh7_nf=W{3*`-}^P1z;eh1iqd%Yz@l4`rOT zyi62R^tQAA&h$5ro%fH|HvlNZfdwf7r;emj^_Zt5Z8OPQoce)J9i{QWbx$~)UfO|Q z6^^Mg!|eFZf>{FjC)Q)sW3okWnory@1gr-k-LmHqI4mC3HD``dI*!)qHa+1#a!qSq z_qjwMYm1g-rmH!D#^kTh>JuTMNNHgw`F@MF)qjDQevo<$e`veMK^C(N#Hdr-OF1~?Fo}&4ClxdPq`~563aekLB z0XmLSSCjg4rKG|p-zW2!1~es*Y}RKz9HHxC!a@9TzWV$x{~B-$Dvc20D&3YNdRfwDszxV+d?Y^8ML#I z!&7X}!y?|#5m51@z&|EYY{kkJ5v^~j~$5(2?V{nXZs&_L;wZ5;Lm_XkYlwg{gZ z2ucq3Bnd*z5cKB1ZrXEXx@ttY#2Jx|OG95wq+G=v7Xhx@Us7!)y~eNFx=JdO{IFcc zD*AHVD64i^Fi>ufXfk2}(>{Vqs(adS1m{^TPN4Z8^!Jy|S>*>s_tO*z@;-^o7;oxJ z4rb<@_zW~57Y~>)s;J{N{=|qHD@s>~`Kpu4??rB2-nnZfY&)sfx z*72}yrB;p(+_av9EQ8X$NCXds3i!qCJ$jZwt|^s&9EJ>b%Daw1;aP3ciS76{l+hg; zUJK(+g+bnxff6=0$e{6e_o4F#RbRJ+RQwy!$`P$t=+UWmZ%B<2E!wkRc0NhF)<_jp zM)7R^_szI$XX7EyQXTD`_AiAY+7?a3U?bIXLZ51}AzN5Q`+%qzTnz|XDso4AB0L?m zR8qA+0HZ`dPI~6JpOTNPFt(?ct_zi)M%hRtRJbmWaTvc!uWP00Xr3lMbX@I4{Ng+Y z1y{$$!y+5Gy}*?{QF5n%$)0ULMb>x#u_#rFn4(^ib&y6&uCU9Ff18h`P|H6OX~1(jMOyLH8{#aiom(AsM0Z$TG2jJEZ{U8gw)pt18!pBb9(I! zLRSYu;o&8<9Ha>pdn{&DG8NF&3S-nL1t)Z0q-~nAI*2iz0Roq{}o;5-R)p;7* zi{4pAX+D~0EH=6A>Q0Lplx(>P36v5aqX)PbeO~AGnR7+pZmi8>k-FMv@`_nLY^f$j zrvUT(zO9;bng8L0mKi%Vf&;}>CyCM_i?MK1S#TEqwcON7uBio*}S-y|@&xJ%NfN b$VtHtcI=MeJ=mYX2R}DU2opFQ(U-pgN77Uu literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysMenuService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysMenuService.class new file mode 100644 index 0000000000000000000000000000000000000000..abd9cd007da5421062ee4500fa23a66311d32992 GIT binary patch literal 1365 zcmb_c%SyvQ6uncesqt0cZ@aA<2i#VKx+qjq6e_OVOp~#WOlQg@srE$@L-pH;myzx=m8UoP82jQu~kVR!)k{|Pdd0|h7EYcO-R5= z_&22_P^%ZxZOQl*Yk0FGY$>f~)*&0NB1;1&j4Vt`GHe-EhB-Ia$E%EZG7$u>>lW@8 zx;hzxmwzi}D{p>~s&V6CkV|s|E^#z6olV=B{F(oIErN9LR(i3JK~nF|aGdjtdeNgu z@3hdZ$&J6wOt*7jW-q%^1j>n-_@Labj*ZV-LZaBMKU?H1F=&ARfjL}901hsdGAuv| z96Xhv0xo{bxEUbXH%qXLp&7J-=T%tCL#xx!^)z$?Hgjle3T>y*PBFCmtM}eCE9<=v S2YJE6DRhMF2pp$ePrd=4$eAYq literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysNoticeService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysNoticeService.class new file mode 100644 index 0000000000000000000000000000000000000000..77144bb3279d44f2cfc9d6aee32c2adf874a8441 GIT binary patch literal 1070 zcmb`GNlU{(6vyAxHfiftx4K-s){BGSts=CCLLsd}z@s=##&k+LBa;P#-^_y_zz-$9 zB;7!)1ia0g|Gas>w|#!Se*i!S&P*r~xOOC!DrUZtbjl?2I1Q43I!fb#>sUCP_U$AX zst}KMeq%zJKx4vUMtvqddN-PICnR7#3+Z-zpTK$R!qS{Mq0;$ZFVV;s!I*2>^P|@` zftoEm$-+o;0>kyMZ>%+tu9`9-=>oBRi=S_$Al<|cF+f1zs%0%;okgrvF&Xqd0j86~ zb)T`n{o{AV6EkEs=LG65_pue-B<(<_Xg!zH_Mn8Djbz%kCnPiT?_&Q zHgG!uD!5@4Fwi#9DnS+P8r1QW+ncbRzQR$5bQyPGcOfBP literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysRoleService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysRoleService.class new file mode 100644 index 0000000000000000000000000000000000000000..70bf88aee1be0c3965bb6f9ab7db2f199aedb950 GIT binary patch literal 898 zcmb_aO;5r=5S^_+v3{YV9=+nlO}s)(@IZno(b&Y3m!-RwCCe_^wkUtigFnC@Wt_Hr z7!ydEcV+{F&)u|;aG$Tf%>b|{BGXo1Zc}&_kE+I_LXl13ln3D)zfsSWIPg< z4vaQ!0=t2XG)qz|2)vY=?)Y0Ya5G_2(}jZeEuL~DGHeV)GBW&;SvC=gurUEQXa#L7p~pG&WOM8E*Ma783J>7wv;6A$5B#zP1ONa4 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserMessageService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserMessageService.class new file mode 100644 index 0000000000000000000000000000000000000000..6340b7d3c9edfc161c15f432dfb96c8d2b235d70 GIT binary patch literal 1182 zcmb_b+fD*85S^~T%0LEqY*o|!pkW@RcT;UVO@vNBorOucO$HkUAH0TTWhDhSm zfJ%j+l9totZd=_^qIEUrDog3K1Id1&H2iCfb@j5bh@vAx9^7-?kkwk%5nO2F=1o}G z+?dfwS(J=IY<@_w0jSNxyk4n zOgFAzi%>eW#XN0f_2+dxkGC*~0KtY{e}HTTK^AggfT?c=Y(gP^)$0fGVi%z_g|-qX oZ^RI6C-4rGr||A9a}V~X(7^<%B&@>}>u3TU>!1iuk|IvO05NoC6aWAK literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/ISysUserService.class new file mode 100644 index 0000000000000000000000000000000000000000..7aee1b84932f2ef8f8b5dd4788162ff9e3c9c8d0 GIT binary patch literal 1269 zcmb_cO;6iE5Pj=}Bse7vg+l4qnO<1IH4zdVkf?${vdRe|E%r9q$k|0}J5g@@E)M+x z{3ygYCdL9mYKenCW}jyEz1cT=cYpg2zyW^N;V|s^nrkx_q0xLKwCGD7O(X6bOFz<% zl`r|RH;w*K;AL?gRfhIZj0F#c?(@^Dq4Z;h#$Tm_!|8Frz_)u(c+cp5=U2~4;m5{i zrLU8#P(=f2`H9h{!?5hBz7}y}CBsFz>~8N34S^X6rTL?R&OUABC}P+?k@3I;XTpk+ zjHQhjS{eUTsisAS-69V!w(380T$ar#%f6B1{9K=U8q1V0!|&}9ZCG>~lXojtR$eug z$KWQ{K`zY=WJqU}={zVlc(Jv*1tXpt70eva@&{yGc_yN0Vl27Adr`EI_IUCyR~B{g z=KZUdZD%cQXF8Eh6O!5IdYf8Ko+8&XiS^}?3d!{A&!&AR9poAVLxrvlpjKsALJbb; z6gg>%Rf}U^pitq5S|TGfXT_z)Lcx71d$0ZNPCby(h6ue!T4~Casmi9}rV|qS ztN)9>Fs=;4xZWveF@qxx4m0eJC1_+zcyXogb0gO1I6M2u%CX8t_#D( zKP?}Fvo2L*F$frrQDsInemUs8q{crT@9`JSvsJk0;yf-eOj#!Py3a`MibTwCDXCvP zRH`PFsySMl2}S=;WB!u#RTr0VnPIZir{&FOScY9t5JgEzp`=qbLNOu#` nxrFWfAln|)$pNOhKGPho;X1)5Os^4}6mG=pP28g02A6^FGz1A3 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysConfigServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..bcd02d197647678efd0e6b40527419610b42fef1 GIT binary patch literal 4226 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 bqVX~Pw4;6`N%AOS11{~PXy++BNSyc&-+GEe literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysFileServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7fd6f7b67c99e3b3897a51b1aed8987325d2c402 GIT binary patch literal 6320 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 M&e12?!o*PXf5i-5)c^nh literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysLoginLogServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..bff675b8665f0c6ee4739799dadf6517613f99fa GIT binary patch literal 3809 zcmb_fTT>KA6#ja-EG!d1P!mNIMUk6MViJ?M24z7a$%27HqobTKZ|NQsnZvgXflSnYkS<;m5Hg{ZU zmbm0aVft0yv|Nu~gtu*5!n8|e$IMmztXs4tJ#yjsG94$;$uRhwZ*$Y(vS{ARKNnVz zL^s3rHaIUIZ2kMT-0-*`coi$C5XM5@B=R`AMee28<33H#rTcIW=aU#?xN-DIGjIVT45N`!nd&{SAiPXfr^=dL5{tsOlyfc` zxP%FYo}vgA9PX1PhDoEn%+ZJGAxh0j15=o0=;GzFQ)MW&A8M__C6reQY{%TFNGq@@ z>zAUJbPBV$n#2``ktS|2VB%v6vJx*-l1?_|*vh~C%50hHBPukK0)*j{h@Y+{xxlk! zG2Mzu{;+qB7Al_`xQ=TK7xrVW=Wp_IrKZwQ%*T;N3@1Y-wJ6Dm;Dr#9;X$NKK%rym z++5^=P=S;V`PBK)%0R!rZ=Odp;MWG`aD!pGzV7u6+3N?~3zYs0ry5#-s)~?>kgC(? z+eEzDC}|oMgoajJaiwY~zr9z6hc{sgOSqfFHw;VdmaFE~z`!!TrBDsrJ2J2XDm4D# zRcsfE&?4d$I25X@aMnNuEAM1~I7u|le(jbN?%_ca_ZyciMW#yD!=o3gC;)n#X#8O? zn{~!I&4wYBb1R-DmTc8@M-EOsYL>dHngNCR!wMOzB-U-;rk*@6r5kWnsi|d5W?ipn z`ejuZX$&ff7p}Ku`qWv48&u1}j7BrndNZyY(454}VGs6G_yIp9@gtS6y{==+ZFh?* z4KL*joCx`b?#ERFKjRrgA9d}wM-2bQD{XW$WPX>+f+PHkS=ZgFl%rA=FXFKxxbNZ` zfsT{6|1lKV{BFFzMw}P8qzAh3J;Ov?rCP}C*(W+01XuZ2Fd(p@b7oPG6issG z;GEhp2c`}gP6J)A1{DrtSxVvQ$wBx@Y%yHggTBv{`yG@-iQ#N>Qkr!`Z{j>nkR9~v zLIOi-q@)>TNDY*TuYxGagyuz{R*;g3;i;faFLC+y{(sP)e z$BDrS^y4J`0b}7ce29-|M+~$Wrr(sH1WwU=Z-S0#p&!F(jL`8JdQV_fOJC6_fsyH# zIJS$k)M{R0_~{PDAHTt6UIoQ7B!A%v{wcg zS2&b;XLfLB7vCMU!|J=Xp2aa-p>cUOW{2?_nsMZ?wr7VN$>_u*dM2=r$Fz3S$0xKt ZrJr)tFN7qIA~s>uNs3OM!-2%9{{a`gV8H+Y literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysMenuService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysMenuService.class new file mode 100644 index 0000000000000000000000000000000000000000..079baab868820970793660cab5d8336b4f11b71e GIT binary patch literal 6041 zcmb_g`Fk718Gc7T6w4c1DBvW8Bpe~NWH$;4P>7s>ZR%oICT?s@OX;ze*7nA$U9r1z zaPPaNr8iCQ`=AFsXu-s8OX=NGdf)ed(x>mtuB7!L1?A}v_Rh}Eyx;qs^NpVR@A?w} zhVh>`Vgff7?5yo9>y~3@OS-Ku7+G({%N87$1H)Z53r5x~m96abiZ^N4mFZwEj&_0M z8GTvLTDrZEJvDd6DEM)73LJd~h~pd41bRxuK5dj8&-5L4Mc{b835;7?n5`n!_vQpT zhfLe_PYRsqzj&DRtU&vyQ#2B2!%hud=n-h^PtSINs%wa2hd^)Mw2eC|r8&c$(dR5f zAeDCtx;3l2rhE@4+x{jb~RdZ zCv)An9Q)$9g4$oKM>X_ew?NFKrpe8U3dE%yhAm6rKz~EE$E?bIR6E~%MeC{^)Nm!P zVgLuupnnY8Z_yIc6V&If(EE5HWiEqfv7MN(7Et@>s(9&Umo&CRo zwWeqSSzHrN$*C494FWK~YyMnz}%rr{`#F_mrStia_Ahz9F&3EY6^#&M%Sx=HA6 zw2OwDaI=8s8UCm;ZE@HaxFXE3tz>fP*&SeDiX&3m2@NN43$v5kr+ua;)BLh%c24`Q zDYJW4rq!^95e%|QdHOQbxLwvzfq@p%Qy@_(7sCLM1fH+q_A387)fdG-Q8X-8oghqx zql7M8Y=$BkJL{OmuqNa+OvGsy* zs;R8jpb|KZnK-5yeGQ7Vu2~(run^tzdVi$aqUBXy6V0zqxm&NhY#%f4P8eWc9FxyIcS@}~XTLZ*~ zHV$9>pg^Nzv zNN_6`M+Mh-jXJhhDH*O(^vxRHg16FGWy4rvm$t1YwH;Bsjfy1jcDy5w`{|y#al<8} zK@D?UPs2O$05$cUprGxqp1)BW*On`S@7C}hyqA4mSPAP6-F{C){A`5N|(YDXCR zCpOutwP0l%W$C54qJEIA#??`yZLzzWNZ=ek9LI;M!L8`YwAAnse3aVp4puQv%?s@6 zpNOiUQa8an$Hz5TVDz_J>L{p+KPqr?OMth~1ElYk2mfa@d={T$v0O0xdJ~(fdZ)&g zRsS5mpy7*nh+Z`At?1U~9woR7=F&WZ1nE|J9;@@Ld!ZGcvy$h-8onlZc97?IQOK5DCNFTq zw(YPHQR$&9YTC=r65CT1NL;ATt2^6@hVS6JREbx;>Xg9KQ7?x(1Mu5*yJ#8S!Mx)v zRm#!2KOOXokvhF$;|xhhmp}85fym~2qfs0pkLs2+ZL-AncH(h?Ls6BgaT6gMP9^b# zOn@I~_y8X4jpNBA9#nIu@ly>y!_V1p&$~`(oSq17;m4xD)#=8UVs*Ha(oY1g+Zs5^ z>#9>TmwBMbW5&x)Rd3X}B%Vs*AxZGp8a|0n5$9I|hntr0jh6=IN)o@_)aqBwF`LBi zCHS8-d>LP%_J3>@oCtrRg~n~$a7QiO^9(PJe+XQ=B@nj@r#Sv4u)q0ImVzMma21)h z@vnn_Dft@-8&ZwqE+lv`ck^wG&lsPH%;V591COEi5x&K63IF$SFR%;kxRg6CBLaB$ zSF1UDDc`tHq0(3!cd%~q!FCI~xpfc6G3-@hZsAC7?9M!j-hnkdE5x6eM1=0C znP(41aT|3C%`>WmK5vWAiBM=N5IVM;}K6!Y-_(4L{$nr zeM1EQ0-nADr)u__QuvFZDt!a1cwuH8cLA$-$vSlTEXts2Q^A{J*aFA-KS%2g(L%=~ zV*6@p^nYXRsT`@d~a-CZr6B4);o&4eV68>tikEZSCyG(#91JD}3G}*k5Y$%8^aDY_m zOy#%thfKR-d;ymr8Iy&X(=xxOXaMQgL}sAtJU+OJkJV`e-pEDFQcVn*BA-xV>%!y= zg(VZRs)p#th%M2(=!{QiR`L0V`4SY50DM@12X^hkmt?Gx9xG=EFhY9Lh&_Xufx%UL zmHbxm^?C^kP(~sYduo>HQFt*Td`n6FHXh|u?s$yPRsLo8?R&)kK7NQFsnL(|3;a@z cp2lzRJ2m#aZOk5a7Vgk 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 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysUserService.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/core/service/impl/SysUserService.class new file mode 100644 index 0000000000000000000000000000000000000000..0c2cfa220f86e21440cd0812030a7c364a3e0e18 GIT binary patch literal 4504 zcmb_fX?Gjd8Gf$hSdKLDqJSZUx&cD4ESqV7hDDC4W0K-jAt7=Mp)4JbuH}hGGh$|B z3SSUZ^JUBZq*yMUfJ?5aG?^dWiTKx zddb)@blY%h`q`CB(hM>f6u9eiATDl46Buq1`@C$pz7@FMmcRq$J}_SUpx#32+${-= zGz{P0biL|H$8@XG6PPQzUQPEKp5@e5J)-Jb1dMb)hv zmeV3~X|9yR*Ktb*hiLs5C7Xtua8Mv+(bCb+8cJG6eo%?y&^ZD}llD{sMaLce@$_!* z?A{BL8V=)j#!aPRq-j23O{}Ou)@0}csq7Ir-8U0H`Xo$?jLTU(i1`e@C2&KC6%?*{H@DqO8BD;fa>@7s8#;`fOF&ER|6n%_lY5xkAn+LcHu+)wqy7 zt>GC}iel)f_zs(Ee4S;7rIjvO3AC63-77mK?+af&>h7{Q&yJ?5L4thPV>B8zJBa=d zHA8!?-lo*;fbNx;a?QZ9_0^_h1{NErQ}KZ0Tf?OcET%`Fw@$-4Y*KmEHi9!ogGD0t z<26us3d5ixta@{EuFdB-YJoU&un!(=%{rfAZilMI|K$AAt zjlf)!%*UCe65DE752rto0ZYzJouY8Q>8J{F@;OsBR0xK^$mc(P{U0B__0lJQeer)+ zUitW+fB)of|H@(m&#RW{xC+e=HT(!aCRL>8xlHkUk~%D{dG4lakam2S_pzp!>x^97 zN@Xi<(=+8MOEp{jx3{==DxC!m#0oE4zC{u9j^nZ}QE_@=vUhvPj!L@0RzvEQh_kBY zI^nv3A9zM1>b?9det}dJ8twNctK4N#OP_&-U_92CoZD^gqg{ zJaQ&(q2M%sdyqn2b?_`?dDXx3JH+)IH16!<>>|Huen+O>#qd<|9gIy)zk~h%=28mR z^KTvl@!$OfxDLZy9p}oS=o)Uojhqo66eGfs5|qLLj`yax%nyG|FdXEin>kM5YoYW9 zIZAP!oB9vNidQj_!rS4tl03*OAc~SU9vy2-%i&hs#(gDY5826&P`zdw|42{#JG${F zu7O{`R0qEh;ukU9#-9oC*Ev`E7mGAtfAKQzyo!5LxQqviS1@-O4;2Tl;Ni=7B)0E- zQhwyw+b~AOZ=~vna3rBiv2AM+7qHyXB|L(ySVGGb}w0ZEEG8v-E4~-M?GYU;*i6bDhG_iAM=t-#NOfe*bua}{yG(_t!&Gatd8dkptu z0wu;^7I))#!c%i?wdcY}r11i8Fq0>!$cr4N@Du!$U*+VV@%wZBG>(76L%+qVcnyEx OimE$*#GmmO9QZ#jLELTt literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/LoginRequest.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/LoginRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..dc66ac917a1496ff3ec365be0939df24b600a133 GIT binary patch literal 1057 zcmb7C%}!H66h3qNOSy$oXtkgs>Y`x6xYv-NiK~hPu>0xlqzv@V;LH@m(wG=GBrbda zm%36D4Wx-afX@Ner!b!B52ZgY%*{P#&bjBD?>pa}pMRP^0AL;NB)}uE8b~VDA*(A% zLnc{`Q*&f!)hep_^9DDTmQ+p1txk}DD1po#J7l!ZWQ{(p?D4=7NHz@Dl7*Z=w$%T; zZMBfK`veMG4QWNl%fg6Cov%x&EVDvMLtq&j_L;VfA`MY(r)hwntY$)5LpPLth-mvb zClPXEkR*Xz>)nT6Z%)qN9-o~a|9ImJbQPJNe|p_| z|8lTD{y<1!*9b(4%Vh%5N29wP!* z;40d|=C4rrJk&fjws`@rA%tsQL+_!FuiX6xg+6quoy{W8+4h8drwTgoj+)a2FDCZJ q2nLSRjj@~-hdJfPa#|YCX>pj-Jc2F!gOk($f|K9obPKHqxBmj-!r7$& literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/request/PasswordChangeRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..147b4ea8e2c8b0b6c01f6919699849af36d85db5 GIT binary patch literal 1105 zcmbVKOK%e~5FT${G}$~zn?O>aEpSMSgpUY;DwRr{LW zl^fzjkw8?D;0N$KO3SZ6jPoGPg9}=%?HT)f%-BDEcfSL`2HZ}7L*Sk#sZ`|=4PA87T@k?6A&ek+hYfe`k1C$jXmxe0x9J;hX4Zk z>gdFd359GuAW+)wNFxGX7g{uYz9FSD%m^hlfmH1FoD9^+xI^|zB+&R;`HS8ub1CWPrBzHx&*F|EA1XV8&^w7emF8)ID2zE zizWV0NMY6qL@KLw0?|#?(Zo@Nk!5LAGq=F~812VdFtEYT5!T zykGs#j$_4{7B^cL`@2xF4IAFUpu=-OpzJ~n;)u`_h(cu=V5`bK;ij$d>OvN9!$Wjx z)oP;#S=wb6+#&6SEdt3M)d@ZRSlIH*!=8@4n7h^}tRPDS-=BjYI>a%7Q3|t{@SoF= z!~h@-WFAH-$I4EhO;4XqBP&{mERH!OqBs+rV{2dG@+Vw4fW%1FOTq%K-NCv5MT`hs zfvY%>iry7ki)m${yh|pDo-A^!6sP{}}jI$^=h1@Nh8_Eb&&(Z~|#;6um?@rIM zupr<`pjM-CMxbV7|9V0gT#H^K&@`UV1dp>RZu03E8`3mgP{DQ0B+!8lbJP%2MH(Kl z%xV~~gh9C`Om$QjH!#~A#&O4)X(B5DfBMbp-iyuD>!sbTr9V%9?rtU1pOOUHkBc_J zA2E#Nh;z+>@8OU~`cNMG2m}gIGjDfN$&aa>XPK2BsrRe>T?0M4-(P0lZ4hWVSj^<& z{K0}e^VBpS=tcw|BlYEZdiilNqRixy3tqQouS;@W>FVt%By+MjN8ckdu|2mb##9e}0^D^HL62uMeEy zLb+Ki_XiKFWi{1zn3&NcW7NPI#BoJJnP)852pRB_4{GuO^L89uR9P=4B|Sc9kP;8( zw2TD26MDi3v)f!gNTba!qFd5K8+u#Q1d7DQ)r}oKgS!WB%1!V>1qyt_Pzfi7p-P&n z;UsDTpwvP^g-08mBFPWOtj%ldWK6$|S${ZY?S9N+ogz!k#jHTa#w=%(6`&FbdKFA= zyu%s6^)wQzxD(u+p-pI6$AbcAadlZnH?-o}mlfc%1n`T%IXI8&LFWx<|B9Ez&VF0x zix5PWbRNWA!QB<={08m&slAr9317b1icp_b<1q56Kj=W$G+tYO!VN zvS;cnWopA@fg_k?PYX;n7E`w^lUmBuZp+kb&!mp)_dbC zXuOt4g3%b_1Na;Y@gAZSQ!(-8ramEw-8~QH(I8_W2>VYg|?B7rXnStQo?h&Si~Z zqR`zdYFDc2LxzZ_xo&t2>7Lz9rA1Y^X4`dYVzWZNJ=+DRdGwJ~Qm-?F^2;TLk;hI& z#1TR=fiWZ)k_D;6^G1DFxZ8ZUCJcd7=Cu-crTK0xj_5r}`5zSiqhul+tqT35Szso= z+(X$ZacZlfw5*Gg^dzO-P|Bg2rK2e85*>KOUCnK}Ye|<$%XXQzw9BQ^p6y#xnrK~k z9<_lX`{&K^#qr7c`?KF??|yxId;aO;#fRe<7-kX(Bf@aKKjHS#L4VRwuY;V;4-%Wp zOg$5N&#AoRF0TtMTtbaep~Y6SvVE1d+hrIQ5{P1y)Rd#G&h;i~i%k||xz%d$M4zSK zV&k`*Kn(GwUt5~)_4Ad+EM9aPZdp8)rqj8B*STgMA8wIlh~9Y!mbojMS%%k-l!s!J z6!d&(9H%dvBBK~y`HCwizAQy!q`8QzG&fQbU;=513>jp}K1cI0`kJKQH4jq(w^K}i zCWVErTXKloENRBUGU)nHdvSvf8oG6g7RAWQ>K9CR@#6k!nxHbiX|AbiAsT#BJHs5E z4bvZ#0>e%Ja{7xt#e5KRatJ2FB5qTT0jBvN(+nk>y@bj1p~DpQnU-*emV!+AAk*AX erWLFXW6B4a7Kmx_5+?H|I!rO2=`M{H?)?K!=K|ya literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/AuthResponse.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/AuthResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..bad7cab6b08b662e5674007a923563a337c80c02 GIT binary patch literal 1283 zcmb7@ZEq4m5XWcXIG&C|DWz!DwpK0R!^QZ*7n&xGiHQk5#8%!fuz{;^XYP(Bek)BR zCcf|k_@Rvd**oE+*B6GcGqXGU-`~u@uirm@6441Ag+W19e4ap zkU0;O|7wJbiPN5^&kB6z%9%pibH{bUV?o(=r!UBO;f+*@vb14QiOPbiJ;zmV=CgtF z&*Wf=8}*(yl+(WS9ggEoBb+#apvS%cEDfMf+X=uJKe3~c6LFl;=@&`RwnaHI+1s%w zPX+d_SyUtwb-z~O#2dYnJ_-$$54^%yg=bOE8tu+yQDg+mjO`RIZcz~;AL8ED|51s% zTZG2ngsr5AK4*z?ED?>M9Op+->C~J1L-o?(UT-FU29J2kbbu1G_%UTE!?nZ9aOK*f zZrB1cFgvUkq9?EdHrM@5m9ILjinWAmghmIOblDAcreH@Y8dLrH@(R70aPNrQ)mqOQZQWVKixZV_KW zyL1C9!`QGL%7MC{NCkCZqlu|l4DqY%hXk@*rQ(T;L(;=XhvB}UNh!p zwjBO;FoO1IAL}|(bDe27mFa+Pr!h6xnfCD5{uN9-bfNnNChnD>!_+>t)|n1dneL?b aDKX=yPe)*CU%|vPTrx$oy9=@m-TMP#iOVzq literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/UserResponse.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/dto/response/UserResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..32564823d9dffc84ac165a313a7c20b827ce95d7 GIT binary patch literal 2583 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 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysDictHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysDictHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..aa481dae6f0f8ed459d594d564e556a4ce912d98 GIT binary patch literal 5646 zcmcIn30E7}75<(K$jD=x;+lje0qSB05cb%PP1121m(g0&dGm2&g zM|ItOOVf1U_kBsXq)iC8J^2AW{Y^dn-kZ^8BoIC|=ZJap=H2_gd++z|z3<=uz4JDJ z3H&RLn83-bqdV@JVY`l=HymTx)V-3YuNY3wHj8S!Q1Yg&tbZ|_ila@S>xQvr=(gc3 z>rZEHm|0)oV2*39lnUm8SzNQSroa>F#=5g^k(-38^w~&zjbuuoW888q|C~T-=w6i! zFAB6xxj8d|J=muq4ozUs(C}g>1P*9uM+ZTtEytV-@)@&u#mLwM-JN!`hP`MME%_cz zw)rcTCvdt6mgdf)DP5OLf5pws8$}~;`eu=O4lbMigl$WwO0zlBKQx>!nnu=li@I`8 zA;{R4x55a_*ujfb)4550%P|^3k?G}ED&Gfru1Iu#FsD>C=_i1kEA zOy(s0RxV1xx8-^GpoTOq(6`}vDBIo5dXXf5%4=nfsAieSBuZt;f8Q)i3CwLi<>YefIO&h9|6HUUI#fs?oaKW%Gr=^!!OTS4!;#tGzgxz%@J@$A<-uZ&PEo zx?aO`_y}vPXZi~)djX5y;YPe&OyD{`7RN^g9#9mJB~w=&!!%=mg>M=RWSHq3_a;*! zPj{1bJk8gT(_msrK;y{1SG@xm~Pbq#@r zwK5y7s?d-P-Rxc&UFLh6-D5So*jtq}>mX$T-i2?fxoy$4a_kOeXYzQ<$9Y--Ew_P^ zt)I|vTlN`=&<5FQ$SVFR4WE{Uxzll{T*o&ZU-lB8)$lo4;M#5ko|^cAhA-kvobXpn zM>P-I^cg#rqrJ9~&*Y3j_AAfsKApB$@_Dw;;$;nA#VZ0acU9o2+Gtg(bF1oDd?MJV zBom^V#fFm&K=s>c$uQ;vGOWCuEmvZ}4T@QF#*&wtL-kj=6Ef8Dp4JFRqg2f;eHp8w zYx8nQTI@ztW$Q987+wi3R36@Ay}`8Wt_FqF)>>XOQzt0zYPHK-{}^t$ zy=+t|)SWugJZ0GSg5{g3gB|#xz_D7BDkQ4cUIW+#fW2 zP0jtjI`zreGnspqrIAt52XL@nGC2+L5Yn>PBeH+K7K;QOD zc|QyTL1x$Y+ITmu*uyIc8!mZU=V%|taqMNm>*U)EpD{iYBX9ASd=vX$=UWU1`Tu~D z>_!_7aqTFo#&cnlp;L^hs?cq3v2k;=D2RPfy-@BfJ@bHk@ z`V8L%za>WA!2V4Azg$zky`;)pdL*xq;``k&T?WEWzGTV5=VNQB+7WkfYd-eP@i*;Dp5SVhue@72qGg3wRwpuSV|ejXZiQ zh7EjD(Q*TyS;yzAehtrLijg0u?o^FGdn+J&x3ID+A@dj^$YAPx%5&E~vVpHuHHSy8 zPiYK~T)Q$66lTI}Mfhl)@YfksDa_2+itvd#;crI5Orfm^k8Ks^5&kx*claY-Rii)QulSo9y@r3_4ZO+qQqMZWbBFmX KMV9=tqw{|ZPYgr= literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysFileHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysFileHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..5ba3e0b08a53dccacbddcaa9ee527c57b49dceee GIT binary patch literal 7703 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 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMenuHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMenuHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..8b370fff63239b18b488b8729e5eae6d47b6ccb2 GIT binary patch literal 5048 zcmcInYj+dJ8Gc3>3yC#2c9Y^<+yo3rHen&*l46s@cI@Cp24Wefxo0Jf?ZvBIu@@6J zrESurY3}#?wKP8<;j|R3KmYIYPXLDT zeG&B~PC>?2;wjaGYQACZ!!5i>8uj6X-l`EE>9H*mL@c z!f9Fb1vZztCNJGZvnT})LtsoBsU*hcnlsAUh+_HtLjQ z8XK@#LlT<6hD>%Q1%WLZHlkf%YtFRg@t|Cg?zB;`2(~Nd6b);}a831Ioow^xO;6yS zRdB3M5Vz4eDgAk;bkcB*vh<}(J)7sGKWtfwNWT3plg+u(DEf}8hm=%;f@OO1WPIET zUZ9Fp-kh@yKX8dJ*LwBPDiA}(C8undwq9j=@P4Z9nF?&*EXx_wGr8Yk+je}zHyxY6 z4&)qnPWLLVY0u3n^k*G+K|d=Cdcm|yx)HC{AC~^4QK@j<;AY&0JCeAaY^~qx8hUZF zKysG)Nl?U;qG{Td-1|m`W}u$B&v#{MhlW1v6zC`frd6t~9Llt$^jd@~2PtJEOA{pl zJ(H`2c+TM_SCyZ1Y=^AAwmylWrbN&Cenp>>UWLw(WAu{0v_9`D|8CS@G)w0Mwm14Y zj>ZOuA8LxDnZr*S{`{3330;1-hP~J=ut~X2(bmPfvQNW)+(QtI4QnZi^pMHGH!XcO zu!}0v^zrIoFpUE^l*B=S+g3>k#jl3LxR0q^HYx&ibSsUm9hJrr3?)IDb~lUkCJxYW z6s$;_m?h&*U^6(5Fdx?_+;>bGB^H1Y6|2%EZx3Q5iD7|5*QY_lC>|ocVektKtQ|^7 z^|*$Iag4>VBxjAl@+W4;$`zk}+Fu{OQBA*Q$R|va(Rp>E2&9X2r7u-B2|UuWl3!Jx zTKi7m{Qpha4a~oTO@pIpN;zI!Ltn7^HfzN9=g&f^hk`@mbQKnfd7q8Y4RZU$7UA0y?yyh@} zC<0k`T96tH>{hjSPQ$z^uPNIZb!=bSzUm04H7uwy)pk1Y!ilm58xAM@d1;3&phdU1 zX5rdo8RbIB=-V$av%ZS5#-cr#f`=dpo{M*^Dsqg?KF^a^;AvRIS)PGLr^be-$5`HX zHsv;KPBkeO^dnf(@JGDJld~6U5_mqd7Fl&jCQYkiYdnMWsY+98VdwCdB>pUL?{$c4 z_$ywb9}CndaI`*T6$2~0OCrmm_n57wO{j^lg2YgD4UftSV`cq@rFc}}aPmuW9L3sTR8 z;mL)@Y> z$Yg8TY#orQ*-^u?@}@5bx3=STfnD`misPZiPj#vj@2S}TP{T(mm=ewc#Xso8necHh!nf8amp_>pf3Y~}BkQ1T|UQ8tBcbaL*N zXf~;|IVi%JZ@EKKT1tXN4L@*TUf^S#0oRF*O}>#&FsQ% zZX*Jp3Bfm-$)ca?lWGqG94MR5(xxJ@SJ@j_#-0Q&LkBM6-b?uXG9C~dj@5SAMM^=u zX>2ErJ8%cbHFA4na(gj>M`))??gWK|I&#JMCS!7s^IMGT1YZ=c6IEOx7sPc^;hG9@ z)xbnv&JawNU@~<;u5dy!k;ilmNInE|3NtZ~$77=Yz-5s?BBDB!I}}lZa3WX*!csB0 zZO_0(JfS$-vyA6zoYk;JMD3*+oe{Z@fuV=^?u_JPqPA6uqRtR$BBU&p;50a)jI;5_ zXbUmg;#FuH+;wc_?y5h;jX$kdX?{gk9YPO{=s*Z txbKp-_wg}42}hse3w(*M`0ZBCe~oYPPiE6OR=D%+DP9jUjbL5j(Gq8 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMessageHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysMessageHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..63ed3b33351f29122b854dd5ea79cc68d4db4d75 GIT binary patch literal 4343 zcmb_fX;&0S6umVpBSV8D2_|UbN{~fuTyP1f0U}B=D1wj}W0IbkW~QO1d+Y_B7_+bc z#+;KF^+SF@PJUBPZgux8$N&S$hncRbe)a0U`)<9e{_CF?e*zfCFLA^K&SWgrvR5_J zw$y@VX*peWORk#NtgNX!L3_UB&giboSJ%VQIGP2L%i5}@nwphUZ>E>^j3>}p2+iho zXVu8)0;8$=-ZQqtWkM@;n*JBqiPnfFj|#Mo8J6K)7P#F1AN&j~3N%mJSv`R!v@3{1 z5oqckSZo6kD`-Kh!0wb`={NjBT6b=1X_L^qQg%i&7d6L_{b;b+%Nwr1$OdpWC5-_k zXLK)bXJ<7>E9jo?(A6tB-HQTuCrXlr>8ya-pQ^H(vaQ_cK+4gzjAuJ)z+KT#n}(Zb zf~HLWAzio48#zn!e2368+nYVMK{UZaS-YSambx}YqnEj2&zx_0MnPXRT!RdaTbAu< zo?%;z>TJq(a;jT&3@f)JgMDB-E9wJ1t)>ktt7;Wn^%}$1ibdMdWea8KGk{LjClTr+ z`9Ga~EO2D)S``Ah6EVhRDnfI5o z$qlIuPlr1T9KD!uqXxfj>0o+gtgt( zR`o8PXp;)w#Z^`j))TWNaIk+Ml#uTkrn=-?8Cjjwsi;Aq*DxK&b%FgG)K-~t1@GZ~ z9vB6!C@>bG*}&sg+KCs!^HJdR_G_*{qM$h|6&vtnRSR-^IN+KIWBY2h$aNf={WfwDcx0)HsMhXPSaEG8F5w@3PpRs!d*ad)m0T z1%*e7RadZt9G!T1-3r9GiEg*>M=}k@vCGs7>8#c}EO2i}g{?sWN8^JD%VZ^S19~^eIE$*Y>WvrJj^R7PwGXE%mA&%dIzQTb^T^y!uk~+nE{^!0J_| zL)D6g8tr%9h>{bw?YW+#6~jBAo4_g_#_@oco9c!$tW|qOS5rY!Xs9g(cfOK>5@)O680tYrX<;O@!CX-N8RB)Iunt1l`dqI9kuoY)Jj$MeMjlC&8V|*qC|KM-v zcXa&9UJSeW-x6%+mJDj%T7h)4l9pM%33YL+3azY*g)+1V)LabDaQitv5`2F4 z6xk}YP_D-*$rJQ_d;?hdTD9bXWJ2yyLXbqLd`hXc3_in3)pMx7V}VB{G=RnMKr(Fp w$50HS>0;|X`wnfwh+KH=%Q=sj-pBYF-{4!0NXzf=1AgMJxXY90=hn7=0YN*vR{#J2 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysNoticeHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..8c565749beed3abca15b6486d9e3d4401992f2c4 GIT binary patch literal 5380 zcmcIn`F9&v75<)LTd_P&j7t(s8^#dzEZra3dOYFprL0O0sQD`Y0Nn?BB(TqBa zQxU?xw5%=AvhPs#rBIC1ANT_}{7oFb_hvMbqNQ>U$vMir_x$dC-~I0L?)&$D-~JbX zQ+O+ll)%w~qdV@VVY`lAG8|*g)cuODuNzL$Ha#_7srcvJz$%z$qs26O1ct5}n}%*1 z&YFH9f7L7m0)vj)wPJdk+$?ZB+gf+Q^>|3MOJ7d3$8vK5ee;%M1y2Z^n7BO^lR1H& zMYm{XunPkk($EBUO-$zcA+Se7FZu-bW-Z4&AC~f_ciG6>1U#H|3x=IDJWI~w#hzf@ z@&#twAn8ODO&L082J3F|qTv}OGcY}B8eB7jQ??yZ%K4#*$*gA@g~0W6MNK)(+m^ph z_LuDNMJnlEvDO?T2t8sv-+A|Z8<#ga2*|VIrRcXOB*W1vqnRz{LIYr$__UccW!8xN`=DxWB+>L{2+(XW8$Nw5e zu}>hq$`eRa#8*VtLS?xqpig9Lv6ppuVq5;sxsFQ{U*4I-e72R<>p@V~FPVOs%$R3L zSy0(2*^=&Frdmip_UhNI;thfO8tG30rNIx!TOw-Zhl@tAUJYR7i3c@IU`$}Qh5S2dZcA)v@9sD zpHy~%?&U6-FNCHaEV#wW+-_VJ5Qj6!;psF!%!KH0G2BYJhL7N*yaRnRsJeJxtBA{G z@GPE7<6{B`l;h>4rmGwMG(CQqGYucd^DIz~dySQhN!ex}lQ4(8h60#68V_DnK~p@% zCg+~`>}KtAlQ|ids~XmDf&GVXY?{ODH>TLouq>&T=%F25&pbRV7wf|H*?Pm()wd&k z?-agUcToKu4d>bJ!#PZ%Svt9_;RSfC)O51!E$(V!V3Ki_L!cq72E!HQ5(dLCQqs9v z(X`pxRZEK9tfF0eCojz%@KP&hIoB$(d6WIbqg|VRTEVRE(ynXxr0fkckp;3lkT>tA zG<;fKru~k)=sJPv1oHm>tcK6YOR48-=&OY6P>sA^BFIUQD{r2wv7#-PJHogtii#FE0XxR3O6_|5-`|!HJ z1N9~)(Ng0lUK+xWGc5Z*)9_`yM9H5H;iY)(*BZXA)_zr6`@M#5swNnZAfD`Yg|8P zOZ=wf>eN5^oBjs|-{dTXz5IWVk{m`4?&98eV~A_}quqEH^~rx3rIiJi<6dS9KZ0BL zQFK4YDICCi`0eBB2*2{kS&jw2nW?uhcoXjx_$z18k#Zj>A&=6cUGY(T%wUZABdzx; zt$Vm*gunZqf$;G@j8iHtmEX^SJnA{BmDY{Qqo!}-ffU}xB(Q~twsGtxP6!U4tQ{|H z1rE}xQQCKiql0x;k0w@+ViBi#PHgoeg#^x!%qqU8THrg|jPJ=9-$0CSIn~6)cpZR& z1i%2YI9CIZRRGT8LIU7oLi>mKw}hBWoJeAd@xf!$!z)|3GQEvwwqV34Ov%!^VyQ;W ze&yRqdU6Vbd}SWM3<;X9LpPS78-sCI<7JtAW@h9$*(tl>Y P{Eao>BwhUXzW)CKx1Y-N literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysRoleHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/sys/SysRoleHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..7b7802faa9d2d11ddb11e9d3fb2dc091708293bb GIT binary patch literal 4834 zcmcInX?GMw6umVhX=dm^OcV)XM2VUOZNLa>;zB|q(FtIJaY2!unM%^6r+ernIPUwt z@B0UTfpQdyAN&Cxf0M^s-9yg|%!Gs^IVaOq)%9N8ci&e1_rHJs1z$@BU{j&lsV{Soaunrq^XwU`L z_4UuDA+S+LE7}A$Wi3Y@3X3`E9W`?{!FFcdylKyxo~7oM#g<^f@&)!Z!O@%`n$a;O zg9W#6#PrOf45UXr8|G!O-?kNzoZZmZpY^1f4_wcPC@F48mI&=c7C}%C-qP_ba#|_NDavcI2%DUdX;g>wi znV(bWPrKftaa!h#oaGb@GudlAD1#}pRN}tj4Y&^1YuHA%*6wv3J-9|do1=ab6f>o0 z8ZA#21dP6HHP*5&PixBDlVPM(DTy3%ZU^s)@u}gy?a9xuKRXpq1jXlh*qFE9csW9F|~6Ly4$!3W>{}tc``J2(CfbrCfOCiYdQ>E?s?}Iua%x&EP0zH9RWN zze1m?&j1~d;c=$7F9X$%x-KHCe^#}>Cv_ag1l?AUHamWtY4*jNn{|CvQ`bOOwI$BF zR)JkzwVQpb4)X&M$lCV(jE-a2u4=KVBd5x1+HuERCy-8{IzmB*RAs8=Wavi=^Ewt_ zaUoccPSgTc=oXhOTC z;aPz@E<;?$b9kP9%u%Djy|p2mbe&bIWef_BIWXgfUS3XEs_J#se?8o;B3Iz9hK4q( z$h139amX6V?-8D`7SX6EpAT~aGt81@sA|lcZpWzW27cg~rTDV$XYdBz((oqlY1QcQGst*L3KaKwY(K zSLy_hmP_*TUdBhREZbiLq;l+-Y1=baAcr@#;dOyqYE4Swp~_EXsRQq+*#A(+M=F?7 z?jprM=)hw1Lf~^9C!y9pA8Wla(z=m5y7_<8F$fq6&6b@B^ zOhrHr<46MJk%XveZmT7#J;en@l)!mdIl@xGvSsJsS zz?OE2;_g_k0$Iyrio^H&nfUd3yitBiV=w7rjy@kuoL6kp&=e8qQLx&Af2 W#rF*J(@dNn+S2@z8^Vum>Hh#ohF|Oe literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/user/SysUserHandler.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/handler/user/SysUserHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..acad8a1d9adc88ef6f02c31184e147d8bff35af9 GIT binary patch literal 6851 zcmcgw340UA8Gc6?3yZ}F8`By$4iG2UVAucw90U|FcI?D}YlC~FN7mBXUcBB_v?~*r z(lou&v`y3dKGO6`?<7qeOw%;I(l$-+yFaE+-`QQQR<}H}8Dk`yDec z{rB4Q08ZjRal{1nr7hL6XEoEd)EUjvCUw=BbJQu#%9wgi%{%-WopUbmIpFujQ74eR zsLg7ssaccix$%p7+7(zY$Byc`StG3r+%{BRaN5ps1%H$}7)TCgr3C7a8kXT67dYIx z8UbBn0(HH1Mo(Z3)+>lZ5m?jNHP!%uMg?n8FR*dQu=KO}nQ=XLUK=+FwrR*tYv!1i zGvs^FS?5j}j=+HmII3uf`$(SA-6=aWtmU*B-PLmxw0=@|r5aDo4Q2$?&Y_|Thiq#y z)ispUwX|#JR8L3Q{J3d2Q&j&M+p;OLVbqwkG&i3k;0ISW`{rpUN91pVaqlI26Z0fkUg4px`iisNQiYP+)iMP&`#1 zQINt>#)6DKq2*0?aH4M}>(Wm9q8{akv}HXqW)MMgu^$U;3O!x=yG4InB!ASEp17?1 zhoYEjnR6Zee6yDdv74+c*HR^joamVWl!(@Cd#=2l10*N#U@9J`b zz@1gY{i4WIo#6tH{ojOLM};0N>q6y%?JF8#-gH6nY z9n6x_I`p3v1bmt-pUs3O%S74fWv~jeGOn%Wd@QQ8_61K!fNohQcl&&xol~Lk;v#K%PT*Im`j*aHBhX;=*8$YX43+G<#V`Z z2R`kAEEG60Xl4}LgBF>KClpM|^x9zAy|(4*mMe8>D7YxoRNckA<8_z{W?-?yoznSW z2~ee4Sk|W+)8xmbKCC$oD?ui)sU@nb!C-~yy`HdI{rQDgXsH#Lx4a8gu6Y~1!c@%$ z>Px`IY#ezWTFOg`2EejPQ*a6QF@>^jIA`+EP%z8pLhp3yqU_OX>^=o(AKR0H0F_r>vE zftxB$8Q`gBlt+}jqu~8`kWs34r0?YUzS9CXm-T3`BreWk8Mzk^Dfl2h#N(>tNfNlH zvzEE?WJ>3(h^_Q6)*&-@v2cDEkHqm29!OU)UBO53F-DJZN)$L2rAAom)+m-F5Tts+ zm=%HFU9di zfv)n>$^caGWqgG)oIr*^OH{>$(tS)K{i=e;@HGZ}F6i@6jt&lqo}Ujg4NUT^B$0eW z!8h?Oj;83s=q*v%g~45(@NX;l4!-LPAF)kc-ZV6o2=@v#Df#;fet;kPk_$tdqmung zi7^>do>VY`L2gjL&v0BGT?94|O?sL+Ex0X7jN18JTJJaHeM)objnQ5icm#UN62Dx< zOFwXBHq6;3FQLe|l}z=D-a@iv&8liy!#lk2Mk0C2wq3`~X<7e%#!2AE_(>ek@s^<& z9Sv*Np4QbNFI;h;HsRgN%qe&tKjlRZZ*&S>0xw5(7R>a84|w-wPREdKPv^6#rNK7R zQ!-JOInm*@|L8ASeQuO$f#hDzG)E0rPi?HnHGx~ATMFYtQ9nUf5*q7ZXJXg0 z{Oo=P8=mA_3>*2~=*?_K9X4}p3zF>H;*Z8A%9DQyPb$5F?X|qR;6reD3tL;*j^R~! zHJ^>_ZRKa{-4G7i@EZ2T8EkO_8xqG`IaK0k-}N*$>|Q{74A*cIFpr&Av1b7c#q+rR z36AiwH4zmkGJ&l`(ndM05q#|-zIGhLajp~KJH|-@uf>TF-^nugPA!kGw-&HpCaHw{wBsnghL^k+{xzdMhf+H{?!& z=_Ht)5g^T>qM9*`*A;;bdq74oO3wI(JRd6R0*6HnxhcjDX~-DH_+5ZDOZrIabrwy! ztNR*WFTuU3s&Th?JlaFNd E+;xhm_jtIs`7%S?oq>V54&LI?=xtn+B;O+7!I744 zh;bD7yR<$JC!uz=a8u)pHdVsT3xSqfgRP`vxC-54DH-IQ+~l;2m|L8!d)7Kq?H5r4(s@lQsrhe`5()i?0& KcrX54-|#;l0Kgsq literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/OperationLogConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..2e26150045795c17fdb0d8eceb664d624e7a91f7 GIT binary patch literal 2390 zcmb_dZBrXn6n-u*q0rklg#}w$X`wAmAZ2T{wVH||0i-5?1){BrF3BY+hB&tHB6FoB;s&>}EXa7@SD zw#u$!RxHOVDYLp$HEn0jv#P#VEBG}}nZ;GJ;5ysN^Oa}LZz<36ZP&@VrOC+Kfi{8o zhP7>(Wy>j<^Q#-G;0wfV*^cdx3$!MZd4aY`x2U?%icX1k!~{-cZAZ=3Dyzy{vR2DV zpgZdpta9G+Z2qo0+x&IADlnVOvfyT`Xbt_LA~vizI#`ncX|Y ztm~B0ykx(`8Js0rHKg?<{>e(_xvBw)b2u+>l+rC%mFHL$I#FX^(na61>uHB1F5n{3 zDeWG;w=sF09i|_axXkG#rQf}UTwhXRgcC_h)G%QnC2@r#Iw>Nj{B^g;bW`Fg(>sYC zc@12XcrxNHSe{j>GWWW~jffk04cwG?CgR>v)mqtSZd&42#ErZL#wDI-ZlLiN^Cl!- zWL_XAc?@JEruZCKxJ)g4Ud)`4c!`B)h4%agZcDrzt-t77el4gqCovbTA9)QdNW8*a z&OPOMu9vHpIQOE&60OJX%j*f3$BD50W=j4G?3K#nL$tVa>M z6V!vk+b=NLz<)h6khJzk1EM#oav%voFYz7`L!UvRN#A0G8M>Pulq z`Io-bbcJS3=uvja_mO%`9DQu{vo*lh5L?4+CD}@`WwLdRt?O*vWGlE0<7`c^FT>Uh zTesQDv9-X~B3nV*xX0EC`z*HTjT$HkbS=6yub`%F{#)qZebiebL!Nx|g?+t9COna^b>xvkKk#d6OSr->u&2%wHmv;hP zJdG;X?`zZ;w>92nysxpt_@2i5j2~!x$oP@Q$Bdt7e9HKl#^;P*Xne`|mB!bM-)MZx z_?^c02Xq-AUCxm%gQUn1?fL@ga*=eoM7j)?v(od5s; literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysConfigConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..9f149deacb47a356a1d226f74a67a29c53b8aceb GIT binary patch literal 2069 zcmb_cZBr9h6n-u*iG&MA2-t#BMU9Cd+uCYvV^fhx6$97?)7tl&U1qakCjZKQ zxz4mR{o0v+=|Af9oZU?#CF$^?GduS=ckg+7&b{aS`S-8C16YR>$B00o>R66@tQxLk zHI<|4+G=%LmhJ3&s^xp_s^9jsRjXK4*E!anuRW{OX>GX9zFns^{1wNTK=M!>E32WL zy0u$5)Ky;~_P};*KQAzv$(9AiHr$#{U=$M)7MLlzRn;gf z&*pvfbId=mTLPQK|0CC&z&YP7xJ_j{0&eEaPPOCPey7j=aj?&2hd8LZT(=-h-zFEw z1%Z{pJO)}MkiV(^p@7a;#Wr=IJP6p)oZG*YD14Q~^ zh_u8_4k3FXp6L$fn3cH2u4Ku=YOz~g-)?Fv=$8Wd+M``?dru^uVk@dl-|SLU;{jG-sf!ZZ z-Ed(V6pqWbEAhPRuy;Vs9X>IEheJBxtdEj9G8Q(9!0jQv2KELSPL+IBeYLHQqEV6D z*8YK8d#*fsi8QQeY*4p{t@aZW3zVB<5LKU}=e^WtP$`Wm#Hf$ztga zOLtki&r)!od6w4sUxB43EEQSW6-boawpZ1gHqXwBrw8*IcQ>wrCNRx>&`Mp67_D*I zS%iXc{MH+s`-OxNBxvPhUMFdlp#tF)?WlEdp0wEbFG6!@g=?rcx<7BJ>u{ph$CWT zLX{A7&OE;+%^^Hf#Pemq^IL=OIN$FLeqj93;3vkP4HRR=pvqV?(2V;Ab;bh&oAJ=# z)hV6}#B-5&UJe+}(}Z0j7HPV~H7pa)YsB+9@w`Di)0FhhAv~EK-`7^a_%zQ_z_UT? H2%7%@%XYI`X{7}VEl`r)Run-gU};LEnzl&V3Zm7MWSeeDcI)n@5^s3F z-+l^yIn3ycU!Czssqed+O@nP5obk(fo;~NiK4KT^3?kdlBD|x@-nnodKT6Kw*qO|`9z zlCq1&Qf|}C`vM)8EZg$02(%`Ws{(B)r(kxY6=!GcqsvX2}PU2bihd=8V=&fNGz~N z7s;CSm0t-eT9UZI=3OLSv>V4wiEO=o*HpeaTjk&@607z4>-%xslDHk&uWS|S_ID&+ zkL-8$<5-h;6K{oAoC@L;uF^|%G`eEnDw{?y9%%NM%k&hyN;!!<=ndwZZg4wRyXif= z!V6!QC`ReRGAJGQV@YgA0qX}e%fc^7V7AG}{`lV>4WN#2DhL=&qBR)<qX&ffrg*JNXph^!?t^KqPQLUpS z*A$(fM-PpmUZhF6MfA}p-H$c;N37!rYz$xq;9837o&+TtOmain}I^RbtwnB{6K39e*7DGonRRN literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysDictTypeConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..387da0fbc1d7ca2fcbed9bdac8a7b384170b2763 GIT binary patch literal 2067 zcmb_cZEq7t5Pmiov=W`_g zEBa-TTB%dc*wxJ|C2Ql-;AvvbeR&NI8Sf4uqSHvo%p(-;z1v0cmc4phr? zt+sMiQ(K*0$8y}4zUl;i*ABYAwijVn|!^P6Jz{s-K&{+&4BQc7Uz?rJ!>Wyx@uKg`lZ)t(Cs%NX# zw(=dG_njlbj?)oXt^PmRmIY1(Ud3xG#}()l-#M&y11IPWR^VaiDVGvL*dA9e+-PuB zIgPUdH;-47uqKNfGFjv?nZ|^`gX0$;J-DQtCEmmP0;5eGJZezgi>2z}`Bgo)S>_$5 zB&KnmXq|{QUi>Gkw9QG)NPK{c0w*aP-;NE{ro+ttEod$9oqpI^iOaY`bP9V&pBN0@ zXGh@+64wU9^X238N)p!x<3#>E<|J-1KSSx%0u^*S%(f&xWOjyjjlFr?lK430KGSXG z?=knb#GRNMd-J#}@mZY5vaeO3mwL=DOWcd|IP~YSAaOtDKi_Y>hh?0mnT$E=FVT9sIjw~NxC z?O4yI#FIGS+aJ`<(Pa`?O1SUue*LHiQ&D3GSP9V*I)Rp+qT{po*42Lhfyk}vV8?4b zQ9j)}dZg&Fpbn3k^ItkVX@jJ8{txoFDX3j@m}F~;tr@mv*($JAVrz~qi>+I1-Dc}9 zTj9Abu(im(3R|meRoU7U$kx2BZ|fC@U(IvJJ<9Xk&$tA7ed)yqjnv0T(U_*0MJNbI zufN8LpUD_PmPY=~<4GE2L?ApxGlA1MLo8nWCm{#@`o`}V6|a6p?!{}2ti>G)N>R3Y!TcqK6xQ|HD5~_rt z|E%*XVkYR!lg<~R&TkC9<$S+0_@40xgC7}xGEj_l1Dmm7pc!8pG#Pgc9L8OPy(2oO zNar-^ybvm!q&IbjR21kC=P^q=HjF-Pn>dUr-e z{Zi>a8>x}{Z>4^PewQdSXPY>HtwyS3?VG)wH#=`T|gQLK7+$X*jgnq*g8@@6tWz+WDL*<9cH;YHX+HbZx2p!MOd)3wULIMK< zseS9vGHaGwH6NDul^qJi?>Vj$E(`RhGdltUt6oJV(T^dC7~%pWdB;_oje1%6C97Oh z0%Lj4wrV?;@9@0!aUk4t0)c$~|I0WlFc^9{uWmW6!0+k*99p@d6CRyBiM8l!Hq#}H z?eR%Qo1J846Bre^akjD^yd+W>O2WWo0uutcvjdziX0QAu-od*9v8oCmRHzo|O#XFE z^PXGH@~#&orZ7!zLDOwKebOtl!->sET*9otISThEP`+!`sldh?L5rd9w8G9yT*mw4 zPGMiWPjm)vc{jr^NL=OcgA~5xgf+TYDP$zBagad@()ws%QQ`ykOp)jD_1&awm|;qM z$cz**PAnR@DRGOL!^AA8aL=o>X}2XlX4){(I#&$bk@%E3BgdRA%eU$QZTJ}?B-k11_nWLTZTB`;&B)(>D zRPh7$FGy^%e^gxhVqi<+8*DevVAWSvs7ekOa;ja(kfvtzY;&!}=$e!y9)TV`pHL@n zx>eCLXxt;>%?m29-sLU5-IbZ7_IPDPAC69|U>&rYQL0()sBns!A~h!J zB+UlUqm%U7q+8o~OQ~EfY6&S!vUP#28MfxxT3{=~)*@RbTQ}Ld&DI^ZqOvWswZh+W zY~5#TgRKHvTWpmCl0~oK+iKn6o_(>~-@+1i56pr3KmG53M!Hyt)0m){NhkJ0Yq>-0-JV&E!IuH)iOyE35$cxGU5^~VT*Z)RLJbQuE?sJS47O!iJYrMyJQDctr zibk4|eoKruG(KYdMB^^wXBuBHu4=3^KG4WBKGY~KKBGPQqrC3Y?!XWRXcni8&Qng4 zG|o^?3v@I~7^RjlhGmRnola>J6WAe-pQ)*`mf2>$EiIHezQuQurfuxvd(!hmw3mqE zM>1l9)>-pU6rqb|gEapVX@0C>an5B8o3Wyy7@ufV8TT|C#(j;aj5UoqqpRUD9%%f^ z=xYS0G*6M{Y0^AHYA=zZS+eFx^E_$3%x#b~Um?v4r1>goPE*F2E}B^>*Ks>ie_Hcy Kq&cLq4~f|=o84>uH}0Bs^+;? zUAbyUTa9MJa@;4rY8ZddHhaFdsuj!j+zJHCe>$@*FtFxTbprhuk{Cox;B?V(^~PSkqWvvZscC_cqGzkxw(=dG zw-yJ?uG0`G6#svwS%DMAD|mI~xB}18#}27oIZP6* z5z$7|hgq3zPH0Nv0;UB{QaG-H4OORyOMMo!Y<#B`c2;5z7l}?`59ni^!CUMo{Jg|h zo#8i?+2!;y5|=yUMC&OmN_^ePFFP-&#*(lkzUkyg>nSWtT zu1oyD{9%$?Hl9!Y(RRs7tgy>4N&9Rog`C9A_9<(=Rz~NWoYksCzJ1EUdI|-JTUZy6 zbV{^dU8M#(*S=Nb)U_4%MuB2&(JXwkI}&&CGr3U)9d47Y+wJ1TeHe?1L?G9revemH z)Jw6b$ORU9MCwx6Mxvp0^r2S<+_Lt8OZvYKcBD)a=xyQIq{gmv#%@t0j*q zi3^ydt9y2^x8u$CEV5h(LIXW>kRUnR_nKkPx6M|=YX%;#fJ|rjkCsEcw1q#ZHEtAtb3_k-9Nvo=e8@d z4|<<}|J+6yy?xj^|3Gsqt>I*S_Dt4UP9DK2OR^ zzV{PZOZZKVTN0ipwbyO~w>3UW7;FR*SkbtXFc6P{1&vQ7CdZ8R&l+vx9)0CrR&XJVNme+?6ge(`YV_z*;4L1m!4p`n$K$1^T9Jv zsM+DR*Lr06yj^^X_$088`z`n{eVn#ITGRdqd2;G($^s_Eni6Y9tXZ*&VwJ_36U!9q zhFCYnx-C|GN(*8wif=`%`(mw$wa!~u_j-QQUUlScJag33J1<>}3*Z~ecO4wr6v%MQ za%K`0arEj-9Q&EZ5b_-5w~WU*>V5$61ZN5-af(s0_z$8a{p#8)jH(yEqVVJ;#%god zB8*2kBX};t1;NV^N`n061>cMCf#8P`J{J5W!d=1T2&;k*Bh=icq_3pt6m@c5Yq8?PI_t5{4#y#M F{{o|H^W*>k literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysMenuConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..a2a312394eb9177c442ecc5bb86788358e9a6c15 GIT binary patch literal 2238 zcmbtVe^VP(6g>|}Lg;IoLV~rW6lhBmK(=aawNPvuK%)tuNmGlqx+Je*A=!a@fvt0k$s9>lRO@exNvDI)KgUeiyWk@$q=QIdC7 z34!5+QGwbcX6w4`Z*D2H2NLPURBK0V0E^B^o_>bn&D|x?8a!gBn zFR5F^FwX28vq@$%%x0OTm@P27#_T$?o6K%8yUpwlvoy1HW*KH#W?Re(%pNe?X7)&6 zB=0ocl3KU8aVK8?Pgvv@gK1Fnr#~CeNUa578Y46_2nAti?m32kBQk&y8u>AgCuo#` zfbb;E1Ww^JsW|vALQc9n{{kWL><`2qKF4ToVP0cQ<4wj38qI;9OHP$b1;>cCHM*7r3P)ZX?*F7P$J@%?SX#145Y`TL15%0xnfp0j^N z8T$B-lmCkEe^{Ypn&0oXe-cOi No4)^FXdJ-Pe*g@JB(MMg literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysNoticeConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..79a7431f0abe834b58841ebf8bbaf6e104e17ab7 GIT binary patch literal 2069 zcmb_cU2hXd6g`s<8#@y)i4)oc0t7HN3E7qwN^9y8Vp2$*gw`P~{a&vJXM?>Pt;do4 zui#~nsMOa=yzq}I?%nkV5WC7lrPZ7}v-jM4&&=F;{qL*40j$D{V??0nc$ViM+I8Qv z8n$QGl+|oEE!TS**i9X@9Nh|(RjpW#?;WZ@tH3I^n_Iqi9kte7iepS5wQnEVR^9e$ z)^=rIIa(lg$MsxY5E#wob_K@P{HjV~6bXrO!~{;2Tu*Ja8Wk1n*p<2xm@4^>UEj3> zm*<_uF}>$D1=dUdN3D5*6WTBO4cqku{OqxVDo?w*-B*7<9fs7ff+*e9G;T|L$-WchyA~*0t9xzs&P&{3?+NnmucuLv_@?Xs_@LVJ zUzNDm_3y8zQIxokbphFnUtOi9n(uC|b{onH`=v;+c4!u!-UEq;*dSUjeMmdo+2H}K zXroIKo85F#8N_2f+Y*nu0ee5FxuYv4aCb-t9QRUEN5-N?5x71i*1+B%;v^l1^K8>T z=sXpvO{Mqz>LWX_8;Tw)dN!!rqgMToZXX)*@ROwsLGO zvt_Y$gRPrv-DWF1&jMSkyjEoE0b3=uwgr-9zZE!Y-Q})3bM#?e;qJyo&WNIiLp zsmS#CA=I&fGImJA z<1mki5ruX_(0|tXBY6(dnI@f2LY+Sw{KEDAYVaH5?*@M`{%K${Rty}*s)1sBYEWa` zGjJLA4W1p*IY&C@N$0sx;Viwd3#1}Lhq!`8(s_w=UM8JaNN0wMzB)uFtK;+92o)dI MSq^p9X&gc0EqjOmi2wiq literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysRoleConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..34348ecbf328de96f72462c5d38d3944114f54c4 GIT binary patch literal 1994 zcmbtU?^6?36g>|}V&YRHB(x$TpkgAFwbp8DXj&jxkpR{pRr~X0^9-xWuCsYzhX2Zb zS!ddre(8tK^pEQF-ra0LNjl7Ql6m*MefOSs&hESKufKo&9l$d7QWz3gv0cmc_EpPs zt+sMiQ(K*bj^(&7eAO|2*EU^WTaCJ9d+xsWjrOhDLFcj8(yQ@<6h;KHFV()XTFPx& z+x3^)HUh~d$8}6uV7O4+6&P9d8ajhvq$Lta3Y@DtuHNdl>)PK@^_CVGt$MagGqmFoXjS`s*Ayo%RWjw|r0aAHdB8pj;O&ey_OsW_nA_V|s3o5U5R6wV72 z`#b29pFtMs400GxAuq7hzwr1+>ZeoU1AHiuXlk?Gpm$s-Ru8{b)pMIA-fcqSA|@%V z6Qzw6-p?xTvY;u6%a|58O>}$;wp5!wT<#sxn(>_;?X1KVT%~lPJxtFZCGTZN^m7u| znLg8_-_QrFt|)PXX)-;U@No_c5+7mlP)yD9>D=Yt5wq?Z-PC?)@}|VcxOJ!|${#_pftG-r7Ha zc!kz>XclTJOMHp1sEo*tluh-!F0hWYpJ*+p(!%z!Rby1+prwJVY|rf6nS6ciIT-s03R z1cs2Ik(YTqO{0twD4wC2z*(H5EH3_oB9lIv{}T!E<~L-Yy~XI}!hC?S02er33NXX* zT7Uva`db`732=ww=K;RpxE!Fu@#_E&7v2!(aH!)J?FytZLbD{{v!r31#wpS;N3UQJ z=Wz$4C}WI{Zw_0?hnlA&T|LdD5Sz5d+E=hmvmtyF?je$ROdug>oxRntGss(xygdoM z?FRUkwLT5-jN|hF-*Nmtzz-aM4Db`jp93h4^#C@ZgMZe4B lZJNBzkhfX#c7?oMCH>b1cw!{sW8g>rMaw literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/converter/SysUserConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..712d1cdcf85570c88c72fb0cf6fa41f00a200f8b GIT binary patch literal 2068 zcmbtU?^6>;7=D%?35lylNYWORDr!swxz<)|8%k9I3I;?2w6zJiGhuU;q66CxCm{OJYFazG)k_v#(l? zZM2oGn%eLVJj1eIxytk1j_G$?Z8YkJ>Dc?)^|fo%4!liIy9@D;B!&bsJ8EAUEoC>2 z$Mqd;`T~hL%eMS^fx%*FOJHchY3MWtk&+ljLf~xGvh`Z0UDxi0s<*VjXw@-QYfHHn z&$~Z|{B6qEolW!VC|#S@3rwr}|dvGT=mRxb5%Hyz%wFiGrDPU4(E zskee2{4_F1rIAHGiJZV(Z^z?@)T>U3kMOa;a8vus4cg;ksd{);RmX0YIor6z1kMx9 zi)drT4_T!xE@)EXQ(P1{MdA1s*s4tjmwhj2&3CPC*eQw2xI%Oadq~e64c=u(;R_Pi z;_&Or^L};Q2A5ZoxE{wj{GY{)#0}<;P&tcqtSu%R5}z@7gpziDW^q&E3*LtmF`qgu zy&T59C2^Z&r-&N=&Ek&4*Z3yl)_mo6=>Fy2leldAx~bi8>*gfB1zmHF5wr706~^R9 z;$2D2cV9qKAq%cnzHZ#3ZkdSV`&L^UVIx#%ZG&cEmWsq8mdK5=9C16}P1M6HO7~D= zIZn5^*ND>bEjM z;|%g_jk7h$))ZR>wn}Wxuw}4yldW59-C=8vt-EYh*m}s;BevGqdLodnIUU#3OBO$$ zxes6FS#ES(0zJX>yDXVpzQX1DR)UFuFQ39bhcLCyW;YTw=T$pvXwyEaT?^zGVC=K$-Eo01J!{ z0<18u23VhYO|b{VdTxigQy8LIf+{&f^E{1{R7-)jVixD9het7wF)Y!ptRaUjVsQNz zqZ+&QQ?;mJBh;~iO=1n;`!J74&=T#0pmo;y3_teMnI)Y+g*u-Hc)|6)4Dd7KF98%| zJ%GvB2%s5X1!yvE2e24-0_-xj0<@3m94DOnqxKWSwjdg)f{y;ivllR&Z6}KPKkG(-rKt+oU!mF&hkEJ+j2r_ zg3>41o1yO{`O6k6I7eGXNNkUMTtZ^nFJjih*AlqE!0gnJ?4=6Z!Uc&@V2ppZOPIIt zjaZM+I%)4#?-jeXh)Wi}6OR#keDbS=D;BPbmk_N54~>qARxMl?2O+w>Tf%~cAMm5X zu+-xl9h#QYCEJN@wjq~x-2Y3-&-l=9T3Eyq{iNWJ{3a9Td$`H4W&5|Su$59PBHgcp2Zvvb7)4ffHBk|0xqn^g6L_Up}&%FrurOpQteinQfp()sk@JMha!Y_iqMtCgvB*N2Oe2$XOG4h#U qO_Stvf_$dP=Op<|lg|wKoMO$VQ}_srJ|AJWo6qf-&u^3ic=iF-isj@0 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/OperationLogDao.class new file mode 100644 index 0000000000000000000000000000000000000000..62f692dda41dddd6f67f64ea2ff3f62a380d3418 GIT binary patch literal 933 zcmb_b$xZ_?40Xy<%38JqCpdzTh~S0>Ar(O-q+wAjxMya}5J;0zk}1sZ@EIKV06q%g zX%V~F#3738*v_-x^Zmo^9RM_7z6uovL9DqpU7?KT9ic^v+!c;XeP)I8HjjO7ktY#P zgyBaSTH&S9p-Fdzslp(G`i1BUu7pncQFMW^ufi~cO=DB;GAngTg*td;>?M`(g4>NG zin+ziIO&Zoc&l`@o^1w8XHq9S#fd|!DYc=KT~z2XY50A2m@CC#eK~yjw(ZMrf|bys zh^Zux4MEQGNJ)2&mN!*?9Wbc1WvWHl4ukG*^S8pE&Iz@bzIZdLy`C%BCJ-a}Q&%*& z1N7%6ITq!7JX*(KzTf$Wb{ChwYcBaZ;=kaJwoPthY)VB#oO>sSwUQDBH?OGaDENk!GE$^5ZG2DJ#KP*Qa2-*E#upj#7qJE;bp``;hG?fM tv<_7mfeO@03r1m_?jZ(aP;SZuOj2O~X^N8Sy`bqQ&kW3xJxmdE0FQ{>G3o#S literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysConfigDao.class new file mode 100644 index 0000000000000000000000000000000000000000..bce344f2ef074c9c029fc1c5b6cb34584c5c13ee GIT binary patch literal 1101 zcmb_bT~E|N6uq+uEBJvZs3a!FH;joBebSVe6p@5j)a)j_Pdj(ZKzHtDW{ULJ@IQR; z2l%55ce=_p5e=vhO>^6O?#H?3eEa_8D*&Xh-iMxmSA~_9j#Wigj+IpC?8qq} zTwR3Pq13t5isZ2IZ^@2Kxvi)V*96=-RL4qI%9iqDeuzcr!-9a<3FI0%h#v;$v4AHdWA#=uZSx+R)aq@lFrZGuuK!S1m4Fu;*{ts{ z#6HQ>%%Li{rYwjDp453|`~f<-N0t%+i$had6_*jRlTrZ{h?+ zOC9gTyzOB)ApJ>2dICBxU~RhiFUvmO`0Z*tRei#R)t@u|%kYnMdxWiKS6_4y*=01N zOWY&98e+3^@qIG7Wwd9sfTbbTuD~5r@nu)K3Vj|$BH*+Gor*Nc{#u~_OlD`8mZzwU z^+C-t8RNe3Ca*BHmVyd~EX(5Ag|m9r3{q$&C}-wL*m?ry_?c&e&#^uGa2At>+*@#)6Q{qHqmyCfJoWC+)O)cGthV^IAIbOO0mlmreh6>|#Fb$k literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictDataDao.class new file mode 100644 index 0000000000000000000000000000000000000000..5239a6a7a4d378e31477573d009f387d0433c79c GIT binary patch literal 1401 zcmb_c-A)uS6h0kbm&HF6QBjOsLQHJ*PKTH*t|TObnjOP^XIh40x83vyohR@)d<`#r z03XVDW>}ZeT}5;+CY{ss|MffP>$lHe0H6!^+Yk|WmTRib2~$SX0n@Ay)Rm4(eQ25U zHsn57L3u_wGc+w-Pv*YIJnJ#jhIs&`MokoPl_6 z>^qF$8MRM%mQyQ+#z}8%N&D4Be=HN&I+U94lvSd)pJP>ve1rgjma7p!wD*NSGW-pzK=r~p0vi)>O`!C6N>Aru5-#d9qpnv+ z?fm-E4>r%MIRCT7jOttGb!9u{9-l@?+Jr4JNXOrny>GO^XYO9iW4l4`10#7&l}K^| zOQ{Jq7rRm+jaPmi)koEo5ct$^KAqM$`R7TU0ica?YOE^Suk{1Yz(5>GCo_fPuMLu4 z8jW0kIJH`bgCLB@T|v+GNQ_&Ez#M)Hxb5a~Q?+3cBIuwL!4h1-vlGE3JT9Z2z*V?5 wRxj7;1yZR|bscVCoKw#glyAc7*!0#9)7uzn4(`<9*G9&7;U3B@bY2Je4)wglPyhe` literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysDictTypeDao.class new file mode 100644 index 0000000000000000000000000000000000000000..fccfa9459a6037001b082bcb2058fb8bb2a76d87 GIT binary patch literal 1109 zcmb_bT~8D-6un(O7Vuj{B{9)Q42g}t$qzASpq#TWr{K(HOl#u}$%+NPSMxP;*_F(~fut=vKEWvI1 s&oQ_K$-j5tE(M-E-AjIk2WO!VPeYee9eC8{uS|mk literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysExceptionLogDao.class new file mode 100644 index 0000000000000000000000000000000000000000..10bef355830604b459af118e8482b1adff5d29b6 GIT binary patch literal 1300 zcmb_c&2H2%5FT%7(=C53f2ADYz@-R;Rc%`rrs9ahqysC4p`~fCxt8q{}~N%#p&%$ktBcuF}L| z{rARt9-YnL%Nd8ay_IJF-B)ue|4d1lrIw3!-Wb;8?J<5-Uga8l#@Ha@m>@GhJ-1>{ zPDdM>3i+(_Q<@tL7U)}~8MQ#OC4pt=K$mtMSb=M_E;6_ZaqL`&8>gY0lTfzu{g;OO&wz@Dn)st+@aI literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysFileDao.class new file mode 100644 index 0000000000000000000000000000000000000000..256158a8fdc34ffa039ba5512f22ad30c0b27791 GIT binary patch literal 1111 zcmb_bU27CE6usHnZd*UfyhABN#(?zy?=%sJnGeEkLhIjnb~!{CLq+`1ECoaG~7MTI;xfopr{ zMTowZvG&MS$(3+?*n}NzurFK}t}wWHEKUSB!d860JVqJ2u*Be{^A!(cuWdy$M)=A3 z4}^|_`{$~Z+~e2<9i4CZARP?OY6edZwN<_5wMP-L*X(>S3&v#7yIb*Og)Rh&93xkiB#cvmXDiYeLV>8w1OBDS zN{Lk4!+7M>JCVeR=mUez3GF@_Iv}3A;cacq`RpHW{EqAUi#z@Un@6hMwAbva+^S#J zX29nKF5E@GXU|zj^5mC8Y|k0sz-iS=+|i1`>d@6*Vsa^iwV7X^CdV-NG6$SkHY@(x zuKy_H+$ya`$tLTAnmjYY108f}Ft^r45w){qlC5($4dftnu^A(u1u3H#GFYHzk)pmp zQSHJqbYO+54y?j8dM`4#3Ms|c;RZEMKCPux!>zN{+tb!NX%5_N@%K)f@52MCmk9h2 F;3pO5WR(B_ literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysLoginLogDao.class new file mode 100644 index 0000000000000000000000000000000000000000..bdaa6b8018ba999f8005607e15503349545e3ceb GIT binary patch literal 1272 zcmb_c+invv5FMwq+muTSPyO?J5r?)Q4fRaU(dhJ{?;foL4|tWtGCTg z`i3~HS5sN!+&c_Mws?j-@U)da)7r;yhG-UB@L?(;kSRQ~Qs{vQ7%fU$Zx#eD zv*>);m`k#)>w|D1YGaU~DcZk>(XO7>{d%!Ok9IH9EB~CaB=#F4TRDmQN)!F<-<#-p zEMo>==gPV5qcr>P9$EtJIXao8-io!mGpwkP$M{)!m22!7V}l6F8mio93)y-qYqX)B zAiwDFl;#726?#@_4z17(Nnjm1(4|!eHsBh4R~cM|I9{&9jag{333WTLMHx4n@GaOT Yoc82x!o1U9+@0>+gZs2zql_JZUwoRO?EnA( literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysMenuDao.class new file mode 100644 index 0000000000000000000000000000000000000000..b845dd1e32d47b0b9d63a4be3f2ee023d28e291f GIT binary patch literal 1129 zcmb_b+e#ck5UpOL>m`XAHPO5zj|RbpJOpGyV8sZ+Y!Y@Muc2qU99w(4hVCA9J|;hs zhkSq^CD!b&u8<2c`Y;St-KXlD>Qfh&KYjv02R7Q!67Vi}($T51lUkAN*P)B9+EdhqM*^0P)v1zJxk7%D~H3cbwisixG7v9)wSowF2a3I%$}aE0Q;< zN0oCanG>@ttIV2kgkE;ZQ6gZjZwjXx1p?@9==bTr4hCH`vA&+o$6=Iw;O;G>c}87~ zN2I@~W)u;95b$~=l2Z)5x72-GopZB0$ZHS}AaAxD3lOk2QuNDUt zpgG^C%ICOmESq3);^6JZO9H;%^3=%0N&4Rgz9-#VREG9$OtjIf*ii%gYJ$lucATTA zq9Mmd+WIZiz%E0Ib%}DaS_vCryb-36hW$G`9)w+wM>n_wL;6Zqfc4|A!C$ z0DqKm+N<0q5)}1evzd0z?97>SzJB}s1prc5AHhJt%hE|lXUdY36XjHeGBiONckES& zzAj_!QR+f!MKW)~Aw^T-uA&iK6R>is&XlyuRq}0die((ZP{1qll?+pFT*Xx;_<{U; z#z!UnmM%)^aZ15N@{Js~AI9ggfG5Ys>76EzD%K%&dKWE5)M?xghqbi=UTkFZNAuV| zl03^is*(%JlDOMxU04%N(91nre@p}{<)(66(4&BGRs44Lrxc-!CN^`H-gI&DnmZVV zZXjmt0OJYicd8{Oq7MSrW+VSH>C=th&805S_%EG5*4+knntgrII%J>Dj4oTo0XbqS z(yJl1d+Rh1WiCraa@hC*8QfHqz*7N>hw4~KqiiL2^Fu5`0vhK#3|{U z%%Li{qb!KQj_cfLe}GQ*$xti^ea!*BJ0y-~Xbwc?!qMh!&w6;zCliPm#bH;xFJ~yP=6}YVpE4MIp|6Q~|z^_|Y zOco%`{@MIT!o3A0Bi@Oq`|Cl?CXDc__BuD%vzCGink>uy_D-apJwXc180B;=Q(kHT zPxzbRhtuN4Pv9A}pdBNagBSdt5%3)1n|KNHoH)5!;G)ILq*qrbOR&uGEN83$TmaaG BCa(Yh literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserDao.class new file mode 100644 index 0000000000000000000000000000000000000000..752b78912a8ba80ef34ed59422bf2ee1b4ed46ed GIT binary patch literal 908 zcmb_b%T60H6ul0Q0DTZ1S+HuCRF!JA3nVlZQV<|jngB}FZY$5sWiWMoQ`-}mkKspH z@Bw@j>NNp^1g-j7j7HbKk8{sCzPi4+1b_~-o6r!jky~kLqzqX(P*#;FeeI>TM^5?R zsytKpFFb4!^Mqa9Y6(f$~n?2@HKze&OeE-w>kLmAHgf{3<-?6lN6D3%FQ7eM`q8GZ)_=O!o~h2b@7G^v{0HO#Fz=& zTEG;4GyHTKZ2cz8K?CMv1Pkz-|1$!fL3|Z2;3X%HuNJweb(6God$J5G9M5vbD!>n; CB`5p< literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/dao/SysUserMessageDao.class new file mode 100644 index 0000000000000000000000000000000000000000..2785f4d965a0bad94fcb590d6fb8c128ae6bf2ec GIT binary patch literal 1261 zcmb_c+invv5FMv9Y09nT66hmuT%=m!4Q)Y6DU~X1RFnnYz4mnLvauuEo3ek<59wF* zfe+xL5aR`pajh%_o8a@$56v%z;xi$w* z_~0rTDu-Ot+3MbeV95Cce_rDP<@8JCvQnO1qJ{UJKOTUK8Z2K`JIM#NMZoLm)e zEB#ka(F7gp3$(s#E|WJDR<~*xpdZ~ZKwOV799s2WL`nlX&)`X$tUqwX7jpU=BeTm{ zTwl%uX)6;JihspAkF2poXtt2mC3+=dY_;Auy%x)~n%T-p+|?zu&tPFlHe-7-IBl8! zoRcK|?-{uszFQH^li3&({WM&kwAXowLt|_ZL0dzu_Tskzd+I~9p`Ic?AL4{o0D~p^ zmTB88(VFPN3Ur`PQU_MyHl6(r+@#|c#4U0M?#|U~je40yHL2F&-duJ6f+e|l&_F)? O1wDXABzMX2V}Ku^OO}2B literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/BaseEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..70c8e9c416b4e6d90cf037c8d5c759d99f110584 GIT binary patch literal 1688 zcmbW0Z%-3J5XNUq3$|2?MNtF=M4?b+L5xZ;BnX<26g7&xHQT$TEMD)L`-9scjlS-?d;soU*CTa(KbCCp&X+P%jK?jDjd({ZQ+WR(OG%JvxKt?&jEIbTl=S!J4rIFgJxr}#+ObED;#cl=tx_1I)LRno)fiQ zXbb3JBpH`?eh@6BO8JXUy+&BlMv zh3-X5hI^QTYHcY!2Ss8uTc!dHBP>Y5#%t*)eS@)m86JD~YoX^Mls>4+$ZK9qKmSxW zeZ~OjI*Vm0QVBBD>61;Hav3UJR~LELeKwuuUYRQ0H0O>aZnygwI&QU0)o$Fm0|W8a zi+oGIP`c-p-v6_r|B(C~ghTir^OVy~!EOXQZ7;y)^aadW1-nt4m9f7V&?Rhv)#n`R zIWNNr7ULX+HL7tWWO^X5P9UDcGT6fMH@fy2A32)Ds_PTMz@ zyBSOiX{Py1rW!4w#$QYeX{JRKs|{dEp2;v3W2WUyrh1yGp2>7So2i~=;$T`Gz?4jf nVXDMTE166@&9t7$w3f}p(@c-S^ke{2GL(j?8Z$k>nxpmKuy{ZX literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/OperationLogEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..21fbf4b84dad25a99c90183a6ce707ff4418738b GIT binary patch literal 2722 zcmb7_ZFAE`5XV!j zypTn#$G!MX?D^3P$>Kz&og|gq>mGYNO8n%F_hX++miQuSi{7qYnxaXEHczQ zcW63|xr|uI9a?O^Vy~GOu&C!9Cen|3w;einkRnjXkNns_4tO()M4}O5#BB@N^Wwge zf;i-V2>H9$WeM{n544H}UPs^zA?x>{@>(KD!wCD9aq1L7t732_hbkdYUWzUr`V8A4 zLPhd84HAb+ejlve)EwWT`4QH((4>_ZU@4rYxs*cg$35(>AD@TnxpK#k{AAmqiIv8Y zLz6AhQY^ast}n~qtH9YN^#vKcc3trKqK#Gfo1sIUmqG5@au!s)Ccm_xGFguvbtMBOSUwA0dIgHAakb_S#x<){s(RsW% z^f`Tj@nh$|>B65djyf+}oiEZQsFd?I<`U-0>b19Y;X`PZP@)DhzN&XPV^mpqg=PwL z8LBewGA4(vSecgdOlwxAt9GX4JkvUY-5kSY?ncH`(@ZN?rbeD=!^(8c&eX^=ZGvfQ z43oK*8B<*|eQjl0%QM}zGI@5UwLDW3Ogm$kOh;r)u4cMnWm?ZO?OK_>u`{jbnfAc+ zcnp(i#*Ar3Gkt4i+Q>8QTbaJMGi~IVeg@OQ7$)-_$e3m|(=FPx^xamT>6w-34&6l` z75Z)~&-4qJejUSPK0z7NoMzg#=ILIZ={GA=)1Ie$c_s#?<1tL;>z6StXr>)2Q!CHJ mtxUUirdFQG2h*!DOy!`6Mk1V(N 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 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysDictTypeEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..49bf039f538b9ccf6a61ff2b9783e71298f7506f GIT binary patch literal 3120 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 F+P|QH(#`+? literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysLoginLogEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..df0d2ab570e71089ef21f8dbf6df8df1018f2d2a GIT binary patch literal 2782 zcmbuATXWk)6vvO8i)&X&9H&hwEtgO(PTF)^Xdt0U$gODuO4A`}h6k7;+l!+jOCDX? z$+v=61@dXyZ_DV&MauZZ z?C;o(JYHv;qsfT}m@Vi3R+KZ)lgS?H*KEySNUo}2jV$`WrZF0aTCCM(T6rx#NMm0n zCt>%Q%au%I1h~ua`~0kMSKjcRm5%+-+f<`E)ZzbJ{p!UinKs8!umiTcYtsbVDK6BG z!*Qy(y;%OKO_M{v!+jJ3T3foZtn|4}Q>;`+@N8ShIEY#NrA>`ti~}602J1uB2rON< zX_}=q80%f_e_wY9t8CfS9Qx0;EwUBqS?}B!X2#Gx?BlUbGjs)J2&1ke_mxFAvkV!m zI8pV(FpWBL*W(_VE!^b0d{-@6{_i(Obs*Yi0#C;a-P#yw4x}S^Yid;Ce!;4W70;J2 zSGdO6-et`Evty-Sf=LKav7%rK0@SJ~Xh4866$R4}pg2WA69QzsD7cDk zB$KXTd<&-%m@Uj>3xCk{U)3>hVB|v+9N)xfYXy3T-o?tI_vn3$ZyNtbbH6}Xp>yMw z(fAg92rV{V$6UcYzHs|@nmZ3&SG#vmfkowER%>P98BN#bBiN3i(=l1}F@0iSYUP>k z8JQO7HewW*T6v}i2)0zhqu}%GctW;W?IWLeGjG|N|^K$lrc>! zrVS(0W}fLsBh$8-X*18%1(Pgc(yw2})KpA6Xujh6w3}x-F)}@&J=0sTn`iRD)GuMu a4{yda1Evant;TQE2ZcWz4u1G}?Eec4rlQ*b literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysMenuEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..ed4673522c1de02034cfb8ec13cd7e4f3f7546d6 GIT binary patch literal 2392 zcmb7^+fo}x5QcjIfdm^HBSd27;NU|nz-E%*m^cs!mJj8!Y^NfMTWXLd@;cgC)gGMU zt&%FcT;+>AKpx8Fzh@VaR-+3pw4>err~B*qXXgKpAO0hvJ$gJt6N0weMw;-A>V-xI z%BZfE@o_AD^Jk>uBud*!8fn=%lG-GGax7cN@pEm`NA_)orUczTXNCtV*4cDH=`$s*!XH1x=#1Bo3y3H`^%DB%`zy|v7 zF#1b&RH9_0dsd}-vK<0HQ2jnsvJv*uz#wl44W}qt;rfTh0+jnILX%HBg60QUnxQ4B zWYI$(;c^&tbo3$(1XTx=Pfen`Izsx26&xB?*cSJX`=`|s`@huJQGhNg?J($v289Jp z$7n9a$LVd~_{ol-$@;wfd-Q!wh;fY(EQ+jlPE@nB; z^h<*|Pvj?Qc|F)wo_^P(OM{JPZkM?mHklpm#;+37ECTRmH1HV$Sm4pXJOWs{(ZB)%Sg_GR6#=Z$XkZZmtjuVj zW((uoAoK-*B}Rdtwp`X4)(=HNf<63{!Tr za;BCFv9~MfDgs+KfCKo%xi8W5*AEirhGf+FsI*gi||pM3DH&xl=ih55mOv#GV|F)2Ky-m+ouVX}Ce% zIXrzSyu_l6U&DO4XDEk3eaoVSr)~H(#fcyLrwvgIf-rFtKMZ1vmdjyOcj8v$2X$m` ziZ@~O%Bi`D>$qK=vtL7)Nw|UG*iRb5qM5!tm4w|P*&H4%5)GNtZ8%0lDGcgupoo%dg!i$8P zh3+kW6D+ZK&1ubfykS_*3-Pb2h!P4ChB7F{a)fjDS4PepX>;@o)8 znc&2Yd>-q`(d5j>5_ih~uc-J0>LS@k3C%38^c}7&q8wSYYEzcRAd8i3b~&x$WfY!> z7s$MnIv}D>aGHs@rN=BwFGt*|8=>eD?4q;NC zie@TErrSoQJ87oJMy9)FraNh-Logi;VNzeIW}1;qJ4U8rnyF%BDw&yzX{P63dNG7a zT@adSRx<4xnfB65KNy)Fn3?v{OjR)bID|>vO`2(5GCiby!(H$w&Ey%G%Jjta-91V( z)xmT&gh^eCn(4A+IxsRFrkP$DnZ7kM9j2K=Ftvs-sT)}{U6D*rjZBp^Q*2~T&gJEK%o?56kaqE5+s@!D>2mYN``hUE4wpfb{5lbrHRJG z2S0!x%J`q%1$tQ?c<9W|&N=7*JO4fX`|tN3BHE$N0%aW9YD*^78TXWAK9{^JSkMcY zD?e)<7#+4vs0HgBF(Hj>daTt8_LV2zM5h8}9eR1q3a@#Pq&qaOQEQL;!l9|=7k z$7PqbjCN)Bl|ys;A%uK!;0ErICw8P%h8tJO0J=@3yDT`hp@8+pSEWx_ha1kc@S-U0 zv9XgGvu(dr+{2%un}--}*Cb$D{|*iza!G~EaIP8!h_8kOP- zK@^b>02cx+zvW8TY&$eoUpa6nyQ?~)L}N5tp_?@2&}7q_>}@o~f_&b&^?ot=OlL3<2;t}JD& zl{gh}Dq|nVuNY7X7w}~CqJj(bJ9;sR3-mI2Q6<|c#tG{*R2X&#d#>?|X1?PgLp7{c zi-2(pYb6e#+cbxhLwD#d*1_Z-H2)2k{mHe|1d$wM ztb8qwO5`nC?9oHq<=`PU2NtF=Eetc=Pi1JIObsxtUcnSkM#3}^F|DRDtqn7+r!uXlGp!9XZGdU>3Z{4{6Q(Md SG8jR-KD!wD=Wq=}zwsZfJG&VEl_nY! zFZ==iDC0Z3TWz=73odqMXU==hdFGs%-+zAoBBDLo$y3Il-KJ#HJ?FM7nZqS-3#Kj< zv*ZVlE8h#6e&7k#I%PuomVdz-7wVl7-a)v^)2Kl^myGa|D-pRHR0t4Daz_|6QUA!# zIkUNJvxe_kvi;nk+2a6-9C2bP>(mx|Qo26(Emtb!t-D^Esg9Nc))Ajw?-OfrpEFO` zp^DqA=>p&3oeorN-?alrB5oE34v@6a;Yz`;g)QN5%Qh(IxwbgO#&{1<-3@W_+VR^qySJQpLy4}+89-CCA@hDzbJ<}VnE7l>4 z4L9(b;*}Nlt*_SW`VJekefg^yc3j^~{UQ`C0BQu!G)o!X6Rh%Bl`t3Zjj7Op+723u z@IXZe4J8;*v_ZpF7;ySQLpe-{3k%aE(lgA4hFbYSQ(y6up&5)i7lH3OMl%x74VuNu zpqq3HW54q^n)?D{uk&oG^KH5Vm3FRS&S1{1tbV7t|Ecw1iRMv_+hK&6NEN5oXi@R* zLX|~vF&U_B8q;EuX(5&Aemc`)l4%LamWMD!eT$ijA=6SS({hrjn#xp3XIf4&t$}HM z2vc-rVy05aRHc=a-mNB?Hd2|^kSV2it4XF!Fl`NCif(JnWQI(P9;GmCB$;+nnV!(o iG^ULt(+e=whA>4BC1xsvDMOp#xb^RaJ_8|M==NU`*Gpmm literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/entity/SysUserMessageEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..65c884c9e1895c51b2d65079231a695f33e98f20 GIT binary patch literal 2422 zcmb`HZBtuC6vxj7LYi=aNNE*YpHOR{mQ_^R(iWsCba2wv0mPS?C0Wy3lY5zaH+A?{ zI-}!^FZ=+0D98WV-Aa11dEtyNayPr@VSndo|N8rnKZ$6U9#^O&sM$$mlD<^^G?4?9 zsGgSjc`oDRhfL)r8+Obv)3SRibz)+3E|1Rh?{b|z(RmKtJ$qQ8X+iZD>ZOu>mGtDZ z(-*p91eM}0&RZ9PR+{wg30giJ!fv2X;yga>>)j+tjWThX%erZR~a?&JVSMvr3$|GyAXB!D{p| z;zkCXZ%%@2r5)9OFBNo=+SO*K|e1Wh;7uCCD(U5n^VdP~qkD^B#& z;owwf#|p`0ZgzO0vY7Y&aN0bNk=?!4|4?quT2C9!{9? zH;P&uOZ|y9&(rR=ipy+t2EHo%a(f+g+0AN1Rd!Q_8+R(`5;TroftFso+?R;$)+3su zdFaB<>s}cp@T$yEgS)0HDO-LK(E?l6VCjzq%|plcI~SYvZbwvSy?N-3h+F^%w)U)c zFQP?O;{e>LpgF#Aq!q5ciXzYq?BnZ*mgoxX7-_`rx{oMeW&=A)hgnDO$J`Rjp{ZTx zxfFEgzYmY?DRe;{FGbtVjqiT?0KijtUGTJU2Vhshj@L_AOI%KWHjA}}-)v411gO`z zU=9M5V_dKR0rEdCcmo1td|YrD0;F+Va1}QQ9wmI2!6>l`tmU=e>Fr-E^mTk0n*jU{ zzL8U)cj-Os1if#=e%<(2TKO5m5?vUt1dTtUkDS^bOdSF>_c1RJjyIrbdxzEy%PMW@;3f)^VAfz~n0JnW~oQCVd)Ux>aP_ z2r^0f3~`U;=~j_x6HK=!Fu5l4Ommj$^B~hkk!dT)^ktZ7qsX)krkx2)uD?Cgf@S(D z$h28xdKhH76K2{hGVO!u@dPF}TArzHneGOewu(&O1exxKnYM~dPr>wT0+X9+&$MWn z9$;j~dwi$JbQomXrH7$@+9@)ffa&`QOzuJPOiN%YQPX}O*=LWRxIO&v#O?nBvpAJ0 literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/OperationLogRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..d58d3a9314fedaffbfedacb2a90b008412381e3e GIT binary patch literal 4587 zcmb_fX;%|h7=CV8M#2 zsb#szGeUDV9Zfe^Z0@*rKIP_Zp{0|WEpnElyOzDFE#!pFUEMMhR_1DPSwSm9WQ}id z&ERH6TS%^nl&hef;Y@XqltrQga_6cGW@t%si=-r~i>cI=wwEb6!>t%YN6IocgzXBO z%x+p%@lct>>8GMdZu^98>h2`N!{Mf-R@1QQ!;MrLS!QURw$dVu7IdrVM1*`eJhI#Y zhNub!JLKIi6&(mObSHFET*_yY!d~J@L(ratmEy)Sw{`hkSZsAyb%)_%(`p7HTRpJk zyU4t7SFQAAZu6|5$PmDe72QlvZO)|`wBbaFPYKJ+#6}Xf;3;CE=8-3tPa3+jDr{}u zGQAit>KT(u&NA@lJ3UduFb^ngWw~yaQ6M%M>%;*ZR4~90djV>y*oQ+5CxYtw$!5wm7&+tgVZQf!mN-00AVg#cMZ9JDVHW^l%r)xvT`G9#>H?)BOE$zzZIEC@UPkLCjdF zWqHk5Hv)X{|4Q5j7sEJ>w-mg|aIRS{Hi)W_J^4qYoS!INWQI=so zte0hHRJ|HL>p%q|sUW4AIkQc-y|3Z}++Y|eS2}K{pYb4NaK30! zG{E43a`fKd*<_j@KFN@5p2D>gwm#>=NFuEu#n9_DcUR8}%^NsoxGR?ENrk`)bpq46 zOJRT7%_{d%V_C(T0-YiL!evIqIw%WNN4P}?GV~XsSp{59S?#_Ps07p~M3tFe+ig^v z7OlLU60^D-!uqNYO~<9v81`PxQ^CxNW!=$fMvI%K<$5zY4FF>a%g$&{PV$w;_^h~V z+3T7^(ub^nHaIX9 zBu{h0Skzq+>u!h3FcdVYIGvUJQ&@`N6WNGASMdezd%bhUn;h%(&gY@XNDZ3RoLjov z@L2@+J+&CVQE?l0x)ppK!5!lIoM{T%8xVz~;0J~yC4vQ8%FrqcP_7BJdj?@a+QdpahnXV_P`&7!yt44`3(x_YgTiy1~aEEaDGh67Q7o zCq4Xk1BS;v{OhE)G`u%p_!CS?gU@c^e930t{X=B)Q3}Es;SB|FdyBZe)$C4So=|*; zU-EG0$!-~=K8gDn3#`K5S4-HwzsD(hC&=659dX#1;#0| z?=(5-RKT|WqHX=Sg%3+Uy#+) literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysMenuRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..9b5427c5a2641b6fe6bdccd9dee5f6656fa87a05 GIT binary patch literal 4456 zcmb_fX?N2`6usjtB959E2S_0)1Og!&sO+>(p-w_dsKb^tKnsP5J#j>2$(7`Ubc61D ze@lB#NedtP1A6+Kdiq9^Z3Qpbw8zJmG@5z$EqCrb|Mkz)KLI51vw{f2blTKRYmFP0 zspYuIvqEz=98EWuZSJ^sA?+4yp=FjdTjVWAcP)EEo8NHegju*=8d1>75WCOUxMpxO zt6f>TFVe1pc80Un?WZlW8ZtRsVUwXH!!0t9s&1juLz-T6ZJJvNhK{slt_j-}HpSVn znbM-7v8kdJGTA<%o4R|B;o)$@2A}b(;dON!8Chg#ow70_iWYRM=tPY2H9WG|0fx8= z1>5A^4iz1UGIXbOQ(P|OmV~{)mkdF3QdXK9i`>@bb1>NIuILWKOv4_A3RqD;N>*%6 zxGPrXDz|w~P!-7bwq@PSOm56(7_{M3nK3EL%qB)sw%}=^nC8(VUsy79XGPfBoMn3T zoY%7^mxN@v-Q4Pl8Zmi587s$ivsmuLxkM-SVZVX_hSM)bJ{1Sh$FQduZPLt43xjfy zNxHMn<$__z!W~p`2t$;VtZ=6c?ofVuhDSnK@dgud+OESYMlj0I#`Ae&gCX5G{p!)k z$11qGp)D88w5yW}%mg=yD8_MA!4ZbOI(1Q@;Z-7Ej^`OBf~wT8_`Cu~bmB!UlmL$w z42sNS(l8kIQGRMTGh-AU5b09&XEaZQGb+yFB*RX>m=$$=9TN%&xK@&+UouH=ym)$o z(7JpNXg>+lZE_0*CYsnbaz*pmnp81`^9%!9eXZO8MEiUxkXDDU(Wbssi`CV(X-y&o zYO(&m8EY;JQOx3P1(z5m8x@b*TU12~bCfFAx?sAxOFMtHxv&~_ffz;RiyG*Ic{+GS z#RXhtI2IOM|A2q4U@O#0$WDP_tO@;Ph-N&o^v{W882I_;#6(Cw7A-wPavrCna8U~A z4F*vweU<%0-P0|Q=^8>OrSq1Gccn5a%LaGncwUa(R&fXK)7kB=2(zx51ti{P@Z3^{ zA0+*`)41nVi&=laM6ra7f;2;~cPhJjPH0|}FwI@DKu;9V%@S=HHR7@VYwT5 zp_LnG*(^<3mP;Ks&--1I6GZ{*3f347l=~#zT(efGFdi#tB473zrVSMjK;qCzeO7UZ z;qUOy30C^XFLE=ZYQdEFI> z?sm8gL*bB0Dpbx-FciZ_QieZO@eq$Z`JDE8ygKsPATdU2@T%Gg)!l|qVtC{^!|;`g zySUe_;L8~95wB-WQ`laICmaReGaM?1u_fnQi>2U4hQ0Nt(mwDji~S^hE%a?e1abMd zfO^Te{8K9>b|caVXd z=)x}g00aIq^x|cDA_E=_^X?>21iR_JBSOP;p)d8t=%YpbbRWSh9{Npsj?i=e=x^9Q z_5^z)pu3)1n;5+D6o-LLjQ!%xm#%bqkbB5@AAR3EoD>7hM=m z;3Q4+flqnBb7V^T+9!dZ;54hieeGG?0g7Tjp$>Sss=qwICE>yOQfzNljV)OjTLs1t z#dert8>$i8bU3zYFSZMqDFMIb0pF!(nbbiUn@s1}CN4g~T>Aj?kZ&@euxC zDYt{ThU?|rUi0whLq%Qi@NW>h#P5~(K~bOL9a+qqn|QCBSD#wPDdrPIurq{tJcQd@ z!tJf7X)Gc)6}ciQd?~<-kNp9@iEIE%@s^<^A3-coa4G~5FG0kSgGu&UVbQz@^7w$R n?KEQ3)uFE>+J}_ckMS8k_wK&H*Z2nC(z__l`wl_ literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysRoleRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..3bc1dfe4c112641eaaf7e5e9d006275acdb52467 GIT binary patch literal 4088 zcmb_eYj+bx7=9+bY@4n$q(FsMZiUh`$O0;$snuSn6jQ*q7Ell;$uwQM*@?TGmUzSa z@6mIl3LpFd9)FX^cXo4G%%v%Ma+2Ad%)HNgdEU#Pe?R*JzzlxU5Mh|l+J-H+xFv0) zz-^uvhFf+G(_VMD>p7*YS8{}r%NUL*O4szHQ#Mx0?y|JRa&1RLH$&_p-{OYF?Ywa_ z^H5|x4ZRFkn#<2hk{S}Z*dUXkE5{`XNH>?zs39G%sy5GMilIL%?JePW!XZ057E`-a z6*gCuLLz&oOxyIP86Hn`Ebw1?b$qXlB8fGI?m3wgQFLKY#{gpFuZhH3KN#XVH1w&b z13LNP@Lc?)}OD{$~9Y=7I;X+u+ASre+QpNL>j?)+? zU*&~2XK|O@HZ+k4Im_Qn#VLy?bR;mz(8G&GtIUw?oR#g^6=0P-(=ygecGfegI4o2i zQc;}6ISsEejI;@t4g=?jlLcO6n5y`pg~Z+B9x;h7v5*6NwonGRe2b`Xy_M0;g1Z~m z_WveqZP2fn#k4+) z7cx11>LSDa&I8z#pY1&!#YecO;bVqjzdd zjwCg@Ns1=8YC7l*OlO#Gk#~)3Z|W>c#T8j{vSPth zS$wFW&!1CXVmQ29qFPW8Yo=?`L@{IA(&MUeQ1?ovrIR<@qGQ^58Y>H8TRNMDOA~>R zUb!fY`Xostj?GHx(dfyG!T8`tQGnDy*>bWzFqrn1+@!$xte}H@-JcxFI*Ry=VSomX z>K4Oa;Q~^*83@0|?VKgtQ)wwTOT|>Ea;$ht-SEzH7gtH|7yC1SY=1Z0?JKZz+_F|o zPoxHWLB(J^Y*KBssQag~6$82NGPZPVO3VYSwfIdr*quk*^HH zS2}Lv&Y*@bW4J@SUbJoD_%n@gHGIc#x^BjEK7T$~8h&6n+WsizK@eG-pbpSQ-yTE| zSMxDVPjNLJ)7ne>1JLQ8m+0*-tzEPZPX2~{lgTI8KY8{EhJK-~2oBP39NqLgM85|} zz(MT8A^HHvgKHSZ%k)M9d>H0GDWC`r({q1>wrQa+qbYHOE{)Q21h4q$cj!Gr@1v8y zVt?`}jz&OFLw9#DcKaF506R$j?4MVv?DHXyknj=u9P!mS6x^?=F^UVgNLUKIhh|b* z7&YhDYrt>#zz-_GV+vS7CU@Uan&Y{ytC9yFlJP@8jyh^#C^(QQW2-#iZ*Mlj6zWK>>VFv5Z_=m#An# zb3Ab(5wap)vmy?Gb&}VOJe`YR117DCu@7n8q_6U~Lq>Qg<8%M%3w({o_=f(A(z$Q( JJ$}UDe*kV#o%jF% literal 0 HcmV?d00001 diff --git a/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.class b/novalon-manage-api/manage-sys/target/classes/cn/novalon/manage/sys/infrastructure/db/repository/SysUserRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..c375c908e059d244a213f79849ac0a8d7c29b928 GIT binary patch literal 4452 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 + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.4.1 + + + + cn.novalon.manage + novalon-manage-api + 1.0.0 + pom + + Novalon Manage API + Novalon Enterprise Management System API + + + 21 + 21 + 21 + UTF-8 + 3.4.1 + + + + manage-sys + + + + + + org.springframework.boot + spring-boot-starter-webflux + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-aop + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-validation + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-actuator + ${spring-boot.version} + + + org.springframework.security + spring-security-crypto + 6.5.0 + + + org.springframework.security + spring-security-config + 6.5.0 + + + org.springframework.boot + spring-boot-starter-data-r2dbc + ${spring-boot.version} + + + org.postgresql + r2dbc-postgresql + 1.0.0.RELEASE + + + com.google.guava + guava + 33.3.1-jre + + + com.github.ben-manes.caffeine + caffeine + 3.1.8 + + + org.apache.commons + commons-lang3 + 3.17.0 + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + org.postgresql + postgresql + 42.7.4 + + + org.flywaydb + flyway-core + 11.0.1 + + + org.flywaydb + flyway-database-postgresql + 11.0.1 + + + org.springdoc + springdoc-openapi-starter-webflux-ui + 2.8.13 + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + ${java.version} + ${java.version} + + + + + diff --git a/novalon-manage-web/package.json b/novalon-manage-web/package.json new file mode 100644 index 0000000..1074ff3 --- /dev/null +++ b/novalon-manage-web/package.json @@ -0,0 +1,49 @@ +{ + "name": "novalon-manage-web", + "version": "1.0.0", + "description": "Novalon Enterprise Management System Frontend", + "type": "module", + "scripts": { + "dev": "vite", + "dev:local": "vite --mode development-local", + "dev:test": "vite --mode test", + "build": "vue-tsc && vite build", + "build:test": "vue-tsc && vite build --mode test", + "build:prod": "vue-tsc && vite build --mode production", + "preview": "vite preview", + "test": "vitest --run", + "test:ui": "vitest --ui", + "test:e2e": "playwright test", + "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore", + "format": "prettier --write src/" + }, + "dependencies": { + "ant-design-vue": "^4.2.6", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "pinia": "^3.0.4", + "vue": "^3.5.26", + "vue-i18n": "^9.8.0", + "vue-router": "^4.6.4" + }, + "devDependencies": { + "@playwright/test": "^1.40.1", + "@types/node": "^20.10.0", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", + "@vitejs/plugin-vue": "^6.0.3", + "@vitest/ui": "^4.0.16", + "@vue/test-utils": "^2.4.3", + "autoprefixer": "^10.4.23", + "eslint": "^8.56.0", + "eslint-plugin-vue": "^9.19.2", + "jsdom": "^27.4.0", + "postcss": "^8.5.6", + "prettier": "^3.1.1", + "tailwindcss": "^4.1.18", + "typescript": "^5.9.3", + "vite": "^7.3.1", + "vitest": "^4.0.16", + "vue-tsc": "^3.2.2" + } +} diff --git a/novalon-manage-web/src/App.vue b/novalon-manage-web/src/App.vue new file mode 100644 index 0000000..c0a868b --- /dev/null +++ b/novalon-manage-web/src/App.vue @@ -0,0 +1,12 @@ + + + diff --git a/novalon-manage-web/src/layouts/DefaultLayout.vue b/novalon-manage-web/src/layouts/DefaultLayout.vue new file mode 100644 index 0000000..da4f76b --- /dev/null +++ b/novalon-manage-web/src/layouts/DefaultLayout.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/novalon-manage-web/src/main.ts b/novalon-manage-web/src/main.ts new file mode 100644 index 0000000..d493205 --- /dev/null +++ b/novalon-manage-web/src/main.ts @@ -0,0 +1,18 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import Antd from 'ant-design-vue' +import router from './router' +import i18n from './i18n' +import App from './App.vue' +import 'ant-design-vue/dist/reset.css' +import './styles/index.scss' + +const app = createApp(App) +const pinia = createPinia() + +app.use(pinia) +app.use(router) +app.use(i18n) +app.use(Antd) + +app.mount('#app') diff --git a/novalon-manage-web/src/router/index.ts b/novalon-manage-web/src/router/index.ts new file mode 100644 index 0000000..e45857a --- /dev/null +++ b/novalon-manage-web/src/router/index.ts @@ -0,0 +1,44 @@ +import { createRouter, createWebHistory } from 'vue-router' +import type { RouteRecordRaw } from 'vue-router' + +const routes: RouteRecordRaw[] = [ + { + path: '/login', + name: 'Login', + component: () => import('@/views/system/Login.vue') + }, + { + path: '/', + component: () => import('@/layouts/DefaultLayout.vue'), + redirect: '/dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + component: () => import('@/views/system/Dashboard.vue') + }, + { + path: 'users', + name: 'UserManagement', + component: () => import('@/views/system/UserManagement.vue') + }, + { + path: 'roles', + name: 'RoleManagement', + component: () => import('@/views/system/RoleManagement.vue') + }, + { + path: 'menus', + name: 'MenuManagement', + component: () => import('@/views/system/MenuManagement.vue') + } + ] + } +] + +const router = createRouter({ + history: createWebHistory(), + routes +}) + +export default router diff --git a/novalon-manage-web/src/utils/request.ts b/novalon-manage-web/src/utils/request.ts new file mode 100644 index 0000000..cccfa5f --- /dev/null +++ b/novalon-manage-web/src/utils/request.ts @@ -0,0 +1,30 @@ +import axios from 'axios' + +const request = axios.create({ + baseURL: '/api', + timeout: 10000 +}) + +request.interceptors.request.use( + (config) => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + (error) => Promise.reject(error) +) + +request.interceptors.response.use( + (response) => response.data, + (error) => { + if (error.response?.status === 401) { + localStorage.removeItem('token') + window.location.href = '/login' + } + return Promise.reject(error) + } +) + +export default request diff --git a/novalon-manage-web/src/views/audit/LoginLog.vue b/novalon-manage-web/src/views/audit/LoginLog.vue new file mode 100644 index 0000000..6d335bd --- /dev/null +++ b/novalon-manage-web/src/views/audit/LoginLog.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/novalon-manage-web/src/views/audit/OperationLog.vue b/novalon-manage-web/src/views/audit/OperationLog.vue new file mode 100644 index 0000000..50fc149 --- /dev/null +++ b/novalon-manage-web/src/views/audit/OperationLog.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/novalon-manage-web/src/views/config/ConfigManagement.vue b/novalon-manage-web/src/views/config/ConfigManagement.vue new file mode 100644 index 0000000..521b567 --- /dev/null +++ b/novalon-manage-web/src/views/config/ConfigManagement.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/novalon-manage-web/src/views/config/DictManagement.vue b/novalon-manage-web/src/views/config/DictManagement.vue new file mode 100644 index 0000000..e346aa8 --- /dev/null +++ b/novalon-manage-web/src/views/config/DictManagement.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/novalon-manage-web/src/views/file/FileManagement.vue b/novalon-manage-web/src/views/file/FileManagement.vue new file mode 100644 index 0000000..0bbc5c4 --- /dev/null +++ b/novalon-manage-web/src/views/file/FileManagement.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/novalon-manage-web/src/views/notify/NoticeManagement.vue b/novalon-manage-web/src/views/notify/NoticeManagement.vue new file mode 100644 index 0000000..260e475 --- /dev/null +++ b/novalon-manage-web/src/views/notify/NoticeManagement.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/novalon-manage-web/src/views/system/Dashboard.vue b/novalon-manage-web/src/views/system/Dashboard.vue new file mode 100644 index 0000000..fe24a61 --- /dev/null +++ b/novalon-manage-web/src/views/system/Dashboard.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/novalon-manage-web/src/views/system/Login.vue b/novalon-manage-web/src/views/system/Login.vue new file mode 100644 index 0000000..3fbcf56 --- /dev/null +++ b/novalon-manage-web/src/views/system/Login.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/novalon-manage-web/src/views/system/MenuManagement.vue b/novalon-manage-web/src/views/system/MenuManagement.vue new file mode 100644 index 0000000..5810967 --- /dev/null +++ b/novalon-manage-web/src/views/system/MenuManagement.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/novalon-manage-web/src/views/system/RoleManagement.vue b/novalon-manage-web/src/views/system/RoleManagement.vue new file mode 100644 index 0000000..28574fd --- /dev/null +++ b/novalon-manage-web/src/views/system/RoleManagement.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/novalon-manage-web/src/views/system/UserManagement.vue b/novalon-manage-web/src/views/system/UserManagement.vue new file mode 100644 index 0000000..713c53c --- /dev/null +++ b/novalon-manage-web/src/views/system/UserManagement.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/novalon-manage-web/vite.config.ts b/novalon-manage-web/vite.config.ts new file mode 100644 index 0000000..45f9089 --- /dev/null +++ b/novalon-manage-web/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import path from 'path' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': path.resolve(__dirname, 'src') + } + }, + server: { + port: 3000, + proxy: { + '/api': { + target: 'http://localhost:8080', + changeOrigin: true + } + } + } +})