From f9d96473daabd2d541e97dece1589a285a7cc12d Mon Sep 17 00:00:00 2001 From: xujun Date: Tue, 21 Apr 2026 16:12:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 43 +- README.md | 874 +++++++++++++++++- pom.xml | 209 +++++ xtools-app-common/pom.xml | 26 + .../xtools-app-common-cache/pom.xml | 40 + .../app/common/cache/aop/RedisServiceAop.java | 73 ++ .../app/common/cache/enums/AppCache.java | 107 +++ .../xtools-app-common-call/pom.xml | 31 + .../app/common/call/SysCallInterceptor.java | 87 ++ .../xtools-app-common-jar/pom.xml | 31 + .../xtools/app/common/jar/init/InitJar.java | 71 ++ .../app/common/jar/utils/RunJarUtils.java | 52 ++ .../xtools-app-common-job/pom.xml | 23 + .../xtools/app/common/job/base/BaseJob.java | 133 +++ .../xtools-app-common-log/pom.xml | 20 + .../xtools-app-common-log-bus/pom.xml | 31 + .../app/common/log/bus/enums/SysLogType.java | 71 ++ .../common/log/bus/handle/LogBusHandle.java | 54 ++ .../common/log/bus/service/LogBusService.java | 25 + .../xtools-app-common-log-filter/pom.xml | 48 + .../app/common/log/filter/HttpLogFilter.java | 177 ++++ .../log/whitelist/HttpLogWhitelist.java | 36 + .../xtools-app-common-mq/pom.xml | 36 + .../app/common/mq/enums/RabbitMqEnums.java | 65 ++ .../app/common/mq/handle/MqErrorHandle.java | 57 ++ .../xtools-app-common-sentinel/pom.xml | 45 + .../sentinel/SysBlockExceptionHandler.java | 62 ++ .../xtools-app-common-task/pom.xml | 31 + .../app/common/task/enums/TaskType.java | 93 ++ .../app/common/task/handle/TaskBusHandle.java | 32 + xtools-app-gen/pom.xml | 20 + xtools-app-gen/xtools-app-gen-biz/pom.xml | 119 +++ .../xtools/app/gen/config/GenProperties.java | 124 +++ .../xtools/app/gen/config/VelocityConfig.java | 42 + .../controller/GenDatasourceController.java | 107 +++ .../controller/GenTableColumnController.java | 93 ++ .../gen/controller/GenTableController.java | 167 ++++ .../xtools/app/gen/convert/GenConvert.java | 31 + .../app/gen/convert/GenDatasourceConvert.java | 57 ++ .../gen/convert/GenTableColumnConvert.java | 65 ++ .../app/gen/convert/GenTableConvert.java | 57 ++ .../xtools/app/gen/enums/FormTypeEnum.java | 118 +++ .../xtools/app/gen/enums/QueryTypeEnum.java | 128 +++ .../app/gen/mapper/GenDatasourceMapper.java | 20 + .../app/gen/mapper/GenTableColumnMapper.java | 20 + .../xtools/app/gen/mapper/GenTableMapper.java | 20 + .../xtools/app/gen/model/dto/GenCodeDto.java | 43 + .../model/dto/req/GenDatasourceAddReq.java | 83 ++ .../model/dto/req/GenDatasourcePageReq.java | 102 ++ .../model/dto/req/GenDatasourceUpdateReq.java | 89 ++ .../app/gen/model/dto/req/GenTableAddReq.java | 107 +++ .../model/dto/req/GenTableColumnAddReq.java | 155 ++++ .../model/dto/req/GenTableColumnPageReq.java | 174 ++++ .../dto/req/GenTableColumnUpdateReq.java | 161 ++++ .../gen/model/dto/req/GenTableInfoReq.java | 32 + .../gen/model/dto/req/GenTablePageReq.java | 127 +++ .../gen/model/dto/req/GenTableUpdateReq.java | 114 +++ .../gen/model/dto/resp/GenDatasourceResp.java | 93 ++ .../model/dto/resp/GenTableColumnResp.java | 162 ++++ .../gen/model/dto/resp/GenTableInfoResp.java | 32 + .../app/gen/model/dto/resp/GenTableResp.java | 115 +++ .../app/gen/model/entity/GenDatasource.java | 106 +++ .../xtools/app/gen/model/entity/GenTable.java | 134 +++ .../app/gen/model/entity/GenTableColumn.java | 190 ++++ .../app/gen/service/GenDatasourceService.java | 66 ++ .../xtools/app/gen/service/GenService.java | 111 +++ .../gen/service/GenTableColumnService.java | 81 ++ .../app/gen/service/GenTableService.java | 73 ++ .../base/GenDatasourceBaseService.java | 21 + .../gen/service/base/GenTableBaseService.java | 21 + .../base/GenTableColumnBaseService.java | 21 + .../impl/GenDatasourceServiceImpl.java | 201 ++++ .../app/gen/service/impl/GenServiceImpl.java | 778 ++++++++++++++++ .../impl/GenTableColumnServiceImpl.java | 216 +++++ .../gen/service/impl/GenTableServiceImpl.java | 202 ++++ .../xtools/app/gen/utils/DatasourceUtils.java | 50 + .../java/xtools/app/gen/utils/GenUtils.java | 102 ++ .../resources/templates/gen/api/api.java.vm | 14 + .../resources/templates/gen/call/call.java.vm | 18 + .../gen/controller/controller.java.vm | 137 +++ .../templates/gen/convert/convert.java.vm | 78 ++ .../templates/gen/mapper/mapper.java.vm | 20 + .../templates/gen/model/dto/addReq.java.vm | 41 + .../templates/gen/model/dto/excel.java.vm | 39 + .../templates/gen/model/dto/pageReq.java.vm | 53 ++ .../templates/gen/model/dto/resp.java.vm | 48 + .../templates/gen/model/dto/updateReq.java.vm | 41 + .../templates/gen/model/entity/entity.java.vm | 51 + .../templates/gen/service/service.java.vm | 91 ++ .../templates/gen/service/serviceBase.java.vm | 20 + .../templates/gen/service/serviceImpl.java.vm | 255 +++++ .../resources/templates/gen/sql/db.sql.vm | 27 + .../main/resources/templates/gen/ts/api.ts.vm | 142 +++ .../resources/templates/gen/vue/index.vue.vm | 687 ++++++++++++++ xtools-app-gen/xtools-app-gen-boot/Dockerfile | 10 + xtools-app-gen/xtools-app-gen-boot/pom.xml | 65 ++ .../main/java/xtools/app/GenApplication.java | 45 + .../main/resources/application-app-gen.yml | 82 ++ .../src/main/resources/application-nacos.yml | 45 + .../src/main/resources/application.yml | 17 + xtools-app-monitor/pom.xml | 20 + .../xtools-app-monitor-boot/Dockerfile | 10 + .../xtools-app-monitor-boot/pom.xml | 60 ++ .../java/xtools/app/MonitorApplication.java | 48 + .../monitor/boot/config/SecurityConfig.java | 77 ++ .../resources/application-app-monitor.yaml | 9 + .../src/main/resources/application-info.yml | 15 + .../src/main/resources/application-nacos.yml | 35 + .../src/main/resources/application.yml | 16 + .../xtools-app-monitor-client/pom.xml | 37 + .../config/BootAdminFilterWhitelist.java | 33 + .../config/BootAdminSecurityConfig.java | 43 + .../src/main/resources/application-info.yml | 15 + xtools-app-standalone/Dockerfile | 10 + xtools-app-standalone/pom.xml | 63 ++ .../xtools/app/StandaloneApplication.java | 46 + .../main/resources/application-app-gen.yml | 82 ++ .../main/resources/application-app-sys.yaml | 10 + .../main/resources/application-boot-base.yaml | 10 + .../main/resources/application-boot-db.yaml | 41 + .../resources/application-boot-druid.yaml | 35 + .../application-boot-elasticsearch.yaml | 9 + .../resources/application-boot-knife4j.yaml | 22 + .../main/resources/application-boot-log.yaml | 4 + .../resources/application-boot-monitor.yaml | 38 + .../application-boot-mybatis-plus.yaml | 8 + .../resources/application-boot-rabbitmq.yaml | 13 + .../resources/application-boot-redis.yaml | 26 + .../resources/application-boot-storage.yaml | 18 + .../resources/application-boot-xxl-job.yaml | 26 + .../resources/application-cloud-sentinel.yaml | 14 + .../resources/application-customizer-api.yaml | 6 + .../resources/application-customizer-log.yaml | 22 + .../src/main/resources/application.yml | 32 + xtools-app-sys/pom.xml | 29 + xtools-app-sys/xtools-app-sys-api/pom.xml | 29 + .../xtools/app/sys/api/SysAddressApi.java | 28 + .../xtools/app/sys/api/SysDictItemApi.java | 32 + .../java/xtools/app/sys/api/SysFileApi.java | 83 ++ .../java/xtools/app/sys/api/SysParamApi.java | 35 + .../java/xtools/app/sys/api/SysRiskApi.java | 61 ++ .../xtools/app/sys/enums/SysRiskType.java | 76 ++ .../app/sys/model/dto/req/SysFileAddReq.java | 129 +++ .../sys/model/dto/req/SysFileChangeReq.java | 42 + .../sys/model/dto/req/SysFileUpdateReq.java | 135 +++ .../app/sys/model/dto/req/SysParamAddReq.java | 52 ++ .../sys/model/dto/req/SysParamUpdateReq.java | 58 ++ .../sys/model/dto/resp/SysAddressResp.java | 73 ++ .../sys/model/dto/resp/SysDictItemResp.java | 94 ++ .../app/sys/model/dto/resp/SysFileResp.java | 138 +++ .../app/sys/model/dto/resp/SysRiskResp.java | 67 ++ xtools-app-sys/xtools-app-sys-auth/pom.xml | 71 ++ .../app/sys/auth/filter/AuthFilter.java | 235 +++++ .../app/sys/auth/holder/AuthHolder.java | 45 + .../sys/auth/model/dto/InterfacePermDto.java | 36 + .../app/sys/auth/model/dto/LoginUserDto.java | 51 + .../app/sys/auth/model/dto/TokenDto.java | 39 + .../xtools/app/sys/auth/utils/AuthUtils.java | 327 +++++++ .../xtools/app/sys/auth/utils/PremUtils.java | 125 +++ .../app/sys/auth/whitelist/AuthWhitelist.java | 36 + xtools-app-sys/xtools-app-sys-biz/pom.xml | 186 ++++ .../java/xtools/app/sys/config/ApiConfig.java | 42 + .../app/sys/config/SysAuthWhitelist.java | 47 + .../java/xtools/app/sys/config/SysConfig.java | 62 ++ .../app/sys/config/SysHttpLogWhitelist.java | 34 + .../app/sys/config/SysLogMySqlConfig.java | 43 + .../sys/controller/SysAddressController.java | 45 + .../app/sys/controller/SysBaseController.java | 130 +++ .../sys/controller/SysCommonController.java | 45 + .../app/sys/controller/SysDeptController.java | 96 ++ .../app/sys/controller/SysDictController.java | 123 +++ .../sys/controller/SysDictItemController.java | 136 +++ .../app/sys/controller/SysFileController.java | 116 +++ .../app/sys/controller/SysHomeController.java | 58 ++ .../app/sys/controller/SysJarController.java | 36 + .../app/sys/controller/SysLogController.java | 67 ++ .../sys/controller/SysLoginController.java | 70 ++ .../app/sys/controller/SysMenuController.java | 97 ++ .../sys/controller/SysMonitorController.java | 92 ++ .../sys/controller/SysNoticeController.java | 141 +++ .../sys/controller/SysParamController.java | 126 +++ .../app/sys/controller/SysRiskController.java | 229 +++++ .../app/sys/controller/SysRoleController.java | 88 ++ .../sys/controller/SysRoleMenuController.java | 68 ++ .../app/sys/controller/SysTaskController.java | 41 + .../SysUpdateHistoryController.java | 90 ++ .../app/sys/controller/SysUserController.java | 88 ++ .../controller/SysUserNoticeController.java | 57 ++ .../SysUserNoticeInfoController.java | 70 ++ .../app/sys/convert/SysAddressConvert.java | 27 + .../app/sys/convert/SysBaseConvert.java | 27 + .../app/sys/convert/SysDeptConvert.java | 64 ++ .../app/sys/convert/SysDictConvert.java | 74 ++ .../app/sys/convert/SysDictItemConvert.java | 74 ++ .../app/sys/convert/SysFileConvert.java | 55 ++ .../xtools/app/sys/convert/SysLogConvert.java | 37 + .../app/sys/convert/SysLoginConvert.java | 27 + .../app/sys/convert/SysMenuConvert.java | 64 ++ .../app/sys/convert/SysNoticeConvert.java | 55 ++ .../app/sys/convert/SysParamConvert.java | 74 ++ .../app/sys/convert/SysRiskConvert.java | 72 ++ .../app/sys/convert/SysRoleConvert.java | 55 ++ .../app/sys/convert/SysRoleMenuConvert.java | 17 + .../app/sys/convert/SysTaskConvert.java | 37 + .../sys/convert/SysUpdateHistoryConvert.java | 64 ++ .../app/sys/convert/SysUserConvert.java | 63 ++ .../app/sys/convert/SysUserNoticeConvert.java | 55 ++ .../sys/convert/SysUserNoticeInfoConvert.java | 17 + .../app/sys/convert/SysUserRoleConvert.java | 17 + .../java/xtools/app/sys/init/InitSys.java | 68 ++ .../java/xtools/app/sys/job/SysFileJob.java | 35 + .../java/xtools/app/sys/job/SysLogJob.java | 83 ++ .../app/sys/mapper/SysAddressMapper.java | 19 + .../xtools/app/sys/mapper/SysDeptMapper.java | 19 + .../app/sys/mapper/SysDictItemMapper.java | 19 + .../xtools/app/sys/mapper/SysDictMapper.java | 19 + .../xtools/app/sys/mapper/SysFileMapper.java | 19 + .../xtools/app/sys/mapper/SysLogMapper.java | 19 + .../xtools/app/sys/mapper/SysMenuMapper.java | 46 + .../app/sys/mapper/SysNoticeMapper.java | 19 + .../xtools/app/sys/mapper/SysParamMapper.java | 19 + .../xtools/app/sys/mapper/SysRiskMapper.java | 40 + .../xtools/app/sys/mapper/SysRoleMapper.java | 19 + .../app/sys/mapper/SysRoleMenuMapper.java | 19 + .../xtools/app/sys/mapper/SysTaskMapper.java | 19 + .../sys/mapper/SysUpdateHistoryMapper.java | 19 + .../xtools/app/sys/mapper/SysUserMapper.java | 19 + .../sys/mapper/SysUserNoticeInfoMapper.java | 38 + .../app/sys/mapper/SysUserNoticeMapper.java | 36 + .../app/sys/mapper/SysUserRoleMapper.java | 19 + .../xtools/app/sys/model/dto/Sm2KeyDto.java | 34 + .../app/sys/model/dto/excel/SysDictExcel.java | 47 + .../sys/model/dto/excel/SysDictItemExcel.java | 68 ++ .../sys/model/dto/excel/SysParamExcel.java | 48 + .../app/sys/model/dto/excel/SysRiskExcel.java | 66 ++ .../app/sys/model/dto/req/IgnoreMaskReq.java | 48 + .../app/sys/model/dto/req/SysDeptAddReq.java | 77 ++ .../app/sys/model/dto/req/SysDeptPageReq.java | 96 ++ .../sys/model/dto/req/SysDeptUpdateReq.java | 83 ++ .../app/sys/model/dto/req/SysDictAddReq.java | 59 ++ .../sys/model/dto/req/SysDictItemAddReq.java | 77 ++ .../sys/model/dto/req/SysDictItemPageReq.java | 96 ++ .../model/dto/req/SysDictItemUpdateReq.java | 83 ++ .../app/sys/model/dto/req/SysDictPageReq.java | 78 ++ .../sys/model/dto/req/SysDictUpdateReq.java | 65 ++ .../app/sys/model/dto/req/SysFilePageReq.java | 144 +++ .../app/sys/model/dto/req/SysLogPageReq.java | 90 ++ .../app/sys/model/dto/req/SysLoginReq.java | 59 ++ .../app/sys/model/dto/req/SysMenuAddReq.java | 137 +++ .../app/sys/model/dto/req/SysMenuPageReq.java | 156 ++++ .../sys/model/dto/req/SysMenuTreesReq.java | 36 + .../sys/model/dto/req/SysMenuUpdateReq.java | 143 +++ .../sys/model/dto/req/SysNoticeAddReq.java | 101 ++ .../sys/model/dto/req/SysNoticePageReq.java | 126 +++ .../sys/model/dto/req/SysNoticeUpdateReq.java | 107 +++ .../sys/model/dto/req/SysParamPageReq.java | 78 ++ .../app/sys/model/dto/req/SysRiskAddReq.java | 48 + .../app/sys/model/dto/req/SysRiskPageReq.java | 78 ++ .../sys/model/dto/req/SysRiskUpdateReq.java | 54 ++ .../app/sys/model/dto/req/SysRoleAddReq.java | 72 ++ .../app/sys/model/dto/req/SysRoleMenuReq.java | 40 + .../app/sys/model/dto/req/SysRolePageReq.java | 90 ++ .../sys/model/dto/req/SysRoleUpdateReq.java | 77 ++ .../app/sys/model/dto/req/SysTaskPageReq.java | 90 ++ .../model/dto/req/SysUpdateHistoryAddReq.java | 53 ++ .../dto/req/SysUpdateHistoryPageReq.java | 72 ++ .../dto/req/SysUpdateHistoryUpdateReq.java | 59 ++ .../app/sys/model/dto/req/SysUserAddReq.java | 95 ++ .../model/dto/req/SysUserNoticeAddReq.java | 61 ++ .../dto/req/SysUserNoticeInfoPageReq.java | 61 ++ .../model/dto/req/SysUserNoticePageReq.java | 90 ++ .../model/dto/req/SysUserNoticeUpdateReq.java | 67 ++ .../app/sys/model/dto/req/SysUserPageReq.java | 114 +++ .../sys/model/dto/req/SysUserUpdateReq.java | 101 ++ .../sys/model/dto/req/UserInfoEditReq.java | 68 ++ .../model/dto/req/UserInfoPasswdEditReq.java | 55 ++ .../model/dto/resp/SysBaseUserInfoResp.java | 50 + .../app/sys/model/dto/resp/SysDeptResp.java | 94 ++ .../sys/model/dto/resp/SysDeptTreeResp.java | 33 + .../app/sys/model/dto/resp/SysDictResp.java | 73 ++ .../sys/model/dto/resp/SysHomeDataResp.java | 45 + .../app/sys/model/dto/resp/SysIpAddrResp.java | 49 + .../app/sys/model/dto/resp/SysLogResp.java | 138 +++ .../app/sys/model/dto/resp/SysMenuResp.java | 144 +++ .../sys/model/dto/resp/SysMenuTreeResp.java | 33 + .../app/sys/model/dto/resp/SysNoticeResp.java | 128 +++ .../app/sys/model/dto/resp/SysParamResp.java | 69 ++ .../app/sys/model/dto/resp/SysRoleResp.java | 89 ++ .../app/sys/model/dto/resp/SysTaskResp.java | 80 ++ .../model/dto/resp/SysUpdateHistoryResp.java | 60 ++ .../model/dto/resp/SysUserNoticeInfoResp.java | 70 ++ .../sys/model/dto/resp/SysUserNoticeResp.java | 82 ++ .../app/sys/model/dto/resp/SysUserResp.java | 123 +++ .../app/sys/model/entity/SysAddress.java | 86 ++ .../xtools/app/sys/model/entity/SysDept.java | 99 ++ .../xtools/app/sys/model/entity/SysDict.java | 78 ++ .../app/sys/model/entity/SysDictItem.java | 99 ++ .../xtools/app/sys/model/entity/SysFile.java | 158 ++++ .../sys/model/entity/SysInterfacePerm.java | 34 + .../xtools/app/sys/model/entity/SysLog.java | 162 ++++ .../xtools/app/sys/model/entity/SysMenu.java | 169 ++++ .../app/sys/model/entity/SysNotice.java | 137 +++ .../xtools/app/sys/model/entity/SysParam.java | 79 ++ .../xtools/app/sys/model/entity/SysRisk.java | 79 ++ .../xtools/app/sys/model/entity/SysRole.java | 92 ++ .../app/sys/model/entity/SysRoleMenu.java | 57 ++ .../xtools/app/sys/model/entity/SysTask.java | 94 ++ .../sys/model/entity/SysUpdateHistory.java | 71 ++ .../xtools/app/sys/model/entity/SysUser.java | 120 +++ .../app/sys/model/entity/SysUserNotice.java | 81 ++ .../sys/model/entity/SysUserNoticeInfo.java | 88 ++ .../app/sys/model/entity/SysUserRole.java | 57 ++ .../main/java/xtools/app/sys/mq/SysLogMq.java | 67 ++ .../java/xtools/app/sys/mq/SysTaskMq.java | 67 ++ .../app/sys/service/SysAddressService.java | 16 + .../app/sys/service/SysBaseService.java | 69 ++ .../app/sys/service/SysCommonService.java | 25 + .../app/sys/service/SysDeptService.java | 81 ++ .../app/sys/service/SysDictItemService.java | 89 ++ .../app/sys/service/SysDictService.java | 79 ++ .../app/sys/service/SysFileService.java | 34 + .../app/sys/service/SysHomeService.java | 26 + .../xtools/app/sys/service/SysLogService.java | 64 ++ .../app/sys/service/SysLoginService.java | 36 + .../app/sys/service/SysMenuService.java | 116 +++ .../app/sys/service/SysMonitorService.java | 45 + .../app/sys/service/SysNoticeService.java | 79 ++ .../app/sys/service/SysParamService.java | 69 ++ .../app/sys/service/SysPermService.java | 20 + .../app/sys/service/SysRiskService.java | 116 +++ .../app/sys/service/SysRoleMenuService.java | 35 + .../app/sys/service/SysRoleService.java | 71 ++ .../app/sys/service/SysTaskService.java | 36 + .../sys/service/SysUpdateHistoryService.java | 85 ++ .../sys/service/SysUserNoticeInfoService.java | 52 ++ .../app/sys/service/SysUserNoticeService.java | 65 ++ .../app/sys/service/SysUserRoleService.java | 15 + .../app/sys/service/SysUserService.java | 90 ++ .../service/base/SysAddressBaseService.java | 19 + .../sys/service/base/SysDeptBaseService.java | 67 ++ .../sys/service/base/SysDictBaseService.java | 34 + .../service/base/SysDictItemBaseService.java | 19 + .../sys/service/base/SysFileBaseService.java | 19 + .../sys/service/base/SysLogBaseService.java | 19 + .../sys/service/base/SysMenuBaseService.java | 56 ++ .../service/base/SysNoticeBaseService.java | 19 + .../sys/service/base/SysParamBaseService.java | 19 + .../sys/service/base/SysRiskBaseService.java | 20 + .../sys/service/base/SysRoleBaseService.java | 19 + .../service/base/SysRoleMenuBaseService.java | 61 ++ .../sys/service/base/SysTaskBaseService.java | 19 + .../base/SysUpdateHistoryBaseService.java | 19 + .../sys/service/base/SysUserBaseService.java | 42 + .../base/SysUserNoticeBaseService.java | 19 + .../base/SysUserNoticeInfoBaseService.java | 19 + .../service/base/SysUserRoleBaseService.java | 84 ++ .../sys/service/impl/LogBusServiceImpl.java | 93 ++ .../service/impl/SysAddressServiceImpl.java | 85 ++ .../sys/service/impl/SysBaseServiceImpl.java | 177 ++++ .../service/impl/SysCommonServiceImpl.java | 54 ++ .../sys/service/impl/SysDeptServiceImpl.java | 359 +++++++ .../service/impl/SysDictItemServiceImpl.java | 298 ++++++ .../sys/service/impl/SysDictServiceImpl.java | 266 ++++++ .../sys/service/impl/SysFileServiceImpl.java | 375 ++++++++ .../sys/service/impl/SysHomeServiceImpl.java | 134 +++ .../sys/service/impl/SysLogServiceImpl.java | 198 ++++ .../sys/service/impl/SysLoginServiceImpl.java | 182 ++++ .../sys/service/impl/SysMenuServiceImpl.java | 466 ++++++++++ .../service/impl/SysMonitorServiceImpl.java | 72 ++ .../service/impl/SysNoticeServiceImpl.java | 367 ++++++++ .../sys/service/impl/SysParamServiceImpl.java | 412 +++++++++ .../sys/service/impl/SysPermServiceImpl.java | 100 ++ .../sys/service/impl/SysRiskServiceImpl.java | 428 +++++++++ .../service/impl/SysRoleMenuServiceImpl.java | 81 ++ .../sys/service/impl/SysRoleServiceImpl.java | 231 +++++ .../sys/service/impl/SysTaskServiceImpl.java | 213 +++++ .../impl/SysUpdateHistoryServiceImpl.java | 278 ++++++ .../impl/SysUserNoticeInfoServiceImpl.java | 153 +++ .../impl/SysUserNoticeServiceImpl.java | 225 +++++ .../service/impl/SysUserRoleServiceImpl.java | 21 + .../sys/service/impl/SysUserServiceImpl.java | 306 ++++++ .../xtools/app/sys/utils/PasswdUtils.java | 66 ++ .../main/resources/mapper/SysMenuMapper.xml | 65 ++ .../main/resources/mapper/SysRiskMapper.xml | 20 + .../mapper/SysUserNoticeInfoMapper.xml | 44 + .../resources/mapper/SysUserNoticeMapper.xml | 45 + xtools-app-sys/xtools-app-sys-boot/Dockerfile | 10 + xtools-app-sys/xtools-app-sys-boot/pom.xml | 84 ++ .../main/java/xtools/app/SysApplication.java | 45 + .../src/main/resources/application-nacos.yml | 50 + .../src/main/resources/application.yml | 16 + xtools-app-sys/xtools-app-sys-call/pom.xml | 36 + .../xtools/app/sys/call/SysAddressCall.java | 32 + .../xtools/app/sys/call/SysDictItemCall.java | 35 + .../java/xtools/app/sys/call/SysFileCall.java | 98 ++ .../xtools/app/sys/call/SysParamCall.java | 47 + .../java/xtools/app/sys/call/SysRiskCall.java | 73 ++ .../app/sys/config/SysHttpServiceConfig.java | 21 + .../xtools-app-sys-file-web/pom.xml | 31 + .../controller/SysCommonFileController.java | 76 ++ xtools-app-sys/xtools-app-sys-file/pom.xml | 49 + .../app/sys/file/enums/FileBizBaseEnum.java | 46 + .../app/sys/file/enums/FileBizEnum.java | 138 +++ .../sys/file/enums/FilePermissionType.java | 90 ++ .../file/service/SysFileDownloadCallback.java | 28 + .../sys/file/service/SysFileOptService.java | 142 +++ .../service/impl/SysFileOptServiceImpl.java | 353 +++++++ .../app/sys/file/utils/FileIdUtils.java | 82 ++ .../pom.xml | 31 + .../config/SysLogElasticsearchConfig.java | 44 + .../convert/SysLogElasticsearchConvert.java | 27 + .../log/bus/elasticsearch/dto/EsSysLog.java | 143 +++ .../service/base/EsSysLogRepository.java | 20 + .../service/impl/EsSysLogServiceImpl.java | 307 ++++++ xtools-app-sys/xtools-app-sys-param/pom.xml | 43 + .../app/sys/param/dto/SysBlacklistDto.java | 32 + .../app/sys/param/dto/UpdateHistoryDto.java | 40 + .../app/sys/param/enums/SysParamBaseEnum.java | 25 + .../app/sys/param/enums/SysParamDataType.java | 75 ++ .../app/sys/param/enums/SysParamEnum.java | 89 ++ .../app/sys/param/utils/SysParamUtils.java | 244 +++++ xtools-app-sys/xtools-app-sys-risk/pom.xml | 36 + .../main/java/xtools/app/sys/risk/IpRisk.java | 86 ++ .../java/xtools/app/sys/risk/UriRisk.java | 77 ++ .../app/sys/risk/enums/SysRiskBaseEnum.java | 32 + .../app/sys/risk/enums/SysRiskEnum.java | 106 +++ .../app/sys/risk/utils/IpRiskUtils.java | 61 ++ .../app/sys/risk/utils/UriRiskUtils.java | 53 ++ .../xtools-app-sys-scheduled/pom.xml | 76 ++ .../controller/SysScheduledController.java | 171 ++++ .../convert/SysScheduledConvert.java | 74 ++ .../sys/scheduled/init/InitSysScheduled.java | 53 ++ .../scheduled/mapper/SysScheduledMapper.java | 19 + .../model/dto/excel/SysScheduledExcel.java | 54 ++ .../model/dto/req/SysScheduledAddReq.java | 53 ++ .../model/dto/req/SysScheduledPageReq.java | 72 ++ .../model/dto/req/SysScheduledUpdateReq.java | 60 ++ .../model/dto/resp/SysScheduledResp.java | 66 ++ .../scheduled/model/entity/SysScheduled.java | 71 ++ .../service/SysScheduledService.java | 113 +++ .../service/base/SysScheduledBaseService.java | 19 + .../service/impl/SysScheduledServiceImpl.java | 389 ++++++++ .../sys/scheduled/utils/ScheduledUtils.java | 112 +++ 443 files changed, 36365 insertions(+), 19 deletions(-) create mode 100644 pom.xml create mode 100644 xtools-app-common/pom.xml create mode 100644 xtools-app-common/xtools-app-common-cache/pom.xml create mode 100644 xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/aop/RedisServiceAop.java create mode 100644 xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/enums/AppCache.java create mode 100644 xtools-app-common/xtools-app-common-call/pom.xml create mode 100644 xtools-app-common/xtools-app-common-call/src/main/java/xtools/app/common/call/SysCallInterceptor.java create mode 100644 xtools-app-common/xtools-app-common-jar/pom.xml create mode 100644 xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/init/InitJar.java create mode 100644 xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/utils/RunJarUtils.java create mode 100644 xtools-app-common/xtools-app-common-job/pom.xml create mode 100644 xtools-app-common/xtools-app-common-job/src/main/java/xtools/app/common/job/base/BaseJob.java create mode 100644 xtools-app-common/xtools-app-common-log/pom.xml create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/pom.xml create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/enums/SysLogType.java create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/handle/LogBusHandle.java create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/service/LogBusService.java create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/pom.xml create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/filter/HttpLogFilter.java create mode 100644 xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/whitelist/HttpLogWhitelist.java create mode 100644 xtools-app-common/xtools-app-common-mq/pom.xml create mode 100644 xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/enums/RabbitMqEnums.java create mode 100644 xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/handle/MqErrorHandle.java create mode 100644 xtools-app-common/xtools-app-common-sentinel/pom.xml create mode 100644 xtools-app-common/xtools-app-common-sentinel/src/main/java/xtools/app/common/sentinel/SysBlockExceptionHandler.java create mode 100644 xtools-app-common/xtools-app-common-task/pom.xml create mode 100644 xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/enums/TaskType.java create mode 100644 xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/handle/TaskBusHandle.java create mode 100644 xtools-app-gen/pom.xml create mode 100644 xtools-app-gen/xtools-app-gen-biz/pom.xml create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/GenProperties.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/VelocityConfig.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenDatasourceController.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableColumnController.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableController.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenConvert.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenDatasourceConvert.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableColumnConvert.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableConvert.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/FormTypeEnum.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/QueryTypeEnum.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenDatasourceMapper.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableColumnMapper.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableMapper.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/GenCodeDto.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceAddReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourcePageReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceUpdateReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableAddReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnAddReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnPageReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnUpdateReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableInfoReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTablePageReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableUpdateReq.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenDatasourceResp.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableColumnResp.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableInfoResp.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableResp.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenDatasource.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTable.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTableColumn.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenDatasourceService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableColumnService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenDatasourceBaseService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableBaseService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableColumnBaseService.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenDatasourceServiceImpl.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenServiceImpl.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableColumnServiceImpl.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableServiceImpl.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/DatasourceUtils.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/GenUtils.java create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/api/api.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/call/call.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/controller/controller.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/convert/convert.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/mapper/mapper.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/addReq.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/excel.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/pageReq.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/resp.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/updateReq.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/entity/entity.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/service.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceBase.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceImpl.java.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/sql/db.sql.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/ts/api.ts.vm create mode 100644 xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/vue/index.vue.vm create mode 100644 xtools-app-gen/xtools-app-gen-boot/Dockerfile create mode 100644 xtools-app-gen/xtools-app-gen-boot/pom.xml create mode 100644 xtools-app-gen/xtools-app-gen-boot/src/main/java/xtools/app/GenApplication.java create mode 100644 xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-app-gen.yml create mode 100644 xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-nacos.yml create mode 100644 xtools-app-gen/xtools-app-gen-boot/src/main/resources/application.yml create mode 100644 xtools-app-monitor/pom.xml create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/Dockerfile create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/pom.xml create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/MonitorApplication.java create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/monitor/boot/config/SecurityConfig.java create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-app-monitor.yaml create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-info.yml create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-nacos.yml create mode 100644 xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application.yml create mode 100644 xtools-app-monitor/xtools-app-monitor-client/pom.xml create mode 100644 xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminFilterWhitelist.java create mode 100644 xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminSecurityConfig.java create mode 100644 xtools-app-monitor/xtools-app-monitor-client/src/main/resources/application-info.yml create mode 100644 xtools-app-standalone/Dockerfile create mode 100644 xtools-app-standalone/pom.xml create mode 100644 xtools-app-standalone/src/main/java/xtools/app/StandaloneApplication.java create mode 100644 xtools-app-standalone/src/main/resources/application-app-gen.yml create mode 100644 xtools-app-standalone/src/main/resources/application-app-sys.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-base.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-db.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-druid.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-elasticsearch.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-knife4j.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-log.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-monitor.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-mybatis-plus.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-rabbitmq.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-redis.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-storage.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-boot-xxl-job.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-cloud-sentinel.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-customizer-api.yaml create mode 100644 xtools-app-standalone/src/main/resources/application-customizer-log.yaml create mode 100644 xtools-app-standalone/src/main/resources/application.yml create mode 100644 xtools-app-sys/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-api/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysAddressApi.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysDictItemApi.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysFileApi.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysParamApi.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysRiskApi.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/enums/SysRiskType.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileChangeReq.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysAddressResp.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysDictItemResp.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysFileResp.java create mode 100644 xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysRiskResp.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/filter/AuthFilter.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/holder/AuthHolder.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/InterfacePermDto.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/LoginUserDto.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/TokenDto.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/AuthUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/PremUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/whitelist/AuthWhitelist.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/ApiConfig.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysAuthWhitelist.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysConfig.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysHttpLogWhitelist.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysLogMySqlConfig.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysAddressController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysBaseController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysCommonController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDeptController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictItemController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysFileController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysHomeController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysJarController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLogController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLoginController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMenuController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMonitorController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysNoticeController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysParamController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRiskController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleMenuController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysTaskController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUpdateHistoryController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeInfoController.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysAddressConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysBaseConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDeptConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictItemConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysFileConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLogConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLoginConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysMenuConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysNoticeConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysParamConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRiskConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleMenuConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysTaskConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUpdateHistoryConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeInfoConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserRoleConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/init/InitSys.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysFileJob.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysLogJob.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysAddressMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDeptMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictItemMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysFileMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysLogMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysMenuMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysNoticeMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysParamMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRiskMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMenuMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysTaskMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUpdateHistoryMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeInfoMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserRoleMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/Sm2KeyDto.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictExcel.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictItemExcel.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysParamExcel.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysRiskExcel.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/IgnoreMaskReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysFilePageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLogPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLoginReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuTreesReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticePageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysParamPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleMenuReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRolePageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysTaskPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeInfoPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticePageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoEditReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoPasswdEditReq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysBaseUserInfoResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptTreeResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDictResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysHomeDataResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysIpAddrResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysLogResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuTreeResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysNoticeResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysParamResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysRoleResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysTaskResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUpdateHistoryResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeInfoResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserResp.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysAddress.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDept.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDict.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDictItem.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysFile.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysInterfacePerm.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysLog.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysMenu.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysNotice.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysParam.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRisk.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRole.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRoleMenu.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysTask.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUpdateHistory.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUser.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNotice.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNoticeInfo.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserRole.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysLogMq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysTaskMq.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysAddressService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysCommonService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDeptService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictItemService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysFileService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysHomeService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLogService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLoginService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMenuService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMonitorService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysNoticeService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysParamService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysPermService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRiskService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleMenuService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysTaskService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUpdateHistoryService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeInfoService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserRoleService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysAddressBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDeptBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictItemBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysFileBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysLogBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysMenuBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysNoticeBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysParamBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRiskBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleMenuBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysTaskBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUpdateHistoryBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeInfoBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserRoleBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/LogBusServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysAddressServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysBaseServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysCommonServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDeptServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictItemServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysFileServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysHomeServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLogServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLoginServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMenuServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMonitorServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysNoticeServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysParamServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysPermServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRiskServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleMenuServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysTaskServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUpdateHistoryServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeInfoServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserRoleServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/utils/PasswdUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysMenuMapper.xml create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysRiskMapper.xml create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeInfoMapper.xml create mode 100644 xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeMapper.xml create mode 100644 xtools-app-sys/xtools-app-sys-boot/Dockerfile create mode 100644 xtools-app-sys/xtools-app-sys-boot/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-boot/src/main/java/xtools/app/SysApplication.java create mode 100644 xtools-app-sys/xtools-app-sys-boot/src/main/resources/application-nacos.yml create mode 100644 xtools-app-sys/xtools-app-sys-boot/src/main/resources/application.yml create mode 100644 xtools-app-sys/xtools-app-sys-call/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysAddressCall.java create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysDictItemCall.java create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysFileCall.java create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysParamCall.java create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysRiskCall.java create mode 100644 xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/config/SysHttpServiceConfig.java create mode 100644 xtools-app-sys/xtools-app-sys-file-web/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-file-web/src/main/java/xtools/app/sys/file/web/controller/SysCommonFileController.java create mode 100644 xtools-app-sys/xtools-app-sys-file/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizBaseEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FilePermissionType.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileDownloadCallback.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileOptService.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/impl/SysFileOptServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/utils/FileIdUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/config/SysLogElasticsearchConfig.java create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/convert/SysLogElasticsearchConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/dto/EsSysLog.java create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/base/EsSysLogRepository.java create mode 100644 xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/impl/EsSysLogServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-param/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/SysBlacklistDto.java create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/UpdateHistoryDto.java create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamBaseEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamDataType.java create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/utils/SysParamUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/IpRisk.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/UriRisk.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskBaseEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskEnum.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/IpRiskUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/UriRiskUtils.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/pom.xml create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/controller/SysScheduledController.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/convert/SysScheduledConvert.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/init/InitSysScheduled.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/mapper/SysScheduledMapper.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/excel/SysScheduledExcel.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledAddReq.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledPageReq.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledUpdateReq.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/resp/SysScheduledResp.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/entity/SysScheduled.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/SysScheduledService.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/base/SysScheduledBaseService.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/impl/SysScheduledServiceImpl.java create mode 100644 xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/utils/ScheduledUtils.java diff --git a/.gitignore b/.gitignore index 26a62dc..df985dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,29 @@ -# ---> Actionscript -# Build and Release Folders -bin-debug/ -bin-release/ -[Oo]bj/ -[Bb]in/ +# ---> Project -# Other files and folders +# logs +**/logs/ + +# ai +.claude + +# ---> Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# ---> Eclipse .settings/ +.project +.classpath -# Executables -*.swf -*.air -*.ipa -*.apk - -# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` -# should NOT be excluded as they contain compiler settings and other important -# information for Eclipse / Flash Builder. - +# ---> Idea +.idea/ +*.iml \ No newline at end of file diff --git a/README.md b/README.md index 46fbb59..c06bf78 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,873 @@ -# xtools-app +# xtools-app 项目设计文档 -低调大师工具箱,基础应用模块,适配JDK25 \ No newline at end of file +## 一、功能和用途 + +### 1.1 项目概述 + +- **项目名称**:xtools-app +- **项目版本**:1.0.0 +- **父POM**:org.xujun:xtools-parent-cloud:5.0.0 +- **项目定位**:基础应用平台,提供企业级应用开发的核心功能和公共模块,支持单体部署和微服务部署两种模式 +- **组织**:org.xujun + +#### 1.2 技术特点 + +- 采用最新的 **JDK 25** 版本,充分利用新特性(ScopedValue、虚拟线程、Record等) +- 基于 **Spring Boot 4.0.5** 构建,支持自动配置和快速开发 +- 集成 **Spring Cloud 2025.1.1** 微服务框架 +- 使用 **Spring Cloud Alibaba 2025.1.0.0** 微服务组件 +- 使用 **MyBatis-Plus 3.5.16** 简化数据访问层开发(基于 MyBatis 4.0.1) +- 使用 **Spring Data Elasticsearch**(基于 Elasticsearch Client 9.2.6)实现日志存储和检索 +- 支持 **Nacos 3.1.1** 服务注册与发现、配置中心 +- 集成 **Sentinel 1.8.9** 实现流量控制和熔断降级 +- 使用 **Spring Data Redis**(基于 Lettuce 6.8.2)实现分布式缓存 +- 使用 **Spring AMQP 4.0.2**(RabbitMQ Client 5.27.1)实现异步消息处理 +- 支持 **Knife4j 4.5.0**(基于 SpringDoc OpenAPI 3.0.3)自动生成 API 文档 +- 使用 **Druid 1.2.28** 数据库连接池 +- 使用 **SM2/SM3** 国密算法保障密码和数据安全 + +### 1.3 核心功能 + +```mermaid +graph TB + subgraph 系统管理模块 + A1[用户管理
用户增删改查,角色分配,密码管理] + A2[角色管理
角色配置,权限分配,菜单分配] + A3[菜单管理
树形结构,动态加载,按钮权限] + A4[部门管理
树形结构,人员管理] + A5[字典管理
类型管理,字典项管理] + A6[日志管理
操作日志,登录日志,ES存储] + A7[通知管理
通知发布,用户通知,已读未读] + A8[任务管理
定时任务配置,任务监控] + A9[系统监控
服务器监控,JVM监控] + A10[JAR管理
JAR加载,JAR监控] + A11[文件管理
文件上传,S3存储] + A12[参数管理
系统参数配置] + A13[风控管理
IP限流,URI限流] + A14[地址管理
地址解析,IP归属] + end + + subgraph 代码生成模块 + B1[数据源管理
多数据源,连接测试] + B2[表结构管理
表查询,字段配置,同步] + B3[代码生成
参数配置,模板渲染,ZIP下载] + B4[代码预览
代码查看,多模板支持] + end + + subgraph 公共模块 + C1[缓存模块
Redis缓存,缓存枚举,AOP缓存] + C2[远程调用
OpenFeign,微服务通信] + C3[JAR管理
动态JAR加载,运行时扩展] + C4[日志总线
事件发布,MQ异步写入ES] + C5[日志过滤
请求拦截,操作日志采集] + C6[消息队列
RabbitMQ,异步处理,错误重试] + C7[任务调度
异步任务,定时任务,Redis分布式锁] + C8[限流模块
Sentinel集成,流量控制] + end + + subgraph 监控模块 + D1[监控服务端
Spring Boot Admin Server] + D2[监控客户端
Spring Boot Admin Client] + end +``` + +```mermaid +mindmap + root((xtools-app
基础应用平台)) + 系统管理 + 用户管理 + 增删改查 + 角色分配 + 密码管理 + 状态管理 + 角色管理 + 角色配置 + 权限分配 + 菜单分配 + 菜单管理 + 树形结构 + 动态加载 + 按钮权限 + 部门管理 + 树形结构 + 人员管理 + 字典管理 + 类型管理 + 字典项管理 + 日志管理 + 操作日志 + ES存储检索 + 通知管理 + 通知发布 + 用户通知 + 文件管理 + 本地上传 + S3存储 + 风控管理 + IP限流 + URI限流 + 代码生成 + 数据源管理 + 多数据源 + 连接测试 + 表结构管理 + 表同步 + 字段配置 + 代码生成 + Velocity模板 + ZIP下载 + 代码预览 + 多模板预览 + 公共模块 + 缓存管理 + Redis缓存 + 缓存枚举 + 远程调用 + OpenFeign + 日志处理 + 日志总线 + 日志过滤 + 消息队列 + RabbitMQ + 任务调度 + 异步任务 + 定时任务 +``` + +```mermaid +graph LR + User[用户] --> Login[登录认证] + User --> Menu[菜单访问] + User --> Data[数据操作] + + Login --> Auth[认证授权] + Auth --> Token[Token管理] + Auth --> Redis[Redis缓存] + + Menu --> Perm[权限验证] + Role[角色] --> Perm + + Data --> LogFilter[日志过滤器] + LogFilter --> LogBus[日志总线] + LogBus --> MQ[RabbitMQ] + MQ --> LogMq[日志消费者] + LogMq --> ES[Elasticsearch] + + Cache[Redis缓存] --> Data + + Gen[代码生成] --> DB[数据库] + Gen --> Velocity[Velocity模板] +``` + +## 二、项目结构设计 + +### 2.1 整体架构 + +```mermaid +graph TD + xtools-app[xtools-app
基础应用平台
v1.0.0] --> common[xtools-app-common
公共模块] + xtools-app --> sys[xtools-app-sys
系统管理模块] + xtools-app --> gen[xtools-app-gen
代码生成模块] + xtools-app --> monitor[xtools-app-monitor
监控模块] + xtools-app --> standalone[xtools-app-standalone
单体部署模块] + + common --> cache[common-cache
缓存模块] + common --> call[common-call
远程调用模块] + common --> jar[common-jar
JAR管理模块] + common --> job[common-job
任务调度模块] + common --> log[common-log
日志模块] + common --> mq[common-mq
消息队列模块] + common --> sentinel[common-sentinel
限流模块] + common --> task[common-task
异步任务模块] + + log --> log-bus[log-bus
日志总线] + log --> log-filter[log-filter
日志过滤器] + + sys --> sys-api[sys-api
系统API接口] + sys --> sys-auth[sys-auth
认证授权] + sys --> sys-biz[sys-biz
系统业务逻辑] + sys --> sys-boot[sys-boot
系统微服务启动] + sys --> sys-call[sys-call
系统远程调用] + sys --> sys-file[sys-file
文件管理] + sys --> sys-file-web[sys-file-web
文件Web服务] + sys --> sys-log-es[sys-log-bus-elasticsearch
日志ES存储] + sys --> sys-param[sys-param
系统参数] + sys --> sys-scheduled[sys-scheduled
定时任务] + sys --> sys-risk[sys-risk
风控管理] + + gen --> gen-biz[gen-biz
代码生成业务] + gen --> gen-boot[gen-boot
代码生成微服务启动] + + monitor --> monitor-boot[monitor-boot
监控服务端] + monitor --> monitor-client[monitor-client
监控客户端] +``` + +### 2.2 分层架构 + +```mermaid +flowchart TB + subgraph Controller层 + A1[接收HTTP请求] + A2[参数验证
Valid] + A3[调用Service层] + A4[返回统一响应
Result] + end + + subgraph Service层 + B1[业务逻辑处理] + B2[事务控制
Transactional] + B3[调用Mapper层] + B4[缓存操作
Redis] + end + + subgraph Mapper层 + C1[MyBatis-Plus
BaseMapper] + C2[数据库访问] + C3[SQL执行] + end + + subgraph 横切关注点 + D1[AuthFilter
认证过滤器] + D2[LogBus
日志总线] + D3[Sentinel
流量控制] + D4[MqErrorHandle
消息错误处理] + end + + A1 --> A2 --> A3 --> B1 + B1 --> B2 --> B3 --> C1 + C1 --> C2 --> C3 + + A1 -.-> D1 + A1 -.-> D2 + A1 -.-> D3 + B1 -.-> D4 +``` + +### 2.3 模块职责 + +| 层级 | 模块 | 职责说明 | +|------|------|----------| +| **Controller层** | SysUserController、SysLoginController等 | 接收HTTP请求、参数验证(@Valid)、调用Service层、返回统一响应(Result) | +| **Service层** | SysUserServiceImpl、SysLoginServiceImpl等 | 实现业务逻辑、事务控制(@Transactional)、调用Mapper层、缓存操作 | +| **BaseService层** | SysUserBaseService等 | 继承MyBatis-Plus ServiceImpl,提供基础CRUD操作 | +| **Mapper层** | SysUserMapper、SysRoleMapper等 | 继承MyBatis-Plus BaseMapper,数据库访问、SQL执行 | +| **Entity层** | SysUser、SysRole、SysMenu等 | 数据库实体映射 | +| **DTO层** | Req(请求)、Resp(响应)、Excel | 数据传输对象 | +| **Convert层** | SysUserConvert、SysRoleConvert等 | MapStruct对象转换 | +| **Config层** | SysConfig、ApiConfig等 | 配置类 | +| **MQ层** | SysLogMq、SysTaskMq等 | 消息队列消费者 | +| **Job层** | BaseJob、SysLogJob等 | 定时任务、异步任务 | +| **Utils层** | PasswdUtils、AuthUtils等 | 工具类 | + +### 2.4 包结构设计 + +``` +xtools.app.{module} +├── controller # 控制器层 +├── service # 服务接口 +│ ├── base # 基础服务(继承ServiceImpl) +│ └── impl # 服务实现 +├── mapper # 数据访问层 +├── model +│ ├── entity # 实体类 +│ ├── dto +│ │ ├── req # 请求DTO(AddReq、UpdateReq、PageReq) +│ │ ├── resp # 响应DTO +│ │ └── excel # Excel导入导出DTO +│ └── vo # 视图对象 +├── convert # MapStruct转换器 +├── config # 配置类 +├── utils # 工具类 +├── mq # 消息队列处理 +├── job # 定时任务 +└── es # Elasticsearch相关 +``` + +### 2.5 启动模块 + +项目支持两种部署模式: + +| 模块 | 说明 | +|------|------| +| **xtools-app-standalone** | 单体部署模式,包含所有模块,通过 spring-boot-maven-plugin 打包为可执行JAR | +| **xtools-app-sys-boot** | 微服务模式 - 系统管理服务 | +| **xtools-app-gen-boot** | 微服务模式 - 代码生成服务 | +| **xtools-app-monitor-boot** | 微服务模式 - 监控服务 | + +## 三、项目功能设计 + +### 3.1 认证授权设计 + +#### 认证流程 + +```mermaid +flowchart TD + A[用户请求登录] --> B[前端获取SM2公钥] + B --> C[用户输入账号密码
使用SM2公钥加密] + C --> D{验证验证码} + D -->|验证码已过期| E[返回验证码已过期] + D -->|验证码错误| F[返回验证码错误] + D -->|验证成功| G[后端SM2解密密码] + G --> H{查询账号} + H -->|账户不存在| I[返回账户不存在] + H -->|账户被禁用| J[返回账户被禁用] + H -->|账户正常| K{SM3密码比对} + K -->|密码错误| L[返回密码错误] + K -->|密码正确| M[查询用户角色] + M --> N[生成Token
缓存用户信息到Redis] + N --> O[返回TokenDto] +``` + +#### 验证码机制 + +系统支持两种验证码模式(随机切换): +- **GIF动态验证码**:基于 Easy Captcha 生成动态图片验证码 +- **算术验证码**:随机生成加减法算术题图片 + +验证码通过 Redis 缓存(`AppCache.UID_CAPTCHA`,过期时间60秒)。 + +#### RBAC权限模型 + +```mermaid +graph TD + User[用户 SysUser] -->|多对多| UserRole[用户角色关联
SysUserRole] + UserRole -->|多对多| Role[角色 SysRole] + + Role -->|多对多| RoleMenu[角色菜单关联
SysRoleMenu] + RoleMenu -->|多对多| Menu[菜单权限 SysMenu] + + Menu --> M1[页面菜单] + Menu --> M2[按钮权限] + Menu --> M3[接口权限] +``` + +#### 权限验证流程 + +```mermaid +flowchart TD + A[用户发起请求] --> B{判断请求类型} + B -->|微服务请求| C[验证Cloud Token] + B -->|常规请求| D[获取请求URI] + + C --> C1{Token有效?} + C1 -->|无效| C2[返回UNAUTHORIZED] + C1 -->|有效| C3[传递头部信息] + C3 --> C4[校验掩码设置] + C4 --> C5[放行请求] + + D --> D1{URI在权限白名单?} + D1 -->|是| D2[放行请求] + D1 -->|否| D3{获取UID} + D3 -->|UID为空| D4[返回METHOD_NOT_ALLOWED] + D3 -->|UID存在| D5{URI在登录白名单?} + D5 -->|是| D2 + D5 -->|否| D6{验证AccessToken} + D6 -->|无效| D7[返回UNAUTHORIZED] + D6 -->|有效| D8{校验URI访问权限} + D8 -->|无权限| D9[返回FORBIDDEN] + D8 -->|有权限| D10[设置上下文信息] + D10 --> D11[校验掩码设置] + D11 --> D2 +``` + +#### 认证模式 + +系统支持两种认证模式,通过请求头 `Cloud` 标识区分: +- **微服务认证**:验证 Cloud Token(一次性令牌,Redis Hash存储) +- **常规认证**:验证 UID + AccessToken + URI权限 + +### 3.2 日志管理设计 + +#### 日志处理流程 + +```mermaid +flowchart LR + A[HTTP请求] --> B[LogFilter
日志过滤器] + B --> C[采集请求信息
URI,参数,IP,UserAgent] + C --> D[LogBus
日志总线] + D --> E[RabbitMQ
异步消息队列] + E --> F[SysLogMq
日志消费者] + F --> G[LogBusService
日志处理服务] + G --> H[Elasticsearch
日志存储] +``` + +#### 日志类型 + +| 类型 | 说明 | 处理方式 | +|------|------|----------| +| 操作日志 | 用户操作行为记录 | LogFilter采集 -> MQ -> ES | +| 系统日志 | 系统运行日志 | LogBus记录 -> MQ -> ES | +| 任务日志 | 定时任务执行日志 | BaseJob记录 -> LogBus -> MQ -> ES | +| 错误日志 | 异常和错误信息 | 异常捕获 -> LogBus -> MQ -> ES | + +#### 日志配置 + +- **日志总线**:基于 `xtools-boot-log` 封装,支持通过 `LogBus.init()` 链式调用记录日志 +- **消息队列**:使用 RabbitMQ 异步处理,并发度配置为 5-10 +- **存储**:日志存储到 Elasticsearch,通过 `EsSysLogRepository` 和 `EsSysLogServiceImpl` 实现 +- **日志追踪**:使用 `LogTrackHolder`(基于 ScopedValue)实现日志链路追踪 + +### 3.3 代码生成设计 + +#### 代码生成流程 + +```mermaid +flowchart TD + A[配置数据源] --> B[测试连接] + B --> C[同步数据库] + C --> D{读取表信息} + + D --> E[获取表列表
DatabaseMetaData] + E --> F[过滤排除表] + F --> G[生成表信息
GenTable] + + G --> H[获取字段信息
DatabaseMetaData] + H --> I[处理字段类型
类型映射,表单类型] + I --> J[生成字段信息
GenTableColumn] + + J --> K[保存到数据库] + K --> L{用户操作} + + L -->|预览代码| M[Velocity渲染模板] + L -->|下载代码| N[Velocity渲染模板] + L -->|修改配置| O[保存表和字段配置] + + M --> P[返回代码列表
GenCodeDto] + N --> Q[打包ZIP下载] +``` + +#### 模板引擎 + +- 使用 **Apache Velocity 2.4.1** 模板引擎 +- 通过 `GenProperties` 配置模板路径和生成参数 +- 支持多种模板类型:Entity、Service、ServiceImpl、Mapper、Controller、Vue、TS API、SQL等 +- 支持微服务 API 模块生成(可配置开关 `openApi`) +- 支持字典数据、脱敏数据等高级配置 + +#### 代码生成特性 + +| 特性 | 说明 | +|------|------| +| 多数据源 | 支持 MySQL 等多种数据库类型 | +| 表结构同步 | 自动读取表和字段元数据 | +| 智能类型映射 | 自动将数据库类型映射为 Java 类型 | +| 表单类型推断 | 根据字段类型自动推断表单组件 | +| 查询方式推断 | String类型默认LIKE,时间类型默认范围查询 | +| 模板配置 | 可配置后端和前端项目名称、模块路径等 | +| ZIP下载 | 生成的代码打包为ZIP文件下载 | + +### 3.4 任务调度设计 + +#### 任务实现 + +```mermaid +flowchart TD + A[任务触发] --> B[BaseJob.run] + B --> C[初始化日志追踪
ScopedValue] + C --> D[获取Redis锁
tryLock] + D --> E{获取锁成功?} + E -->|否| F[记录日志:已存在] + E -->|是| G[执行runJob方法] + G --> H{执行成功?} + H -->|异常| I[记录错误日志] + H -->|成功| J[记录成功日志] + I --> K[释放锁
releaseLock] + J --> K +``` + +#### 任务类型 + +| 类型 | 实现方式 | 说明 | +|------|----------|------| +| 异步任务 | `BaseJob implements Runnable` | 支持分布式锁,防止重复执行 | +| XXL-JOB | `xtools-boot-job-xxl`(可选) | 分布式任务调度平台 | +| 定时任务 | `SysScheduled` | Spring Task 定时任务管理 | +| Spring任务 | `JobInterface.execute()` | Spring 原生任务执行接口 | + +#### 任务调度特性 + +- **分布式锁**:使用 Redis `tryLock` / `releaseLock` 实现分布式锁,防止多实例重复执行 +- **日志追踪**:通过 `ScopedValue`(JDK 25特性)实现任务执行上下文传递 +- **异常处理**:任务执行异常自动记录错误日志 +- **超时控制**:支持自定义锁超时时间 + +### 3.5 缓存设计 + +#### 缓存策略 + +| 缓存Key | 说明 | 过期时间 | +|---------|------|----------| +| `xtools-app:uid:{uid}:sm2` | SM2公钥缓存 | 5分钟 | +| `xtools-app:uid:{uid}:captcha` | 验证码缓存 | 60秒 | +| `xtools-app:auth:sys:user:{token}` | 用户认证信息 | 1小时 | +| `xtools-app:auth:sys:uri` | 权限URI缓存 | 永不过期 | +| `xtools-app:auth:cloud:token` | 微服务Token | 60秒 | +| `xtools-app:mq:msg:err:{id}` | MQ消息错误次数 | 60秒 | +| `xtools-app:lock:job:{className}` | 任务分布式锁 | 5分钟 | +| `xtools-app:risk:ip:{ip}` | 风控IP | 永不过期 | +| `xtools-app:risk:uri:{uri}` | 风控URI | 永不过期 | +| `xtools-app:sys:cache:param:{key}` | 系统参数缓存 | 永不过期 | +| `xtools-app:sys:cache:jar:{name}` | JAR包缓存 | 永不过期 | +| `xtools-app:sys:cache:addr:{key}` | 地址缓存 | 1小时 | + +#### 缓存架构 + +```mermaid +graph TD + A[应用层] --> B[AppCache
缓存枚举] + B --> C[RedisService
Redis操作服务] + + subgraph Redis缓存 + D1[认证缓存
Token,用户信息] + D2[业务缓存
参数,地址,JAR] + D3[风控缓存
IP,URI限流] + D4[分布式锁
任务锁] + D5[临时数据
验证码,SM2密钥] + end + + C --> D1 + C --> D2 + C --> D3 + C --> D4 + C --> D5 +``` + +### 3.6 文件存储设计 + +项目支持多种文件存储方式(通过 `xtools-app-standalone` 可选配置): + +| 存储方式 | 模块 | 说明 | +|---------|------|------| +| S3存储 | `xtools-boot-storage-s3` | 兼容S3协议的对象存储 | +| 本地文件 | `xtools-boot-storage-file` | 本地文件系统存储(可选) | + +## 四、编码规范设计 + +### 4.1 命名规范 + +#### 类命名 + +| 类型 | 命名规范 | 示例 | +|------|----------|------| +| 实体类 | `Sys` + 模块名 | `SysUser`、`SysRole`、`SysMenu` | +| 请求DTO | 模块名 + `Req` | `SysUserAddReq`、`SysUserPageReq` | +| 响应DTO | 模块名 + `Resp` | `GenTableInfoResp` | +| Excel DTO | 模块名 + `Excel` | `SysDictExcel` | +| Service接口 | 模块名 + `Service` | `SysUserService` | +| Service实现 | 模块名 + `ServiceImpl` | `SysUserServiceImpl` | +| Base Service | 模块名 + `BaseService` | `SysUserBaseService` | +| Controller | 模块名 + `Controller` | `SysUserController` | +| Mapper | 模块名 + `Mapper` | `SysUserMapper` | +| 转换器 | 模块名 + `Convert` | `SysUserConvert` | +| 工具类 | 功能名 + `Utils` | `PasswdUtils`、`AuthUtils` | +| 配置类 | 功能名 + `Config` 或 `Properties` | `SysConfig`、`GenProperties` | + +#### 方法命名 + +| 操作 | 命名规范 | 示例 | +|------|----------|------| +| 查询单个 | `getXxx` | `getUserInfo()` | +| 分页查询 | `pageXxx` | `pageSysUser()` | +| 新增 | `addXxx` / `saveXxx` | `addSysUser()` | +| 修改 | `updateXxx` / `editXxx` | `editUserInfo()` | +| 删除 | `delXxx` / `deleteXxx` | `delSysUser()` | +| 统计 | `countXxx` | — | + +### 4.2 注释规范 + +#### 类注释格式 + +```java +/** + *

Title : 类名称

+ *

Description : 类描述

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 21:18 + */ +``` + +#### 方法注释格式 + +```java +/** + * 方法描述 + * + * @param param 参数说明 + * @return 返回值说明 + */ +``` + +#### 常量注释格式 + +```java +/** + * 微服务标识 + */ +private static final String CLOUD_FLAG = String.valueOf(Boolean.TRUE); +``` + +### 4.3 代码风格 + +- **Lombok**:使用 `@RequiredArgsConstructor` 构造器注入,减少样板代码 +- **MapStruct**:使用接口定义对象转换器,编译时自动生成实现 +- **MyBatis-Plus**:继承 `ServiceImpl` 和 `BaseMapper`,简化CRUD操作 +- **依赖注入**:使用 `@RequiredArgsConstructor` + `final` 字段(构造器注入)和 `@Resource`(特殊场景) +- **统一返回**:使用 `Result` 统一响应格式 +- **统一异常**:使用 `BizError`(业务错误)和 `BizWarning`(业务警告)异常类 +- **JDK特性**:使用 `ScopedValue`、`switch表达式`、`record` 等JDK 25特性 +- **常量管理**:通过 `BaseParams` 接口提供通用常量(`CP_NUM0`、`CP_NUM1` 等) + +### 4.4 设计规范 + +- **分层原则**:Controller -> Service -> Mapper 严格分层,禁止跨层调用 +- **单一职责**:每个模块负责单一业务领域 +- **开闭原则**:通过继承 `BaseJob`、`BaseMessageHandle` 等基类扩展功能 +- **接口隔离**:Service接口与BaseService接口分离,基础CRUD与业务逻辑分离 + +### 4.5 安全规范 + +- **密码加密**:使用 SM3 国密算法加密存储密码,SM2 非对称加密传输密码 +- **SQL安全**:使用 MyBatis-Plus 参数化查询,防止SQL注入 +- **数据验证**:使用 `@Valid` 注解进行请求参数验证 +- **权限控制**:基于 RBAC 模型的接口级别权限控制 +- **数据脱敏**:集成掩码机制(MaskIgnore),支持动态开关 + +## 五、项目依赖设计 + +### 5.1 核心框架依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Spring Boot | 4.0.5 | 应用框架 | +| Spring Framework | 7.0.6 | 核心框架 | +| Spring Cloud | 2025.1.1 | 微服务框架 | +| Spring Cloud Alibaba | 2025.1.0.0 | 微服务组件 | +| Spring Data BOM | 2025.1.4 | 数据访问版本管理 | +| MyBatis-Plus | 3.5.16 | ORM增强工具 | +| MyBatis Spring Boot Starter | 4.0.1 | MyBatis集成 | + +### 5.2 数据存储依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Druid | 1.2.28 | 数据库连接池 | +| MySQL Connector/J | 9.6.0 | MySQL数据库驱动 | +| Elasticsearch Client | 9.2.6 | ES搜索引擎客户端 | +| Spring Data Redis | (Spring Boot管理) | Redis集成 | +| Lettuce | 6.8.2 | Redis客户端 | +| Spring AMQP | 4.0.2 | RabbitMQ集成 | +| RabbitMQ Client | 5.27.1 | RabbitMQ客户端 | + +### 5.3 微服务相关依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Nacos Client | 3.1.1 | 服务注册与配置中心 | +| Sentinel | 1.8.9 | 流量控制与熔断降级 | +| Seata | 2.5.0 | 分布式事务(可用) | +| RocketMQ | 5.3.1 | 消息队列(可用) | + +### 5.4 工具库依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Lombok | 1.18.44 | 代码简化 | +| MapStruct | 1.6.3 | 对象映射 | +| FastJSON2 | 2.0.60 | JSON处理 | +| Velocity | 2.4.1 | 模板引擎(代码生成) | +| Jackson | 2.21.2 | JSON序列化 | +| Commons Lang3 | 3.20.0 | 通用工具 | +| Commons IO | 2.21.0 | IO工具 | +| Commons Text | 1.15.0 | 文本处理 | +| Caffeine | 3.2.3 | 本地缓存 | + +### 5.5 安全相关依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| BouncyCastle (bcprov-jdk18on) | 1.84 | 国密算法(SM2/SM3) | +| Easy Captcha | 1.6.2 | 验证码生成 | +| java-jwt | 4.5.1 | JWT令牌 | + +### 5.6 文档相关依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Knife4j | 4.5.0 | API文档增强 | +| SpringDoc OpenAPI | 3.0.3 | OpenAPI文档 | +| Swagger Annotations | 2.2.48 | API注解 | + +### 5.7 系统监控依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Spring Boot Admin | 4.0.3 | 应用监控 | +| OSHI Core | 6.11.1 | 系统信息采集 | +| Micrometer | 1.16.4 | 指标采集 | + +### 5.8 文件处理依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Fesod Sheet | 2.0.1-incubating | Excel处理 | +| PDFBox | 3.0.7 | PDF处理 | +| Thumbnailator | 0.4.21 | 图片压缩 | +| S3 SDK | 2.42.34 | S3对象存储客户端 | + +### 5.9 其他工具依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| XXL-Job Core | 3.4.0 | 分布式任务调度 | +| IP2Region | 3.3.7 | IP归属地查询 | +| UserAgentUtils | 1.21 | 浏览器标识解析 | +| Pinyin4j | 2.5.1 | 拼音转换 | +| ZXing | 3.5.4 | 二维码/条形码 | +| JSoup | 1.22.1 | HTML解析 | +| MMSEG4J | 1.10.0 | 中文分词 | + +### 5.10 xtools 内部框架依赖 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| xtools-core | 5.0.0 | 核心工具库 | +| xtools-web | 5.0.0 | Web工具库 | +| xtools-extend | 5.0.0 | 扩展工具库 | +| xtools-api | 5.0.0 | API基础库 | +| xtools-boot-api | 5.0.0 | Boot API基础(Result、异常) | +| xtools-boot-core | 5.0.0 | Boot核心(Holder、工具) | +| xtools-boot-cache-redis | 5.0.0 | Redis缓存封装 | +| xtools-boot-db-mybatis-plus | 5.0.0 | MyBatis-Plus封装 | +| xtools-boot-elasticsearch | 5.0.0 | Elasticsearch封装 | +| xtools-boot-ip | 5.0.0 | IP工具封装 | +| xtools-boot-knife4j | 5.0.0 | Knife4j封装 | +| xtools-boot-log | 5.0.0 | 日志封装 | +| xtools-boot-mask | 5.0.0 | 数据脱敏封装 | +| xtools-boot-mq-base | 5.0.0 | 消息队列基础 | +| xtools-boot-mq-rabbit | 5.0.0 | RabbitMQ封装 | +| xtools-boot-storage-base | 5.0.0 | 存储基础 | +| xtools-boot-storage-file | 5.0.0 | 本地文件存储 | +| xtools-boot-storage-s3 | 5.0.0 | S3对象存储 | +| xtools-boot-task | 5.0.0 | 异步任务封装 | +| xtools-boot-thread | 5.0.0 | 线程池封装 | +| xtools-boot-web-base | 5.0.0 | Web基础 | +| xtools-boot-web-filter | 5.0.0 | Web过滤器基础 | +| xtools-boot-job-xxl | 5.0.0 | XXL-Job集成 | +| xtools-cloud-alibaba-nacos | 5.0.0 | Nacos集成 | +| xtools-cloud-alibaba-sentinel | 5.0.0 | Sentinel集成 | +| xtools-cloud-call | 5.0.0 | 微服务远程调用 | + +## 六、技术选型说明 + +### 6.1 JDK 25 + +- **选择原因**:采用最新LTS版本,充分利用JDK新特性提升开发效率和运行性能 +- **主要特性**: + - **ScopedValue**:用于任务执行的上下文传递(LogTrackHolder),替代ThreadLocal + - **Virtual Threads(虚拟线程)**:轻量级线程,提升高并发处理能力 + - **Switch表达式**:简化条件分支代码 + - **Record**:用于不可变数据载体 + - **Pattern Matching**:增强的模式匹配能力 + - **性能优化**:ZGC/Shenandoah垃圾回收器优化 + +### 6.2 Spring Boot 4.0.5 + +- **Spring Framework版本**:7.0.6 +- **主要特性**: + - 支持JDK 17+,完美适配JDK 25 + - 响应式编程支持(WebFlux) + - 可观测性增强(Micrometer 1.16.4集成) + - 虚拟线程支持 + - Jakarta EE 10+ 规范支持 + - GraalVM Native Image 支持 + +### 6.3 MyBatis-Plus 3.5.16 + +- **MyBatis版本**:4.0.1 +- **主要特性**: + - 简化CRUD操作,通过 `ServiceImpl` 和 `BaseMapper` 提供通用方法 + - Lambda查询包装器,类型安全的条件构造 + - 内置分页插件 + - 代码生成器(本项目自研代码生成模块) + - 性能分析拦截器 + +### 6.4 Elasticsearch 9.2.6 + +- **Spring Data BOM**:2025.1.4 +- **主要特性**: + - 全文搜索引擎,用于日志存储和检索 + - 高性能、分布式架构 + - 支持近实时搜索 + - 通过 Spring Data Elasticsearch 集成 + +### 6.5 Redis + +- **客户端**:Lettuce 6.8.2 +- **主要特性**: + - 高性能缓存,支持多种数据结构 + - 分布式锁(tryLock/releaseLock) + - 认证信息缓存、权限缓存 + - 会话管理、限流计数 + +### 6.6 RabbitMQ + +- **Spring AMQP**:4.0.2 +- **RabbitMQ Client**:5.27.1 +- **主要特性**: + - 可靠消息传递(消息确认机制) + - 灵活路由(Exchange + Queue + RoutingKey) + - 并发消费控制(concurrency配置) + - 错误处理和重试机制(MqErrorHandle) + +### 6.7 Nacos 3.1.1 + +- **用途**:服务注册与发现、配置中心 +- **主要特性**: + - 服务注册与发现 + - 动态配置管理 + - 服务健康检查 + +### 6.8 Sentinel 1.8.9 + +- **用途**:流量控制与熔断降级 +- **主要特性**: + - 流量控制 + - 熔断降级 + - 系统保护 + - 热点参数限流 + +### 6.9 其他重要依赖版本 + +| 依赖 | 版本 | 用途 | +|------|------|------| +| Spring Cloud Alibaba | 2025.1.0.0 | 微服务框架 | +| Nacos | 3.1.1 | 服务注册与配置中心 | +| Sentinel | 1.8.9 | 流量控制与熔断 | +| FastJSON2 | 2.0.60 | JSON序列化 | +| Lombok | 1.18.44 | 代码简化 | +| MapStruct | 1.6.3 | 对象映射 | +| Velocity | 2.4.1 | 模板引擎 | +| Knife4j | 4.5.0 | API文档增强 | +| BouncyCastle | 1.84 | 加密库 | +| OSHI | 6.11.1 | 系统监控 | +| Easy Captcha | 1.6.2 | 验证码生成 | +| Fesod Sheet | 2.0.1-incubating | Excel处理 | +| Jackson | 2.21.2 | JSON处理 | +| Druid | 1.2.28 | 数据库连接池 | +| Spring Boot Admin | 4.0.3 | 应用监控 | +| java-jwt | 4.5.1 | JWT令牌 | +| XXL-Job | 3.4.0 | 分布式任务调度 | + +--- + +**文档版本**:v1.0 +**编写日期**:2026-04-16 +**项目版本**:1.0.0 +**父POM版本**:xtools-parent-cloud:5.0.0 +**JDK版本**:25 +**维护团队**:xujun.org diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..86cb211 --- /dev/null +++ b/pom.xml @@ -0,0 +1,209 @@ + + 4.0.0 + xtools-app + 1.0.0 + pom + xtools-app + 低调大师工具箱,基础应用模块,适配JDK25 + + + + org.xujun + xtools-parent-cloud + 5.0.0 + + + + + + org.xujun + https://www.xujun.org + + + + + xtools-app-common + xtools-app-monitor + xtools-app-standalone + xtools-app-sys + xtools-app-gen + + + + + + 25 + + + + + + + + + org.xujun + xtools-app-common-cache + ${project.version} + + + org.xujun + xtools-app-common-call + ${project.version} + + + org.xujun + xtools-app-common-jar + ${project.version} + + + org.xujun + xtools-app-common-job + ${project.version} + + + org.xujun + xtools-app-common-log-bus + ${project.version} + + + org.xujun + xtools-app-common-log-filter + ${project.version} + + + org.xujun + xtools-app-common-mq + ${project.version} + + + org.xujun + xtools-app-common-sentinel + ${project.version} + + + org.xujun + xtools-app-common-task + ${project.version} + + + + + + org.xujun + xtools-app-monitor-client + ${project.version} + + + + + + org.xujun + xtools-app-sys-api + ${project.version} + + + org.xujun + xtools-app-sys-auth + ${project.version} + + + org.xujun + xtools-app-sys-biz + ${project.version} + + + org.xujun + xtools-app-sys-call + ${project.version} + + + org.xujun + xtools-app-sys-file + ${project.version} + + + org.xujun + xtools-app-sys-file-web + ${project.version} + + + org.xujun + xtools-app-sys-log-bus-elasticsearch + ${project.version} + + + org.xujun + xtools-app-sys-param + ${project.version} + + + org.xujun + xtools-app-sys-risk + ${project.version} + + + org.xujun + xtools-app-sys-scheduled + ${project.version} + + + + + + org.xujun + xtools-app-gen-biz + ${project.version} + + + + + + org.xujun + xtools-app-demo-biz + ${project.version} + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + -Amapstruct.unmappedTargetPolicy=IGNORE + + + + + + + + + + + \ No newline at end of file diff --git a/xtools-app-common/pom.xml b/xtools-app-common/pom.xml new file mode 100644 index 0000000..26e8c9a --- /dev/null +++ b/xtools-app-common/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + org.xujun + xtools-app + 1.0.0 + + xtools-app-common + pom + + + + xtools-app-common-cache + xtools-app-common-call + xtools-app-common-jar + xtools-app-common-job + xtools-app-common-log + xtools-app-common-mq + xtools-app-common-sentinel + xtools-app-common-task + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-cache/pom.xml b/xtools-app-common/xtools-app-common-cache/pom.xml new file mode 100644 index 0000000..34eaf88 --- /dev/null +++ b/xtools-app-common/xtools-app-common-cache/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-cache + + + + + + + org.xujun + xtools-extend + + + + org.xujun + xtools-boot-log + + + + org.xujun + xtools-boot-cache-redis + + + + + + org.aspectj + aspectjweaver + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/aop/RedisServiceAop.java b/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/aop/RedisServiceAop.java new file mode 100644 index 0000000..b2fb7db --- /dev/null +++ b/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/aop/RedisServiceAop.java @@ -0,0 +1,73 @@ +package xtools.app.common.cache.aop; + +import com.alibaba.fastjson2.JSONObject; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import xtools.boot.api.model.dto.log.LogTrack; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.core.enums.LogLevel; + +import java.util.Objects; + +/** + *

Title : RedisServiceAop

+ *

Description : RedisServiceAop

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/11 14:07 + */ +@Aspect +@Component +public class RedisServiceAop { + + /** + * 方法切面 + */ + @Pointcut("execution(* xtools.boot.cache.redis.base.RedisService.*(..))") + public void methods() { + } + + /** + * 调用记录 + * + * @param joinPoint 切点 + * @return 调用结果 + * @throws Throwable 异常信息 + */ + @Around("methods()") + public Object logMethodCall(ProceedingJoinPoint joinPoint) throws Throwable { + LogTrack logTrack = LogTrackHolder.getDefNull(); + if (Objects.isNull(logTrack)) { + return joinPoint.proceed(); + } + long startTime = System.currentTimeMillis(); + String method = joinPoint.getSignature().getName(); + Object[] args = joinPoint.getArgs(); + Exception err = null; + Object result = null; + try { + result = joinPoint.proceed(); + return result; + } catch (Exception e) { + err = e; + throw e; + } finally { + long endTime = System.currentTimeMillis(); + JSONObject logData = JSONObject.of("method", method, "args", args, "result", result, "execTime", endTime - startTime); + LogBus.init(err == null ? LogLevel.INFO : LogLevel.ERROR, LogBusBaseType.REDIS, logTrack) + .data(logData) + .error(err) + .save(); + } + } + +} diff --git a/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/enums/AppCache.java b/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/enums/AppCache.java new file mode 100644 index 0000000..dfbffc9 --- /dev/null +++ b/xtools-app-common/xtools-app-common-cache/src/main/java/xtools/app/common/cache/enums/AppCache.java @@ -0,0 +1,107 @@ +package xtools.app.common.cache.enums; + +import xtools.boot.cache.redis.enums.BaseCacheEnum; +import xtools.core.extend.TemplateUtils; + +/** + *

Title : AppCache

+ *

Description : AppCache

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/4 16:27 + */ +public enum AppCache implements BaseCacheEnum { + + // uid加密SM2 + UID_SM2("uid:{}:sm2", 5 * 60L), + // uid验证码 + UID_CAPTCHA("uid:{}:captcha", 60L), + + // SYS 授权用户信息 + AUTH_SYS_USER("auth:sys:user:", 60 * 60L), + // SYS 授权 URI + AUTH_SYS_URI("auth:sys:uri", -1L), + // CLOUD 授权 TOKEN + AUTH_CLOUD_TOKEN("auth:cloud:token", 60L), + + // MQ消息错误次数 + MQ_MSG_ERR_COUNT("mq:msg:err:", 60L), + + // JOB锁 + LOCK_JOB("lock:job:", 5 * 60L), + + // 风控IP + RISK_IP("risk:ip:", -1L), + // 风控URI + RISK_URI("risk:uri:", -1L), + + // 系统参数缓存 + SYS_CACHE_PARAM("sys:cache:param:", -1L), + // 系统JAR包缓存 + SYS_CACHE_JAR("sys:cache:jar:", -1L), + // 地址缓存 + SYS_CACHE_ADDR("sys:cache:addr:", 60 * 60L), + // 天气缓存 + SYS_CACHE_HOME_WEATHER("sys:cache:home:weather:", 30 * 60L), + ; + + /** + * 系统缓存前缀 + */ + private final static String SYS_CACHE_PREFIX = "xtools-app:"; + + /** + * key + */ + private final String key; + + /** + * 超时时间 + */ + private final Long expireTime; + + /** + * 构造方法 + * + * @param key 缓存 key + * @param expireTime 过期时间 + */ + AppCache(String key, Long expireTime) { + this.key = key; + this.expireTime = expireTime; + } + + /** + * 获取缓存 key + * + * @param param 参数 + * @return 缓存 key + */ + public String key(Object... param) { + return SYS_CACHE_PREFIX + TemplateUtils.format(key, param); + } + + /** + * 获取缓存 key + * + * @return 缓存 key + */ + @Override + public String key() { + return SYS_CACHE_PREFIX + key; + } + + /** + * 获取缓存过期时间 + * + * @return 缓存过期时间 + */ + @Override + public Long expireTime() { + return expireTime; + } +} diff --git a/xtools-app-common/xtools-app-common-call/pom.xml b/xtools-app-common/xtools-app-common-call/pom.xml new file mode 100644 index 0000000..6f4dee9 --- /dev/null +++ b/xtools-app-common/xtools-app-common-call/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-call + + + + + + + org.xujun + xtools-cloud-call + + + + + + org.xujun + xtools-app-common-cache + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-call/src/main/java/xtools/app/common/call/SysCallInterceptor.java b/xtools-app-common/xtools-app-common-call/src/main/java/xtools/app/common/call/SysCallInterceptor.java new file mode 100644 index 0000000..6615921 --- /dev/null +++ b/xtools-app-common/xtools-app-common-call/src/main/java/xtools/app/common/call/SysCallInterceptor.java @@ -0,0 +1,87 @@ +package xtools.app.common.call; + +import jakarta.annotation.Resource; +import org.jspecify.annotations.NonNull; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpRequest; +import org.springframework.stereotype.Component; +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.api.constant.BootCommonConstant; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.core.holder.CommonHolder; +import xtools.cloud.call.interceptor.CallInterceptor; +import xtools.core.CollectionUtils; +import xtools.core.UuidUtils; + +import java.util.Map; + +/** + *

Title : SysCallInterceptor

+ *

Description : SysCallInterceptor

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/27 14:55 + */ +@Component +public class SysCallInterceptor implements CallInterceptor, BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.AUTH_CLOUD_TOKEN; + + @Resource + private RedisService redisService; + + /** + * 请求之前 + * + * @param request 请求 + */ + @Override + public void before(@NonNull HttpRequest request) { + // 设置微服务认证信息 + setCloudToken(request); + Map commonMap = CommonHolder.get(); + // 传递请求头信息 + setHeaders(request, commonMap); + } + + /** + * 设置微服务认证信息 + * + * @param request 请求 + */ + private void setCloudToken(@NonNull HttpRequest request) { + // 设置微服务认证信息 + String token = UuidUtils.get(); + redisService.hashPut(CACHE_PARAM.key(), token, CP_NUM0, CACHE_PARAM.expireTime()); + request.getHeaders().add(BootCommonConstant.CLOUD_TOKEN, token); + } + + /** + * 设置请求头 + * + * @param request 请求 + * @param commonMap 公共参数 + */ + private void setHeaders(@NonNull HttpRequest request, Map commonMap) { + // 传递请求头信息 + if (CollectionUtils.isEmpty(commonMap)) { + return; + } + HttpHeaders headers = request.getHeaders(); + if (commonMap.get(BootCommonConstant.AUTHORIZATION) instanceof String authorization) { + headers.add(BootCommonConstant.AUTHORIZATION, authorization); + } + if (commonMap.get(BootCommonConstant.UID) instanceof String uid) { + headers.add(BootCommonConstant.UID, uid); + } + } + +} diff --git a/xtools-app-common/xtools-app-common-jar/pom.xml b/xtools-app-common/xtools-app-common-jar/pom.xml new file mode 100644 index 0000000..34eea3b --- /dev/null +++ b/xtools-app-common/xtools-app-common-jar/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-jar + + + + + + + org.xujun + xtools-boot-log + + + + + + org.xujun + xtools-app-common-cache + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/init/InitJar.java b/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/init/InitJar.java new file mode 100644 index 0000000..3ec78e8 --- /dev/null +++ b/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/init/InitJar.java @@ -0,0 +1,71 @@ +package xtools.app.common.jar.init; + +import jakarta.annotation.Resource; +import org.jspecify.annotations.NonNull; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.core.utils.JarUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.core.CollectionUtils; +import xtools.core.enums.LogLevel; + +import java.util.List; + + +/** + *

Title : InitJar

+ *

Description : InitJar

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 14:13 + */ +@Component +@Order(BaseParams.CP_NUM200) +public class InitJar implements ApplicationRunner { + + /** + * 应用名称 + */ + @Value("${spring.application.name:xtools-app}") + private String name; + + @Resource + private RedisService redisService; + + + @Override + public void run(@NonNull ApplicationArguments args) { + ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newMain()).run(() -> { + try { + init(); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.OTHER).title("初始化Jar异常").error(e).save(); + } + }); + + } + + /** + * 初始化 + */ + private void init() { + List jarNameList = JarUtils.getJarName(); + if (CollectionUtils.isEmpty(jarNameList)) { + return; + } + String key = AppCache.SYS_CACHE_JAR.key() + name; + redisService.set(key, jarNameList); + } +} diff --git a/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/utils/RunJarUtils.java b/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/utils/RunJarUtils.java new file mode 100644 index 0000000..6782a55 --- /dev/null +++ b/xtools-app-common/xtools-app-common-jar/src/main/java/xtools/app/common/jar/utils/RunJarUtils.java @@ -0,0 +1,52 @@ +package xtools.app.common.jar.utils; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.utils.RedisUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + *

Title : RunJarUtils

+ *

Description : RunJarUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/18 21:11 + */ +public class RunJarUtils implements BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.SYS_CACHE_JAR; + + /** + * 获取运行中的Jar + */ + public static List get() { + String cacheKey = AppCache.SYS_CACHE_JAR.key(); + Set keys = RedisUtils.get().getByPattern(cacheKey + CP_ASTERISK); + List dataList = new ArrayList<>(); + for (String key : keys) { + JSONArray cacheData = RedisUtils.get().get(key, JSONArray.class); + if (Objects.isNull(cacheData) || cacheData.isEmpty()) { + continue; + } + JSONObject data = new JSONObject(); + data.put("name", key.replace(cacheKey, CP_EMPTY)); + data.put("jars", cacheData); + dataList.add(data); + } + return dataList; + } + +} diff --git a/xtools-app-common/xtools-app-common-job/pom.xml b/xtools-app-common/xtools-app-common-job/pom.xml new file mode 100644 index 0000000..0414b30 --- /dev/null +++ b/xtools-app-common/xtools-app-common-job/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-job + + + + + + org.xujun + xtools-app-common-cache + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-job/src/main/java/xtools/app/common/job/base/BaseJob.java b/xtools-app-common/xtools-app-common-job/src/main/java/xtools/app/common/job/base/BaseJob.java new file mode 100644 index 0000000..14ac813 --- /dev/null +++ b/xtools-app-common/xtools-app-common-job/src/main/java/xtools/app/common/job/base/BaseJob.java @@ -0,0 +1,133 @@ +package xtools.app.common.job.base; + +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.boot.core.interfaces.JobInterface; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.core.UuidUtils; +import xtools.core.enums.LogLevel; +import xtools.core.extend.CheckUtils; +import xtools.core.time.InstantUtils; + +import java.time.Instant; +import java.util.Objects; + +/** + *

Title : BaseJob

+ *

Description : BaseJob

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/23 17:36 + */ +public abstract class BaseJob implements Runnable, BaseParams, JobInterface { + + /** + * 锁参数 + */ + private static final AppCache LOCK_PARAM = AppCache.LOCK_JOB; + + /** + * 运行作业 + */ + @Override + public void run() { + ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newMain()).run(this::exec); + } + + /** + * 执行作业 + */ + private void exec() { + // 获取执行的class名称 + String className = getClass().getSimpleName(); + // 标题 + String title = "[" + className + "]"; + // 获取本次作业名称 + String jobName = null; + // 获取redis服务 + RedisService redisService = null; + // 锁 + boolean locked = false; + try { + // 记录日志 + LogBus.init(LogLevel.INFO, LogBusBaseType.JOB).title(title + "开始执行").save(); + + jobName = className + CP_LINE + InstantUtils.format(Instant.now(), "yyyyMMddHHmmssSSS") + CP_LINE + UuidUtils.get(); + redisService = RedisUtils.get(); + // 获取超时时间 + Long expireTime = expireTime(); + if (!CheckUtils.id(expireTime)) { + expireTime = LOCK_PARAM.expireTime(); + } + // 加锁 + locked = redisService.tryLock(LOCK_PARAM.key() + className, jobName, expireTime); + if (!locked) { + LogBus.init(LogLevel.INFO, LogBusBaseType.JOB).title(title + "已存在").save(); + return; + } + + runJob(); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.JOB).title(title + "运行异常").error(e).save(); + } finally { + if (Objects.nonNull(redisService) && locked) { + boolean released = redisService.releaseLock(LOCK_PARAM.key() + className, jobName); + if (!released) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.JOB).title(title + "锁释放异常").save(); + } else { + LogBus.init(LogLevel.INFO, LogBusBaseType.JOB).title(title + "执行成功").save(); + } + } + } + } + + /** + * 执行任务 + */ + @Override + public void execute() { + // 标题 + String title = "[" + getClass().getSimpleName() + "]"; + ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newMain()).run(() -> { + Exception e = null; + try { + // 记录日志 + LogBus.init(LogLevel.INFO, LogBusBaseType.JOB).title(title + "开始执行").save(); + runJob(); + } catch (Exception ex) { + e = ex; + } finally { + if (Objects.nonNull(e)) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.JOB).title(title + "运行异常").error(e).save(); + } else { + LogBus.init(LogLevel.INFO, LogBusBaseType.JOB).title(title + "执行成功").save(); + } + } + }); + } + + /** + * 获取锁超时时间 + * + * @return 锁超时时间 + */ + public Long expireTime() { + return null; + } + + /** + * 运行作业 + * + * @throws Exception 运行异常 + */ + public abstract void runJob() throws Exception; + +} diff --git a/xtools-app-common/xtools-app-common-log/pom.xml b/xtools-app-common/xtools-app-common-log/pom.xml new file mode 100644 index 0000000..4f2559e --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + pom + xtools-app-common-log + + + + xtools-app-common-log-bus + xtools-app-common-log-filter + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/pom.xml b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/pom.xml new file mode 100644 index 0000000..b0a4ede --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-common-log + 1.0.0 + + xtools-app-common-log-bus + + + + + + + org.xujun + xtools-boot-log + + + + + + org.xujun + xtools-app-common-mq + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/enums/SysLogType.java b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/enums/SysLogType.java new file mode 100644 index 0000000..d6dfb80 --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/enums/SysLogType.java @@ -0,0 +1,71 @@ +package xtools.app.common.log.bus.enums; + +import xtools.boot.api.enums.BaseEnum; +import xtools.boot.log.interfaces.LogBusType; + +/** + *

Title : SysLogType

+ *

Description : SysLogType

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/3 11:26 + */ +public enum SysLogType implements LogBusType { + + ; + + /** + * 编码 + **/ + private final int code; + + /** + * 说明 + **/ + private final String desc; + + /** + * 初始化方法 + * + * @param code Code + * @param desc 说明 + */ + SysLogType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code + BASE_CODE; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } +} diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/handle/LogBusHandle.java b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/handle/LogBusHandle.java new file mode 100644 index 0000000..ba81044 --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/handle/LogBusHandle.java @@ -0,0 +1,54 @@ +package xtools.app.common.log.bus.handle; + +import org.springframework.stereotype.Component; +import xtools.app.common.log.bus.service.LogBusService; +import xtools.app.common.mq.enums.RabbitMqEnums; +import xtools.boot.core.utils.SpringContextUtils; +import xtools.boot.log.interfaces.LogBusInterface; +import xtools.boot.log.model.dto.LogBody; +import xtools.boot.mq.base.utils.MqBus; + +import java.util.Objects; + +/** + *

Title : LogBusHandle

+ *

Description : LogBusHandle

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/3 17:01 + */ +@Component +public class LogBusHandle implements LogBusInterface { + + /** + * 日志服务 + */ + private static LogBusService logBusService; + + /** + * 是否使用本地服务 + */ + private static Boolean localService; + + /** + * 保存日志 + * + * @param logBody 日志 + */ + @Override + public void save(LogBody logBody) { + if (Objects.isNull(localService)) { + logBusService = SpringContextUtils.getBeanDefNull(LogBusService.class); + localService = Objects.nonNull(logBusService); + } + if (localService) { + logBusService.saveLog(logBody); + } else { + MqBus.push(RabbitMqEnums.SYS_LOG, logBody); + } + } +} diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/service/LogBusService.java b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/service/LogBusService.java new file mode 100644 index 0000000..5786279 --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-bus/src/main/java/xtools/app/common/log/bus/service/LogBusService.java @@ -0,0 +1,25 @@ +package xtools.app.common.log.bus.service; + +import xtools.boot.log.model.dto.LogBody; + +/** + *

Title : LogBusService

+ *

Description : LogBusService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/7 19:41 + */ +public interface LogBusService { + + /** + * 保存日志 + * + * @param logBody 日志 + */ + void saveLog(LogBody logBody); + +} diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/pom.xml b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/pom.xml new file mode 100644 index 0000000..0758738 --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + org.xujun + xtools-app-common-log + 1.0.0 + + xtools-app-common-log-filter + + + + + + + org.xujun + xtools-extend + + + + org.xujun + xtools-web + + + + org.xujun + xtools-boot-web-filter + + + + + + + org.xujun + xtools-app-common-log-bus + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/filter/HttpLogFilter.java b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/filter/HttpLogFilter.java new file mode 100644 index 0000000..28dd37c --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/filter/HttpLogFilter.java @@ -0,0 +1,177 @@ +package xtools.app.common.log.filter; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.jspecify.annotations.NonNull; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.ContentCachingResponseWrapper; +import xtools.app.common.log.whitelist.HttpLogWhitelist; +import xtools.base.config.BaseParams; +import xtools.boot.api.constant.BootCommonConstant; +import xtools.boot.core.utils.PathPatternUtils; +import xtools.boot.core.utils.SpringContextUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.web.filter.base.BaseFilter; +import xtools.core.CollectionUtils; +import xtools.core.enums.LogLevel; +import xtools.web.HeaderUtils; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + *

Title : HttpLogFilter

+ *

Description : HttpLogFilter

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/6 16:37 + */ +@Component +public class HttpLogFilter extends BaseFilter implements Ordered, BaseParams { + + /** + * 日志白名单 + */ + private static final Set LOG_WHITE_LIST = new HashSet<>(); + + /** + * 响应体白名单 + */ + private static final Set RESP_WHITE_LIST = new HashSet<>(); + + /** + * 缓存大小 + */ + private static final int DEFAULT_CACHE_LIMIT = 1024 * 1024; + + @Override + public int getOrder() { + return CP_NUM200; + } + + @Override + protected void initFilterBean() throws ServletException { + super.initFilterBean(); + Collection beanList = SpringContextUtils.getBeanList(HttpLogWhitelist.class); + if (CollectionUtils.isEmpty(beanList)) { + return; + } + beanList.forEach(item -> { + LOG_WHITE_LIST.addAll(item.ignoreLog()); + RESP_WHITE_LIST.addAll(item.ignoreResp()); + }); + } + + @Override + protected void doFilterInternal( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + long startTime = System.currentTimeMillis(); + // 获取访问 uri + String uri = HeaderUtils.getUri(request); + if (PathPatternUtils.match(LOG_WHITE_LIST, uri)) { + filterChain.doFilter(request, response); + return; + } + + // 获取请求日志 + JSONObject log = getRequestLog(request); + // 记录请求日志 + LogBus.init(LogLevel.INFO, LogBusBaseType.HTTP_REQUEST).data(log).save(); + + // 包装请求和响应 + ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request, DEFAULT_CACHE_LIMIT); + ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); + + // 处理请求 + filterChain.doFilter(requestWrapper, responseWrapper); + + // 获取请求参数 + Object reqParam = getContent(requestWrapper.getContentAsByteArray()); + log.put("reqBody", reqParam); + + // 处理异常日志 + LogLevel level = LogLevel.INFO; + if (!PathPatternUtils.match(RESP_WHITE_LIST, uri)) { + // 获取响应内容 + Object respData = getContent(responseWrapper.getContentAsByteArray()); + log.put("respData", respData); + if (respData instanceof JSONObject respJson) { + Boolean success = respJson.getBoolean("success"); + if (Objects.equals(success, false)) { + level = LogLevel.ERROR; + } + } + } + long endTime = System.currentTimeMillis(); + log.put("execTime", endTime - startTime); + // 将内容复制回原始响应 + responseWrapper.copyBodyToResponse(); + // 记录响应日志 + LogBus.init(level, LogBusBaseType.HTTP_RESPONSE).data(log).save(); + } + + /** + * 获取内容 + * + * @param content 内容 + * @return 内容 + */ + @NonNull + private Object getContent(byte[] content) { + if (Objects.isNull(content) || content.length == CP_NUM0) { + return "empty"; + } + String data = new String(content, StandardCharsets.UTF_8); + try { + return JSONObject.parseObject(data); + } catch (Exception e) { + // ignore + } + try { + return JSONArray.parse(data); + } catch (Exception e) { + // ignore + } + return data; + } + + /** + * 获取请求日志 + * + * @param request 请求 + * @return 请求日志 + */ + public JSONObject getRequestLog(HttpServletRequest request) { + // 基础日志信息 + JSONObject log = new JSONObject(); + log.put("uri", HeaderUtils.getUri(request)); + log.put("method", request.getMethod()); + log.put("query", HeaderUtils.getQuery(request)); + log.put("params", HeaderUtils.getParamsToString(request)); + log.put("userAgent", HeaderUtils.getUserAgent(request)); + log.put("referer", HeaderUtils.getReferer(request)); + log.put("ip", HeaderUtils.getIp(request)); + log.put(BootCommonConstant.UID, HeaderUtils.getRequestParam(request, BootCommonConstant.UID)); + log.put(BootCommonConstant.AUTHORIZATION, HeaderUtils.getRequestParam(request, BootCommonConstant.AUTHORIZATION)); + return log; + } + +} diff --git a/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/whitelist/HttpLogWhitelist.java b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/whitelist/HttpLogWhitelist.java new file mode 100644 index 0000000..61c545f --- /dev/null +++ b/xtools-app-common/xtools-app-common-log/xtools-app-common-log-filter/src/main/java/xtools/app/common/log/whitelist/HttpLogWhitelist.java @@ -0,0 +1,36 @@ +package xtools.app.common.log.whitelist; + +import java.util.Set; + +/** + *

Title : HttpLogWhitelist

+ *

Description : HttpLogWhitelist

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/2 14:36 + */ +public interface HttpLogWhitelist { + + /** + * 添加日志白名单 + * + * @return 日志白名单 + */ + default Set ignoreLog() { + return Set.of(); + } + + /** + * 添加响应体白名单 + * + * @return 响应体白名单 + */ + default Set ignoreResp() { + return Set.of(); + } + +} diff --git a/xtools-app-common/xtools-app-common-mq/pom.xml b/xtools-app-common/xtools-app-common-mq/pom.xml new file mode 100644 index 0000000..50a2eee --- /dev/null +++ b/xtools-app-common/xtools-app-common-mq/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-mq + + + + + + + org.xujun + xtools-boot-mq-base + + + + org.xujun + xtools-boot-mq-rabbit + + + + + + org.xujun + xtools-app-common-cache + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/enums/RabbitMqEnums.java b/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/enums/RabbitMqEnums.java new file mode 100644 index 0000000..f3c6d44 --- /dev/null +++ b/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/enums/RabbitMqEnums.java @@ -0,0 +1,65 @@ +package xtools.app.common.mq.enums; + +import xtools.boot.mq.base.enums.MqEnums; + +/** + *

Title : RabbitMqEnums

+ *

Description : RabbitMqEnums

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/5 16:46 + */ +public enum RabbitMqEnums implements MqEnums { + + // 系统日志 + SYS_LOG("sys.log", false), + // 系统任务 + SYS_TASK("sys.task", true), + ; + + /** + * 队列名称 + */ + private final String queue; + + /** + * 是否保存日志 + */ + private final boolean saveLog; + + /** + * 构造方法 + * + * @param queue 队列名称 + * @param saveLog 是否保存日志 + */ + RabbitMqEnums(String queue, boolean saveLog) { + this.queue = queue; + this.saveLog = saveLog; + } + + /** + * 获取队列名称 + * + * @return 队列名称 + */ + @Override + public String queue() { + return queue; + } + + /** + * 是否保存日志 + * + * @return 是否保存日志 + */ + @Override + public boolean saveLog() { + return saveLog; + } + +} diff --git a/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/handle/MqErrorHandle.java b/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/handle/MqErrorHandle.java new file mode 100644 index 0000000..a703049 --- /dev/null +++ b/xtools-app-common/xtools-app-common-mq/src/main/java/xtools/app/common/mq/handle/MqErrorHandle.java @@ -0,0 +1,57 @@ +package xtools.app.common.mq.handle; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.mq.base.handle.BaseErrorHandle; +import xtools.extend.encrypt.Sm3Utils; + +/** + *

Title : MqErrorHandle

+ *

Description : MqErrorHandle

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/12 10:53 + */ +@Slf4j +@Component +public class MqErrorHandle implements BaseErrorHandle, BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.MQ_MSG_ERR_COUNT; + + @Resource + private RedisService redisService; + + /** + * 消息处理错误异常(需要消息队列重推消息,抛出异常即可) + * + * @param message 消息内容 + * @param exception 异常信息 + */ + @Override + public void messageHandle(String message, Exception exception) { + String cacheKey = CACHE_PARAM.key() + Sm3Utils.encryptToString(message); + Long incr = redisService.incr(cacheKey); + redisService.expire(cacheKey, CACHE_PARAM.expireTime()); + if (incr >= CP_NUM3) { + redisService.del(cacheKey); + } else { + try { + Thread.sleep(CP_NUM1000); + } catch (InterruptedException e) { + log.error("消息处理异常,等待失败", e); + } + throw new RuntimeException(exception); + } + } +} diff --git a/xtools-app-common/xtools-app-common-sentinel/pom.xml b/xtools-app-common/xtools-app-common-sentinel/pom.xml new file mode 100644 index 0000000..42bf463 --- /dev/null +++ b/xtools-app-common/xtools-app-common-sentinel/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-sentinel + + + + + + + org.xujun + xtools-web + + + + + + + org.xujun + xtools-app-common-log-bus + + + + + + org.xujun + xtools-cloud-alibaba-sentinel + + + + + jakarta.servlet + jakarta.servlet-api + provided + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-sentinel/src/main/java/xtools/app/common/sentinel/SysBlockExceptionHandler.java b/xtools-app-common/xtools-app-common-sentinel/src/main/java/xtools/app/common/sentinel/SysBlockExceptionHandler.java new file mode 100644 index 0000000..5928a60 --- /dev/null +++ b/xtools-app-common/xtools-app-common-sentinel/src/main/java/xtools/app/common/sentinel/SysBlockExceptionHandler.java @@ -0,0 +1,62 @@ +package xtools.app.common.sentinel; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson2.JSONObject; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.cloud.alibaba.sentinel.handler.CustomBlockExceptionHandler; +import xtools.core.enums.LogLevel; +import xtools.web.HeaderUtils; + +/** + *

Title : SysBlockExceptionHandler

+ *

Description : SysBlockExceptionHandler

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : Windows11

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/14 21:54 + */ +@Component +public class SysBlockExceptionHandler implements CustomBlockExceptionHandler { + + /** + * 自定义Sentinel阻塞异常处理器 + * + * @param request HttpServletRequest + * @param response HttpServletResponse + * @param resourceName 资源名称 + * @param e BlockException + * @return 是否默认写出提示信息 + */ + @Override + public boolean handle( + HttpServletRequest request, + HttpServletResponse response, + String resourceName, + BlockException e + ) { + // 日志数据 + JSONObject log = new JSONObject(); + // IP + log.put("ip", HeaderUtils.getIp(request)); + // URI + log.put("uri", HeaderUtils.getAllUri(request)); + // 用户标识 + log.put("userAgent", HeaderUtils.getUserAgent(request)); + // 请求参数 + log.put("params", HeaderUtils.getParams(request)); + // 请求来源 + log.put("referer", HeaderUtils.getReferer(request)); + // 规则数据 + log.put("rule", e.getRule()); + // 保存日志 + LogBus.init(LogLevel.WARN, LogBusBaseType.SENTINEL).error(e).data(log).save(); + return true; + } +} diff --git a/xtools-app-common/xtools-app-common-task/pom.xml b/xtools-app-common/xtools-app-common-task/pom.xml new file mode 100644 index 0000000..47eaca0 --- /dev/null +++ b/xtools-app-common/xtools-app-common-task/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-common + 1.0.0 + + xtools-app-common-task + + + + + + + org.xujun + xtools-boot-task + + + + + + org.xujun + xtools-app-common-mq + + + + + \ No newline at end of file diff --git a/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/enums/TaskType.java b/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/enums/TaskType.java new file mode 100644 index 0000000..62a3496 --- /dev/null +++ b/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/enums/TaskType.java @@ -0,0 +1,93 @@ +package xtools.app.common.task.enums; + +import xtools.boot.api.enums.BaseEnum; +import xtools.boot.task.interfaces.BaseTaskType; + +/** + *

Title : TaskType

+ *

Description : TaskType

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 10:29 + */ +public enum TaskType implements BaseTaskType { + + // 其他任务 + OTHER(10, "其他任务"), + // 删除系统日志 + DEL_SYS_LOG(20, "删除系统日志"), + // 删除系统文件 + DEL_SYS_FILE(30, "删除系统文件"), + ; + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 初始化方法 + * + * @param code Code + * @param desc 说明 + */ + TaskType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 判断枚举值类型 + * + * @param code 枚举值 + * @return 枚举值类型 + */ + public static TaskType valueOf(int code) { + for (TaskType type : values()) { + if (type.code == code) { + return type; + } + } + throw new IllegalArgumentException("unknown code, code=" + code); + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + +} diff --git a/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/handle/TaskBusHandle.java b/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/handle/TaskBusHandle.java new file mode 100644 index 0000000..aa45fdc --- /dev/null +++ b/xtools-app-common/xtools-app-common-task/src/main/java/xtools/app/common/task/handle/TaskBusHandle.java @@ -0,0 +1,32 @@ +package xtools.app.common.task.handle; + +import org.springframework.stereotype.Component; +import xtools.app.common.mq.enums.RabbitMqEnums; +import xtools.boot.mq.base.utils.MqBus; +import xtools.boot.task.interfaces.TaskBusInterface; +import xtools.boot.task.model.dto.TaskInfo; + +/** + *

Title : TaskBusHandle

+ *

Description : TaskBusHandle

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 10:31 + */ +@Component +public class TaskBusHandle implements TaskBusInterface { + + /** + * 保存任务 + * + * @param taskInfo 任务 + */ + @Override + public void save(TaskInfo taskInfo) { + MqBus.push(RabbitMqEnums.SYS_TASK, taskInfo); + } +} diff --git a/xtools-app-gen/pom.xml b/xtools-app-gen/pom.xml new file mode 100644 index 0000000..19a8556 --- /dev/null +++ b/xtools-app-gen/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.xujun + xtools-app + 1.0.0 + + xtools-app-gen + pom + + + + xtools-app-gen-biz + xtools-app-gen-boot + + + \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/pom.xml b/xtools-app-gen/xtools-app-gen-biz/pom.xml new file mode 100644 index 0000000..8f96c75 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/pom.xml @@ -0,0 +1,119 @@ + + + 4.0.0 + + org.xujun + xtools-app-gen + 1.0.0 + + xtools-app-gen-biz + + + + + + dev + + true + + + + + org.xujun + xtools-boot-knife4j + + + + + + prod + + + + + + + + + org.xujun + xtools-extend + + + + org.xujun + xtools-boot-core + + + + org.xujun + xtools-boot-db-mybatis + + + + org.xujun + xtools-boot-db-mybatis-plus + + + + org.xujun + xtools-boot-mask + + + + org.xujun + xtools-boot-web-base + + + + org.xujun + xtools-boot-web-filter + + + + + + org.xujun + xtools-app-common-jar + + + org.xujun + xtools-app-common-log-bus + + + org.xujun + xtools-app-common-log-filter + + + + org.xujun + xtools-app-sys-auth + + + + + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-processor + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + org.apache.velocity + velocity-engine-core + + + + \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/GenProperties.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/GenProperties.java new file mode 100644 index 0000000..5860f75 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/GenProperties.java @@ -0,0 +1,124 @@ +package xtools.app.gen.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

Title : GenProperties

+ *

Description : 代码生成配置属性

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/20 08:43 + */ +@Data +@Component +@ConfigurationProperties(prefix = "gen") +public class GenProperties { + + + /** + * 后端应用名 + */ + private String backendAppName; + + /** + * 前端应用名 + */ + private String frontendAppName; + + /** + * 下载文件名 + */ + private String downloadFileName; + + /** + * 排除数据表 + */ + private List excludeTables; + + /** + * 默认配置 + */ + private DefaultConfig defaultConfig; + + /** + * 过滤配置 + */ + private FilterConfig filterConfig; + + /** + * 模板配置 + */ + private Map templateConfigs = new HashMap<>(16); + + /** + * 默认配置 + */ + @Data + public static class DefaultConfig { + /** + * 作者 + */ + private String author; + + /** + * 版本 + */ + private String version; + + /** + * 默认模块名 + */ + private String moduleName; + } + + /** + * 过滤配置 + */ + @Data + public static class FilterConfig { + + /** + * 列注释过滤(正则) + */ + private List columnRemarks; + + } + + /** + * 模板配置 + */ + @Data + public static class TemplateConfig { + + /** + * 模板路径 (e.g. /templates/codegen/controller.java.vm) + */ + private String templatePath; + + /** + * 子包名 (e.g. controller/service/mapper/model) + */ + private String subPackageName; + + /** + * 文件扩展名,如 .java + */ + private String extension = ".java"; + + /** + * 项目模块名 + */ + private String projectModule = "biz"; + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/VelocityConfig.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/VelocityConfig.java new file mode 100644 index 0000000..947096d --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/config/VelocityConfig.java @@ -0,0 +1,42 @@ +package xtools.app.gen.config; + +import org.apache.velocity.app.VelocityEngine; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +/** + *

Title : VelocityConfig

+ *

Description : VelocityConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/20 10:22 + */ +@Configuration +public class VelocityConfig { + + /** + * 创建 VelocityEngine 实例 + * + * @return VelocityEngine 实例 + */ + @Bean + public VelocityEngine velocityEngine() { + Properties properties = new Properties(); + + properties.setProperty("resource.loaders", "class"); + properties.setProperty("resource.loader.class.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + properties.setProperty("resource.default_encoding", "UTF-8"); + properties.setProperty("output.encoding", "UTF-8"); + + VelocityEngine velocityEngine = new VelocityEngine(); + velocityEngine.init(properties); + return velocityEngine; + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenDatasourceController.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenDatasourceController.java new file mode 100644 index 0000000..94a5ee1 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenDatasourceController.java @@ -0,0 +1,107 @@ +package xtools.app.gen.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.gen.model.dto.req.GenDatasourceAddReq; +import xtools.app.gen.model.dto.req.GenDatasourcePageReq; +import xtools.app.gen.model.dto.req.GenDatasourceUpdateReq; +import xtools.app.gen.model.dto.resp.GenDatasourceResp; +import xtools.app.gen.service.GenDatasourceService; +import xtools.app.gen.service.GenService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : GenDatasourceController

+ *

Description : GenDatasourceController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:33 + */ +@Tag(name = "代码生成-数据源模块") +@RestController +@RequiredArgsConstructor +@RequestMapping("/gen/datasource") +public class GenDatasourceController { + + private final GenDatasourceService genDatasourceService; + + private final GenService genService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return genDatasourceService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genDatasourceService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid GenDatasourceAddReq req) { + return genDatasourceService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid GenDatasourceUpdateReq req) { + return genDatasourceService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return genDatasourceService.delById(req.getIdList()); + } + + @Operation(summary = "测试连接") + @GetMapping("test-db/{id}") + public Result testDb( + @Schema(description = "数据源 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genService.testDb(id); + } + + @Operation(summary = "同步数据库") + @GetMapping("sync-db/{id}") + public Result syncDb( + @Schema(description = "数据源 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genService.syncDb(id); + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableColumnController.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableColumnController.java new file mode 100644 index 0000000..7e207e2 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableColumnController.java @@ -0,0 +1,93 @@ +package xtools.app.gen.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.gen.model.dto.req.GenTableColumnAddReq; +import xtools.app.gen.model.dto.req.GenTableColumnPageReq; +import xtools.app.gen.model.dto.req.GenTableColumnUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableColumnResp; +import xtools.app.gen.service.GenTableColumnService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : GenTableColumnController

+ *

Description : 代码生成字段配置表模块

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 11:20 + */ +@Tag(name = "代码生成-字段信息模块") +@RestController +@RequiredArgsConstructor +@RequestMapping("/gen/table-column") +public class GenTableColumnController { + + private final GenTableColumnService genTableColumnService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return genTableColumnService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genTableColumnService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid GenTableColumnAddReq req) { + return genTableColumnService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid GenTableColumnUpdateReq req) { + return genTableColumnService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return genTableColumnService.delById(req.getIdList()); + } + + @Operation(summary = "根据表 ID 删除字段信息") + @DeleteMapping("del-by-table-id/{id}") + public Result delByTableId( + @Schema(description = "表 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return Result.ok(genTableColumnService.deleteByTableId(id)); + } + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableController.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableController.java new file mode 100644 index 0000000..21909ca --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/controller/GenTableController.java @@ -0,0 +1,167 @@ +package xtools.app.gen.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.gen.model.dto.GenCodeDto; +import xtools.app.gen.model.dto.req.GenTableAddReq; +import xtools.app.gen.model.dto.req.GenTableInfoReq; +import xtools.app.gen.model.dto.req.GenTablePageReq; +import xtools.app.gen.model.dto.req.GenTableUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableInfoResp; +import xtools.app.gen.model.dto.resp.GenTableResp; +import xtools.app.gen.service.GenService; +import xtools.app.gen.service.GenTableService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + *

Title : GenTableController

+ *

Description : 代码生成配置表模块

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:30 + */ +@Tag(name = "代码生成-表信息模块") +@RestController +@RequiredArgsConstructor +@RequestMapping("/gen/table") +public class GenTableController { + + private final GenService genService; + + private final GenTableService genTableService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return genTableService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genTableService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid GenTableAddReq req) { + return genTableService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid GenTableUpdateReq req) { + return genTableService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return genTableService.delById(req.getIdList()); + } + + @Operation(summary = "根据数据源 ID 删除表信息") + @DeleteMapping("del-by-datasource-id/{id}") + public Result delByDatasourceId( + @Schema(description = "数据源 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genService.delTableAndColumnByDatasourceId(id); + } + + @Operation(summary = "同步数据库") + @GetMapping("sync-db/{id}") + public Result syncDb( + @Schema(description = "数据源 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genService.syncDb(id); + } + + @Operation(summary = "同步字段") + @GetMapping("sync-column/{id}") + public Result syncColumn( + @Schema(description = "表 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return genService.syncColumn(id); + } + + @Operation(summary = "获取表格信息") + @PostMapping("get-table-list") + public Result> getTableList(@RequestBody @Valid IdListReq req) { + return genService.getTableList(req.getIdList()); + } + + @Operation(summary = "保存表格信息") + @PostMapping("save-table-list") + public Result saveTableList(@RequestBody @Valid List req) { + return genService.saveTableList(req); + } + + @Operation(summary = "预览代码") + @PostMapping("preview-code") + public Result> previewCode(@RequestBody @Valid IdListReq req) { + return genService.previewCode(req.getIdList()); + } + + @Operation(summary = "下载代码") + @PostMapping("download-code") + public void downloadCode(HttpServletResponse response, @RequestBody @Valid IdListReq req) { + byte[] data = genService.downloadCode(req.getIdList()); + try (ServletOutputStream outputStream = response.getOutputStream()) { + // 设置返回内容格式 + response.setContentType("application/octet-stream"); + // 把文件名按UTF-8取出并按 ISO8859-1 编码,保证弹出窗口中的文件名中文不乱码 + // 中文不要太多,最多支持17个中文,因为header有150个字节限制 + // 这一步一定要在读取文件之后进行,否则文件名会乱码,找不到文件 + // 设置下载弹窗的文件名和格式(文件名要包括名字和文件格式) + String encodeName = URLEncoder.encode("code.zip", StandardCharsets.UTF_8); + response.setHeader("Content-Disposition", "attachment;filename=" + encodeName); + outputStream.write(data); + outputStream.flush(); + } catch (IOException e) { + throw new BizError("下载异常"); + } + } + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenConvert.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenConvert.java new file mode 100644 index 0000000..1904075 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenConvert.java @@ -0,0 +1,31 @@ +package xtools.app.gen.convert; + +import org.mapstruct.Mapper; +import xtools.app.gen.model.dto.resp.GenTableInfoResp; +import xtools.app.gen.model.entity.GenTable; + +import java.util.List; + +/** + *

Title : GenTableConvert

+ *

Description : GenTableConvert

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:10 + */ +@Mapper(componentModel = "spring") +public interface GenConvert { + + /** + * 表格列表转表格信息列表 + * + * @param genTableList 表格列表 + * @return 表格信息列表 + */ + List baseToGenTableInfoResp(List genTableList); + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenDatasourceConvert.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenDatasourceConvert.java new file mode 100644 index 0000000..a2cde1a --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenDatasourceConvert.java @@ -0,0 +1,57 @@ +package xtools.app.gen.convert; + +import org.mapstruct.Mapper; +import xtools.app.gen.model.dto.req.GenDatasourceAddReq; +import xtools.app.gen.model.dto.req.GenDatasourceUpdateReq; +import xtools.app.gen.model.dto.resp.GenDatasourceResp; +import xtools.app.gen.model.entity.GenDatasource; + +import java.util.List; + +/** + *

Title : GenDatasourceConvert

+ *

Description : GenDatasourceConvert

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:30 + */ +@Mapper(componentModel = "spring") +public interface GenDatasourceConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + GenDatasource addReqToEntity(GenDatasourceAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + GenDatasource updateReqToEntity(GenDatasourceUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + GenDatasourceResp entityToResp(GenDatasource data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableColumnConvert.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableColumnConvert.java new file mode 100644 index 0000000..111fda8 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableColumnConvert.java @@ -0,0 +1,65 @@ +package xtools.app.gen.convert; + +import org.mapstruct.Mapper; +import xtools.app.gen.model.dto.req.GenTableColumnAddReq; +import xtools.app.gen.model.dto.req.GenTableColumnUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableColumnResp; +import xtools.app.gen.model.entity.GenTableColumn; + +import java.util.List; + +/** + *

Title : GenTableColumnConvert

+ *

Description : GenTableColumnConvert

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:55 + */ +@Mapper(componentModel = "spring") +public interface GenTableColumnConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + GenTableColumn addReqToEntity(GenTableColumnAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + GenTableColumn updateReqToEntity(GenTableColumnUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + GenTableColumnResp entityToResp(GenTableColumn data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 批量修改请求转实体 + * + * @param req 批量修改请求 + * @return 批量实体 + */ + List updateReqToEntityList(List req); + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableConvert.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableConvert.java new file mode 100644 index 0000000..b7bf13b --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/convert/GenTableConvert.java @@ -0,0 +1,57 @@ +package xtools.app.gen.convert; + +import org.mapstruct.Mapper; +import xtools.app.gen.model.dto.req.GenTableAddReq; +import xtools.app.gen.model.dto.req.GenTableUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableResp; +import xtools.app.gen.model.entity.GenTable; + +import java.util.List; + +/** + *

Title : GenTableConvert

+ *

Description : GenTableConvert

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:10 + */ +@Mapper(componentModel = "spring") +public interface GenTableConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + GenTable addReqToEntity(GenTableAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + GenTable updateReqToEntity(GenTableUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + GenTableResp entityToResp(GenTable data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/FormTypeEnum.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/FormTypeEnum.java new file mode 100644 index 0000000..ffe9e45 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/FormTypeEnum.java @@ -0,0 +1,118 @@ +package xtools.app.gen.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : GenError

+ *

Description : GenError

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2025/12/23 16:53 + */ +public enum FormTypeEnum implements BaseEnum { + + /** + * 输入框 + */ + INPUT(1, "输入框"), + + /** + * 下拉框 + */ + SELECT(2, "下拉框"), + + /** + * 单选框 + */ + RADIO(3, "单选框"), + + /** + * 复选框 + */ + CHECK_BOX(4, "复选框"), + + /** + * 数字输入框 + */ + INPUT_NUMBER(5, "数字输入框"), + + /** + * 开关 + */ + SWITCH(6, "开关"), + + /** + * 文本域 + */ + TEXT_AREA(7, "文本域"), + + /** + * 日期时间框 + */ + DATE(8, "日期框"), + + /** + * 日期框 + */ + DATE_TIME(9, "日期时间框"), + + /** + * 隐藏域 + */ + HIDDEN(10, "隐藏域"); + + /** + * 编码 + **/ + private final int code; + + /** + * 说明 + **/ + private final String desc; + + /** + * 初始化方法 + * + * @param code Code + * @param desc 说明 + */ + FormTypeEnum(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/QueryTypeEnum.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/QueryTypeEnum.java new file mode 100644 index 0000000..0050eb8 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/enums/QueryTypeEnum.java @@ -0,0 +1,128 @@ +package xtools.app.gen.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : GenError

+ *

Description : GenError

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2025/12/23 16:53 + */ +public enum QueryTypeEnum implements BaseEnum { + + /** + * 等于 + */ + EQ(1, "="), + + /** + * 模糊匹配 + */ + LIKE(2, "LIKE '%s%'"), + + /** + * 包含 + */ + IN(3, "IN"), + + /** + * 范围 + */ + BETWEEN(4, "BETWEEN"), + + /** + * 大于 + */ + GT(5, ">"), + + /** + * 大于等于 + */ + GE(6, ">="), + + /** + * 小于 + */ + LT(7, "<"), + + /** + * 小于等于 + */ + LE(8, "<="), + + /** + * 不等于 + */ + NE(9, "!="), + + /** + * 左模糊匹配 + */ + LIKE_LEFT(10, "LIKE '%s'"), + + /** + * 右模糊匹配 + */ + LIKE_RIGHT(11, "LIKE 's%'"), + + /** + * 时间范围 + */ + TIME_RANGE(12, "utils"); + + /** + * 编码 + **/ + private final int code; + + /** + * 说明 + **/ + private final String desc; + + /** + * 初始化方法 + * + * @param code Code + * @param desc 说明 + */ + QueryTypeEnum(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenDatasourceMapper.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenDatasourceMapper.java new file mode 100644 index 0000000..df1a9b1 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenDatasourceMapper.java @@ -0,0 +1,20 @@ +package xtools.app.gen.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.gen.model.entity.GenDatasource; + +/** + *

Title : GenDatasourceMapper

+ *

Description : GenDatasourceMapper

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:12 + */ +@Mapper +public interface GenDatasourceMapper extends BaseMapper { +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableColumnMapper.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..c9bc502 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableColumnMapper.java @@ -0,0 +1,20 @@ +package xtools.app.gen.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.gen.model.entity.GenTableColumn; + +/** + *

Title : GenTableColumnMapper

+ *

Description : GenTableColumnMapper

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 11:00 + */ +@Mapper +public interface GenTableColumnMapper extends BaseMapper { +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableMapper.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableMapper.java new file mode 100644 index 0000000..3699f0f --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/mapper/GenTableMapper.java @@ -0,0 +1,20 @@ +package xtools.app.gen.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.gen.model.entity.GenTable; + +/** + *

Title : GenTableMapper

+ *

Description : GenTableMapper

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:35 + */ +@Mapper +public interface GenTableMapper extends BaseMapper { +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/GenCodeDto.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/GenCodeDto.java new file mode 100644 index 0000000..92cd7d3 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/GenCodeDto.java @@ -0,0 +1,43 @@ +package xtools.app.gen.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenCodeDto

+ *

Description : GenCodeDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/21 08:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenCodeDto implements Serializable { + + /** + * 路径 + */ + @Schema(description = "路径", example = "/gen/code/") + private String path; + + /** + * 文件名 + */ + @Schema(description = "文件名", example = "UserController.java") + private String fileName; + + /** + * 内容 + */ + @Schema(description = "内容", example = "public class Test {}") + private String content; +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceAddReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceAddReq.java new file mode 100644 index 0000000..2f68c39 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceAddReq.java @@ -0,0 +1,83 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenDatasourceAddReq

+ *

Description : 数据源信息添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenDatasourceAddReq implements Serializable { + + /** + * 数据源名称 + */ + @Schema(description = "数据源名称", example = "test_db") + private String dbName; + + /** + * 数据库类型[1.MySQL,2.PostgreSQL] + */ + @Schema(description = "数据库类型[1.MySQL,2.PostgreSQL]", example = "1") + private Integer dbType; + + /** + * JDBC 连接地址 + */ + @Schema(description = "JDBC 连接地址", example = "jdbc:mysql://localhost:3306/testdb") + private String jdbcUrl; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "root") + private String username; + + /** + * 密码 + */ + @Schema(description = "密码", example = "password123") + private String password; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 子模块名 + */ + @Schema(description = "子模块名", example = "user") + private String subModuleName; + + /** + * 包路径 + */ + @Schema(description = "包路径", example = "com.example.project") + private String packageName; + + /** + * 状态[1.正常,0.停用] + */ + @Schema(description = "状态[1.正常,0.停用]", example = "1") + private Integer status; + + /** + * 备注 + */ + @Schema(description = "备注", example = "测试数据源") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourcePageReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourcePageReq.java new file mode 100644 index 0000000..4daebab --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourcePageReq.java @@ -0,0 +1,102 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : GenDatasourcePageReq

+ *

Description : 数据源信息分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:06 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenDatasourcePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源名称 + */ + @Schema(description = "数据源名称", example = "test_db") + private String dbName; + + /** + * 数据库类型[1.MySQL,2.PostgreSQL] + */ + @Schema(description = "数据库类型[1.MySQL,2.PostgreSQL]", example = "1") + private Integer dbType; + + /** + * JDBC 连接地址 + */ + @Schema(description = "JDBC 连接地址", example = "jdbc:mysql://localhost:3306/testdb") + private String jdbcUrl; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "root") + private String username; + + /** + * 密码 + */ + @Schema(description = "密码", example = "password123") + private String password; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 子模块名 + */ + @Schema(description = "子模块名", example = "user") + private String subModuleName; + + /** + * 包路径 + */ + @Schema(description = "包路径", example = "com.example.project") + private String packageName; + + /** + * 状态[1.正常,0.停用] + */ + @Schema(description = "状态[1.正常,0.停用]", example = "1") + private Integer status; + + /** + * 备注 + */ + @Schema(description = "备注", example = "测试数据源") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceUpdateReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceUpdateReq.java new file mode 100644 index 0000000..b2eeae9 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenDatasourceUpdateReq.java @@ -0,0 +1,89 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenDatasourceUpdateReq

+ *

Description : 数据源信息更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:06 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenDatasourceUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源名称 + */ + @Schema(description = "数据源名称", example = "test_db") + private String dbName; + + /** + * 数据库类型[1.MySQL,2.PostgreSQL] + */ + @Schema(description = "数据库类型[1.MySQL,2.PostgreSQL]", example = "1") + private Integer dbType; + + /** + * JDBC 连接地址 + */ + @Schema(description = "JDBC 连接地址", example = "jdbc:mysql://localhost:3306/testdb") + private String jdbcUrl; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "root") + private String username; + + /** + * 密码 + */ + @Schema(description = "密码", example = "password123") + private String password; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 子模块名 + */ + @Schema(description = "子模块名", example = "user") + private String subModuleName; + + /** + * 包路径 + */ + @Schema(description = "包路径", example = "com.example.project") + private String packageName; + + /** + * 状态[1.正常,0.停用] + */ + @Schema(description = "状态[1.正常,0.停用]", example = "1") + private Integer status; + + /** + * 备注 + */ + @Schema(description = "备注", example = "测试数据源") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableAddReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableAddReq.java new file mode 100644 index 0000000..cfe0d1a --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableAddReq.java @@ -0,0 +1,107 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenTableAddReq

+ *

Description : 表信息添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenTableAddReq implements Serializable { + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表名 + */ + @Schema(description = "表名", example = "sys_user") + private String tableName; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 包名 + */ + @Schema(description = "包名", example = "com.example.project") + private String packageName; + + /** + * 业务名 + */ + @Schema(description = "业务名", example = "用户管理") + private String businessName; + + /** + * 实体类名 + */ + @Schema(description = "实体类名", example = "SysUser") + private String entityName; + + /** + * 属性名 + */ + @Schema(description = "属性名", example = "sysUser") + private String propName; + + /** + * 作者 + */ + @Schema(description = "作者", example = "XuJun") + private String author; + + /** + * 上级菜单ID,对应sys_menu的id + */ + @Schema(description = "上级菜单ID,对应sys_menu的id", example = "100") + private String parentMenuId; + + /** + * 表格操作 + */ + @Schema(description = "表格操作") + private Integer excelOpt; + + /** + * 打开微服务API[0.关闭,1.打开] + */ + @Schema(description = "打开微服务API[0.关闭,1.打开]") + private Integer openApi; + + /** + * 要移除的表前缀,如: sys_ + */ + @Schema(description = "要移除的表前缀,如: sys_", example = "sys_") + private String removeTablePrefix; + + /** + * 页面类型[classic|curd] + */ + @Schema(description = "页面类型[classic|curd]", example = "curd") + private String pageType; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统用户表") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnAddReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnAddReq.java new file mode 100644 index 0000000..b9f3bab --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnAddReq.java @@ -0,0 +1,155 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenTableColumnAddReq

+ *

Description : 表字段信息添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenTableColumnAddReq implements Serializable { + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表 ID + */ + @Schema(description = "表 ID", example = "1") + private Long tableId; + + /** + * 是否主键[1.主键,0.非主键] + */ + @Schema(description = "是否主键[1.主键,0.非主键]", example = "1") + private Integer isPk; + + /** + * 数据库列名 + */ + @Schema(description = "数据库列名", example = "user_id") + private String columnName; + + /** + * 数据库列类型 + */ + @Schema(description = "数据库列类型", example = "varchar(64)") + private String columnType; + + /** + * 数据库列长度 + */ + @Schema(description = "数据库列长度", example = "64") + private Integer columnLength; + + /** + * 字段名称 + */ + @Schema(description = "字段名称", example = "userId") + private String fieldName; + + /** + * 字段类型 + */ + @Schema(description = "字段类型", example = "String") + private String fieldType; + + /** + * 字段排序 + */ + @Schema(description = "字段排序", example = "1") + private Integer fieldSort; + + /** + * 字段描述 + */ + @Schema(description = "字段描述", example = "用户ID") + private String fieldComment; + + /** + * 方法名 + */ + @Schema(description = "方法名", example = "getUserId") + private String funName; + + /** + * 最大长度 + */ + @Schema(description = "最大长度", example = "64") + private Integer maxLength; + + /** + * 是否必填[1.是,0.否] + */ + @Schema(description = "是否必填[1.是,0.否]", example = "true") + private Integer isRequired; + + /** + * 是否在列表显示[1.是,0.否] + */ + @Schema(description = "是否在列表显示[1.是,0.否]", example = "true") + private Integer isShowInList; + + /** + * 是否在表单显示[1.是,0.否] + */ + @Schema(description = "是否在表单显示[1.是,0.否]", example = "true") + private Integer isShowInForm; + + /** + * 是否在查询条件显示[1.是,0.否] + */ + @Schema(description = "是否在查询条件显示[1.是,0.否]", example = "true") + private Integer isShowInQuery; + + /** + * 查询方式 + */ + @Schema(description = "查询方式", example = "1") + private Integer queryType; + + /** + * 表单类型 + */ + @Schema(description = "表单类型", example = "1") + private Integer formType; + + /** + * 字典类型 + */ + @Schema(description = "字典类型", example = "user_type") + private String dictType; + + /** + * 脱敏类型 + */ + @Schema(description = "脱敏类型", example = "OFF") + private String maskType; + + /** + * 扩展字段[1.是,0.否] + */ + @Schema(description = "扩展字段[1.是,0.否]", example = "false") + private Integer ext; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户标识字段") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnPageReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnPageReq.java new file mode 100644 index 0000000..753b8df --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnPageReq.java @@ -0,0 +1,174 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : GenTableColumnPageReq

+ *

Description : 表字段信息分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenTableColumnPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表 ID + */ + @Schema(description = "表 ID", example = "1") + private Long tableId; + + /** + * 是否主键[1.主键,0.非主键] + */ + @Schema(description = "是否主键[1.主键,0.非主键]", example = "1") + private Integer isPk; + + /** + * 数据库列名 + */ + @Schema(description = "数据库列名", example = "user_id") + private String columnName; + + /** + * 数据库列类型 + */ + @Schema(description = "数据库列类型", example = "varchar(64)") + private String columnType; + + /** + * 数据库列长度 + */ + @Schema(description = "数据库列长度", example = "64") + private Integer columnLength; + + /** + * 字段名称 + */ + @Schema(description = "字段名称", example = "userId") + private String fieldName; + + /** + * 字段类型 + */ + @Schema(description = "字段类型", example = "String") + private String fieldType; + + /** + * 字段排序 + */ + @Schema(description = "字段排序", example = "1") + private Integer fieldSort; + + /** + * 字段描述 + */ + @Schema(description = "字段描述", example = "用户ID") + private String fieldComment; + + /** + * 方法名 + */ + @Schema(description = "方法名", example = "getUserId") + private String funName; + + /** + * 最大长度 + */ + @Schema(description = "最大长度", example = "64") + private Integer maxLength; + + /** + * 是否必填[1.是,0.否] + */ + @Schema(description = "是否必填[1.是,0.否]", example = "true") + private Integer isRequired; + + /** + * 是否在列表显示[1.是,0.否] + */ + @Schema(description = "是否在列表显示[1.是,0.否]", example = "true") + private Integer isShowInList; + + /** + * 是否在表单显示[1.是,0.否] + */ + @Schema(description = "是否在表单显示[1.是,0.否]", example = "true") + private Integer isShowInForm; + + /** + * 是否在查询条件显示[1.是,0.否] + */ + @Schema(description = "是否在查询条件显示[1.是,0.否]", example = "true") + private Integer isShowInQuery; + + /** + * 查询方式 + */ + @Schema(description = "查询方式", example = "1") + private Integer queryType; + + /** + * 表单类型 + */ + @Schema(description = "表单类型", example = "1") + private Integer formType; + + /** + * 字典类型 + */ + @Schema(description = "字典类型", example = "user_type") + private String dictType; + + /** + * 脱敏类型 + */ + @Schema(description = "脱敏类型", example = "OFF") + private String maskType; + + /** + * 扩展字段[1.是,0.否] + */ + @Schema(description = "扩展字段[1.是,0.否]", example = "false") + private Integer ext; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户标识字段") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnUpdateReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnUpdateReq.java new file mode 100644 index 0000000..e89865b --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableColumnUpdateReq.java @@ -0,0 +1,161 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenTableColumnUpdateReq

+ *

Description : 表字段信息更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GenTableColumnUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表 ID + */ + @Schema(description = "表 ID", example = "1") + private Long tableId; + + /** + * 是否主键[1.主键,0.非主键] + */ + @Schema(description = "是否主键[1.主键,0.非主键]", example = "1") + private Integer isPk; + + /** + * 数据库列名 + */ + @Schema(description = "数据库列名", example = "user_id") + private String columnName; + + /** + * 数据库列类型 + */ + @Schema(description = "数据库列类型", example = "varchar(64)") + private String columnType; + + /** + * 数据库列长度 + */ + @Schema(description = "数据库列长度", example = "64") + private Integer columnLength; + + /** + * 字段名称 + */ + @Schema(description = "字段名称", example = "userId") + private String fieldName; + + /** + * 字段类型 + */ + @Schema(description = "字段类型", example = "String") + private String fieldType; + + /** + * 字段排序 + */ + @Schema(description = "字段排序", example = "1") + private Integer fieldSort; + + /** + * 字段描述 + */ + @Schema(description = "字段描述", example = "用户ID") + private String fieldComment; + + /** + * 方法名 + */ + @Schema(description = "方法名", example = "getUserId") + private String funName; + + /** + * 最大长度 + */ + @Schema(description = "最大长度", example = "64") + private Integer maxLength; + + /** + * 是否必填[1.是,0.否] + */ + @Schema(description = "是否必填[1.是,0.否]", example = "true") + private Integer isRequired; + + /** + * 是否在列表显示[1.是,0.否] + */ + @Schema(description = "是否在列表显示[1.是,0.否]", example = "true") + private Integer isShowInList; + + /** + * 是否在表单显示[1.是,0.否] + */ + @Schema(description = "是否在表单显示[1.是,0.否]", example = "true") + private Integer isShowInForm; + + /** + * 是否在查询条件显示[1.是,0.否] + */ + @Schema(description = "是否在查询条件显示[1.是,0.否]", example = "true") + private Integer isShowInQuery; + + /** + * 查询方式 + */ + @Schema(description = "查询方式", example = "1") + private Integer queryType; + + /** + * 表单类型 + */ + @Schema(description = "表单类型", example = "1") + private Integer formType; + + /** + * 字典类型 + */ + @Schema(description = "字典类型", example = "user_type") + private String dictType; + + /** + * 脱敏类型 + */ + @Schema(description = "脱敏类型", example = "OFF") + private String maskType; + + /** + * 扩展字段[1.是,0.否] + */ + @Schema(description = "扩展字段[1.是,0.否]", example = "false") + private Integer ext; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户标识字段") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableInfoReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableInfoReq.java new file mode 100644 index 0000000..49e831f --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableInfoReq.java @@ -0,0 +1,32 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

Title : GenTableInfoReq

+ *

Description : 表信息请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-20 20:32:22 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class GenTableInfoReq extends GenTableUpdateReq { + + /** + * 字段列表 + */ + @Schema(description = "字段列表", example = "[{\"columnName\": \"user_id\", \"fieldName\": \"userId\", \"fieldType\": \"Long\"}]") + private List columnList; + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTablePageReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTablePageReq.java new file mode 100644 index 0000000..78e2b5d --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTablePageReq.java @@ -0,0 +1,127 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : GenTablePageReq

+ *

Description : 表信息分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data + +@NoArgsConstructor +@AllArgsConstructor +public class GenTablePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表名 + */ + @Schema(description = "表名", example = "sys_user") + private String tableName; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 包名 + */ + @Schema(description = "包名", example = "com.example.project") + private String packageName; + + /** + * 业务名 + */ + @Schema(description = "业务名", example = "用户管理") + private String businessName; + + /** + * 实体类名 + */ + @Schema(description = "实体类名", example = "SysUser") + private String entityName; + + /** + * 属性名 + */ + @Schema(description = "属性名", example = "sysUser") + private String propName; + + /** + * 作者 + */ + @Schema(description = "作者", example = "XuJun") + private String author; + + /** + * 上级菜单ID,对应sys_menu的id + */ + @Schema(description = "上级菜单ID,对应sys_menu的id", example = "100") + private String parentMenuId; + + /** + * 表格操作 + */ + @Schema(description = "表格操作") + private Integer excelOpt; + + /** + * 打开微服务API[0.关闭,1.打开] + */ + @Schema(description = "打开微服务API[0.关闭,1.打开]") + private Integer openApi; + + /** + * 要移除的表前缀,如: sys_ + */ + @Schema(description = "要移除的表前缀,如: sys_", example = "sys_") + private String removeTablePrefix; + + /** + * 页面类型[classic|curd] + */ + @Schema(description = "页面类型[classic|curd]", example = "curd") + private String pageType; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统用户表") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableUpdateReq.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableUpdateReq.java new file mode 100644 index 0000000..5118861 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/req/GenTableUpdateReq.java @@ -0,0 +1,114 @@ +package xtools.app.gen.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : GenTableUpdateReq

+ *

Description : 表信息更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data + +@NoArgsConstructor +@AllArgsConstructor +public class GenTableUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表名 + */ + @Schema(description = "表名", example = "sys_user") + private String tableName; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 包名 + */ + @Schema(description = "包名", example = "com.example.project") + private String packageName; + + /** + * 业务名 + */ + @Schema(description = "业务名", example = "用户管理") + private String businessName; + + /** + * 实体类名 + */ + @Schema(description = "实体类名", example = "SysUser") + private String entityName; + + /** + * 属性名 + */ + @Schema(description = "属性名", example = "sysUser") + private String propName; + + /** + * 作者 + */ + @Schema(description = "作者", example = "XuJun") + private String author; + + /** + * 上级菜单ID,对应sys_menu的id + */ + @Schema(description = "上级菜单ID,对应sys_menu的id", example = "100") + private String parentMenuId; + + /** + * 表格操作 + */ + @Schema(description = "表格操作") + private Integer excelOpt; + + /** + * 打开微服务API[0.关闭,1.打开] + */ + @Schema(description = "打开微服务API[0.关闭,1.打开]") + private Integer openApi; + + /** + * 要移除的表前缀,如: sys_ + */ + @Schema(description = "要移除的表前缀,如: sys_", example = "sys_") + private String removeTablePrefix; + + /** + * 页面类型[classic|curd] + */ + @Schema(description = "页面类型[classic|curd]", example = "curd") + private String pageType; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统用户表") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenDatasourceResp.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenDatasourceResp.java new file mode 100644 index 0000000..ff30c7f --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenDatasourceResp.java @@ -0,0 +1,93 @@ +package xtools.app.gen.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; +import xtools.boot.mask.anntation.Mask; +import xtools.boot.mask.enums.MaskType; + +/** + *

Title : GenDatasourceResp

+ *

Description : 数据源信息响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:06 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class GenDatasourceResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源名称 + */ + @Schema(description = "数据源名称", example = "test_db") + private String dbName; + + /** + * 数据库类型[1.MySQL,2.PostgreSQL] + */ + @Schema(description = "数据库类型[1.MySQL,2.PostgreSQL]", example = "1") + private Integer dbType; + + /** + * JDBC 连接地址 + */ + @Schema(description = "JDBC 连接地址", example = "jdbc:mysql://localhost:3306/testdb") + private String jdbcUrl; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "root") + private String username; + + /** + * 密码 + */ + @Mask(MaskType.PASSWORD) + @Schema(description = "密码", example = "password123") + private String password; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 子模块名 + */ + @Schema(description = "子模块名", example = "user") + private String subModuleName; + + /** + * 包路径 + */ + @Schema(description = "包路径", example = "com.example.project") + private String packageName; + + /** + * 状态[1.正常,0.停用] + */ + @Schema(description = "状态[1.正常,0.停用]", example = "1") + private Integer status; + + /** + * 备注 + */ + @Schema(description = "备注", example = "测试数据源") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableColumnResp.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableColumnResp.java new file mode 100644 index 0000000..bf89e92 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableColumnResp.java @@ -0,0 +1,162 @@ +package xtools.app.gen.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : GenTableColumnResp

+ *

Description : 表字段信息响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class GenTableColumnResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表 ID + */ + @Schema(description = "表 ID", example = "1") + private Long tableId; + + /** + * 是否主键[1.主键,0.非主键] + */ + @Schema(description = "是否主键[1.主键,0.非主键]", example = "1") + private Integer isPk; + + /** + * 数据库列名 + */ + @Schema(description = "数据库列名", example = "user_id") + private String columnName; + + /** + * 数据库列类型 + */ + @Schema(description = "数据库列类型", example = "varchar(64)") + private String columnType; + + /** + * 数据库列长度 + */ + @Schema(description = "数据库列长度", example = "64") + private Integer columnLength; + + /** + * 字段名称 + */ + @Schema(description = "字段名称", example = "userId") + private String fieldName; + + /** + * 字段类型 + */ + @Schema(description = "字段类型", example = "String") + private String fieldType; + + /** + * 字段排序 + */ + @Schema(description = "字段排序", example = "1") + private Integer fieldSort; + + /** + * 字段描述 + */ + @Schema(description = "字段描述", example = "用户ID") + private String fieldComment; + + /** + * 方法名 + */ + @Schema(description = "方法名", example = "getUserId") + private String funName; + + /** + * 最大长度 + */ + @Schema(description = "最大长度", example = "64") + private Integer maxLength; + + /** + * 是否必填[1.是,0.否] + */ + @Schema(description = "是否必填[1.是,0.否]", example = "true") + private Integer isRequired; + + /** + * 是否在列表显示[1.是,0.否] + */ + @Schema(description = "是否在列表显示[1.是,0.否]", example = "true") + private Integer isShowInList; + + /** + * 是否在表单显示[1.是,0.否] + */ + @Schema(description = "是否在表单显示[1.是,0.否]", example = "true") + private Integer isShowInForm; + + /** + * 是否在查询条件显示[1.是,0.否] + */ + @Schema(description = "是否在查询条件显示[1.是,0.否]", example = "true") + private Integer isShowInQuery; + + /** + * 查询方式 + */ + @Schema(description = "查询方式", example = "1") + private Integer queryType; + + /** + * 表单类型 + */ + @Schema(description = "表单类型", example = "1") + private Integer formType; + + /** + * 字典类型 + */ + @Schema(description = "字典类型", example = "user_type") + private String dictType; + + /** + * 脱敏类型 + */ + @Schema(description = "脱敏类型", example = "OFF") + private String maskType; + + /** + * 扩展字段[1.是,0.否] + */ + @Schema(description = "扩展字段[1.是,0.否]", example = "false") + private Integer ext; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户标识字段") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableInfoResp.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableInfoResp.java new file mode 100644 index 0000000..0d86f5c --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableInfoResp.java @@ -0,0 +1,32 @@ +package xtools.app.gen.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

Title : GenTableInfoResp

+ *

Description : 表信息响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-20 20:32:22 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class GenTableInfoResp extends GenTableResp { + + /** + * 字段列表 + */ + @Schema(description = "字段列表") + private List columnList; + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableResp.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableResp.java new file mode 100644 index 0000000..161bf45 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/dto/resp/GenTableResp.java @@ -0,0 +1,115 @@ +package xtools.app.gen.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : GenTableResp

+ *

Description : 表信息响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class GenTableResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID", example = "1") + private Long datasourceId; + + /** + * 表名 + */ + @Schema(description = "表名", example = "sys_user") + private String tableName; + + /** + * 模块名 + */ + @Schema(description = "模块名", example = "system") + private String moduleName; + + /** + * 包名 + */ + @Schema(description = "包名", example = "com.example.project") + private String packageName; + + /** + * 业务名 + */ + @Schema(description = "业务名", example = "用户管理") + private String businessName; + + /** + * 实体类名 + */ + @Schema(description = "实体类名", example = "SysUser") + private String entityName; + + /** + * 属性名 + */ + @Schema(description = "属性名", example = "sysUser") + private String propName; + + /** + * 作者 + */ + @Schema(description = "作者", example = "XuJun") + private String author; + + /** + * 上级菜单ID,对应sys_menu的id + */ + @Schema(description = "上级菜单ID,对应sys_menu的id", example = "100") + private String parentMenuId; + + /** + * 表格操作 + */ + @Schema(description = "表格操作") + private Integer excelOpt; + + /** + * 打开微服务API[0.关闭,1.打开] + */ + @Schema(description = "打开微服务API[0.关闭,1.打开]") + private Integer openApi; + + /** + * 要移除的表前缀,如: sys_ + */ + @Schema(description = "要移除的表前缀,如: sys_", example = "sys_") + private String removeTablePrefix; + + /** + * 页面类型[classic|curd] + */ + @Schema(description = "页面类型[classic|curd]", example = "curd") + private String pageType; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统用户表") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenDatasource.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenDatasource.java new file mode 100644 index 0000000..c25a15c --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenDatasource.java @@ -0,0 +1,106 @@ +package xtools.app.gen.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : GenDatasource

+ *

Description : 数据源信息实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("gen_datasource") +public class GenDatasource extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 数据源名称 + */ + @Schema(description = "数据源名称") + @TableField(value = "db_name") + private String dbName; + + /** + * 数据库类型[1.MySQL,2.PostgreSQL] + */ + @Schema(description = "数据库类型[1.MySQL,2.PostgreSQL]") + @TableField(value = "db_type") + private Integer dbType; + + /** + * JDBC 连接地址 + */ + @Schema(description = "JDBC 连接地址") + @TableField(value = "jdbc_url") + private String jdbcUrl; + + /** + * 用户名 + */ + @Schema(description = "用户名") + @TableField(value = "username") + private String username; + + /** + * 密码 + */ + @Schema(description = "密码") + @TableField(value = "password") + private String password; + + /** + * 模块名 + */ + @Schema(description = "模块名") + @TableField(value = "module_name") + private String moduleName; + + /** + * 子模块名 + */ + @Schema(description = "子模块名") + @TableField(value = "sub_module_name") + private String subModuleName; + + /** + * 包路径 + */ + @Schema(description = "包路径") + @TableField(value = "package_name") + private String packageName; + + /** + * 状态[1.正常,0.停用] + */ + @Schema(description = "状态[1.正常,0.停用]") + @TableField(value = "status") + private Integer status; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTable.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTable.java new file mode 100644 index 0000000..49c13f7 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTable.java @@ -0,0 +1,134 @@ +package xtools.app.gen.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : GenTable

+ *

Description : 表信息实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-24 22:01:05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("gen_table") +public class GenTable extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID") + @TableField(value = "datasource_id") + private Long datasourceId; + + /** + * 表名 + */ + @Schema(description = "表名") + @TableField(value = "table_name") + private String tableName; + + /** + * 模块名 + */ + @Schema(description = "模块名") + @TableField(value = "module_name") + private String moduleName; + + /** + * 包名 + */ + @Schema(description = "包名") + @TableField(value = "package_name") + private String packageName; + + /** + * 业务名 + */ + @Schema(description = "业务名") + @TableField(value = "business_name") + private String businessName; + + /** + * 实体类名 + */ + @Schema(description = "实体类名") + @TableField(value = "entity_name") + private String entityName; + + /** + * 属性名 + */ + @Schema(description = "属性名") + @TableField(value = "prop_name") + private String propName; + + /** + * 作者 + */ + @Schema(description = "作者") + @TableField(value = "author") + private String author; + + /** + * 上级菜单ID,对应sys_menu的id + */ + @Schema(description = "上级菜单ID,对应sys_menu的id") + @TableField(value = "parent_menu_id") + private String parentMenuId; + + /** + * 表格操作 + */ + @Schema(description = "表格操作") + @TableField(value = "excel_opt") + private Integer excelOpt; + + /** + * 打开微服务API[0.关闭,1.打开] + */ + @Schema(description = "打开微服务API[0.关闭,1.打开]") + @TableField(value = "open_api") + private Integer openApi; + + /** + * 要移除的表前缀,如: sys_ + */ + @Schema(description = "要移除的表前缀,如: sys_") + @TableField(value = "remove_table_prefix") + private String removeTablePrefix; + + /** + * 页面类型[classic|curd] + */ + @Schema(description = "页面类型[classic|curd]") + @TableField(value = "page_type") + private String pageType; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTableColumn.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTableColumn.java new file mode 100644 index 0000000..f1a1109 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/model/entity/GenTableColumn.java @@ -0,0 +1,190 @@ +package xtools.app.gen.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : GenTableColumn

+ *

Description : 表字段信息实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-25 14:16:11 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("gen_table_column") +public class GenTableColumn extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 数据源 ID + */ + @Schema(description = "数据源 ID") + @TableField(value = "datasource_id") + private Long datasourceId; + + /** + * 表 ID + */ + @Schema(description = "表 ID") + @TableField(value = "table_id") + private Long tableId; + + /** + * 是否主键 + */ + @Schema(description = "是否主键") + @TableField(value = "is_pk") + private Integer isPk; + + /** + * 数据库列名 + */ + @Schema(description = "数据库列名") + @TableField(value = "column_name") + private String columnName; + + /** + * 数据库列类型 + */ + @Schema(description = "数据库列类型") + @TableField(value = "column_type") + private String columnType; + + /** + * 数据库列长度 + */ + @Schema(description = "数据库列长度") + @TableField(value = "column_length") + private Integer columnLength; + + /** + * 字段名称 + */ + @Schema(description = "字段名称") + @TableField(value = "field_name") + private String fieldName; + + /** + * 字段类型 + */ + @Schema(description = "字段类型") + @TableField(value = "field_type") + private String fieldType; + + /** + * 字段排序 + */ + @Schema(description = "字段排序") + @TableField(value = "field_sort") + private Integer fieldSort; + + /** + * 字段描述 + */ + @Schema(description = "字段描述") + @TableField(value = "field_comment") + private String fieldComment; + + /** + * 方法名 + */ + @Schema(description = "方法名") + @TableField(value = "fun_name") + private String funName; + + /** + * 最大长度 + */ + @Schema(description = "最大长度") + @TableField(value = "max_length") + private Integer maxLength; + + /** + * 是否必填 + */ + @Schema(description = "是否必填") + @TableField(value = "is_required") + private Integer isRequired; + + /** + * 是否在列表显示 + */ + @Schema(description = "是否在列表显示") + @TableField(value = "is_show_in_list") + private Integer isShowInList; + + /** + * 是否在表单显示 + */ + @Schema(description = "是否在表单显示") + @TableField(value = "is_show_in_form") + private Integer isShowInForm; + + /** + * 是否在查询条件显示 + */ + @Schema(description = "是否在查询条件显示") + @TableField(value = "is_show_in_query") + private Integer isShowInQuery; + + /** + * 查询方式 + */ + @Schema(description = "查询方式") + @TableField(value = "query_type") + private Integer queryType; + + /** + * 表单类型 + */ + @Schema(description = "表单类型") + @TableField(value = "form_type") + private Integer formType; + + /** + * 字典类型 + */ + @Schema(description = "字典类型") + @TableField(value = "dict_type") + private String dictType; + + /** + * 脱敏类型 + */ + @Schema(description = "脱敏类型") + @TableField(value = "mask_type") + private String maskType; + + /** + * 扩展字段 + */ + @Schema(description = "扩展字段") + @TableField(value = "ext") + private Integer ext; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenDatasourceService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenDatasourceService.java new file mode 100644 index 0000000..2398aaa --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenDatasourceService.java @@ -0,0 +1,66 @@ +package xtools.app.gen.service; + +import xtools.app.gen.model.dto.req.GenDatasourceAddReq; +import xtools.app.gen.model.dto.req.GenDatasourcePageReq; +import xtools.app.gen.model.dto.req.GenDatasourceUpdateReq; +import xtools.app.gen.model.dto.resp.GenDatasourceResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : GenDatasourceService

+ *

Description : GenDatasourceService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:14 + */ +public interface GenDatasourceService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(GenDatasourceAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(GenDatasourceUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenService.java new file mode 100644 index 0000000..dcda101 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenService.java @@ -0,0 +1,111 @@ +package xtools.app.gen.service; + +import xtools.app.gen.model.dto.GenCodeDto; +import xtools.app.gen.model.dto.req.GenTableInfoReq; +import xtools.app.gen.model.dto.resp.GenTableInfoResp; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : GenService

+ *

Description : GenService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/20 08:43 + */ +public interface GenService { + + /** + * 删除数据源下的所有表信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + Result delTableAndColumnByDatasourceId(Long datasourceId); + + /** + * 测试连接 + * + * @param id 数据源 ID + * @return 测试结果 + */ + Result testDb(Long id); + + /** + * 同步数据库 + * + * @param id 数据源 ID + * @return 同步结果 + */ + Result syncDb(Long id); + + /** + * 同步表字段 + * + * @param id 表 ID + * @return 同步结果 + */ + Result syncColumn(Long id); + + /** + * 获取表信息列表 + * + * @param idList 表 ID 列表 + * @return 表信息列表 + */ + Result> getTableList(List idList); + + /** + * 保存表信息列表 + * + * @param req 表信息列表 + * @return 保存结果 + */ + Result saveTableList(List req); + + /** + * 预览代码 + * + * @param idList 表 ID 列表 + * @return 预览结果 + */ + Result> previewCode(List idList); + + /** + * 下载代码 + * + * @param idList 表 ID 列表 + * @return 下载结果 + */ + byte[] downloadCode(List idList); + + /** + * 根据数据源 ID 删除所有表信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + boolean delTableByDatasourceId(Long datasourceId); + + /** + * 根据数据源 ID 删除所有表字段信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + boolean delTableColumnByDatasourceId(Long datasourceId); + + /** + * 根据表 ID 删除所有表字段信息 + * + * @param tableId 表 ID + * @return 删除结果 + */ + boolean delTableColumnByTableId(Long tableId); + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableColumnService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableColumnService.java new file mode 100644 index 0000000..aea5c3b --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableColumnService.java @@ -0,0 +1,81 @@ +package xtools.app.gen.service; + +import xtools.app.gen.model.dto.req.GenTableColumnAddReq; +import xtools.app.gen.model.dto.req.GenTableColumnPageReq; +import xtools.app.gen.model.dto.req.GenTableColumnUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableColumnResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : GenTableColumnService

+ *

Description : GenTableColumnService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 11:10 + */ +public interface GenTableColumnService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(GenTableColumnAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(GenTableColumnUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 根据数据源 ID 删除 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + boolean deleteByDatasourceId(Long datasourceId); + + /** + * 根据表 ID 删除 + * + * @param tableId 表 ID + * @return 删除结果 + */ + boolean deleteByTableId(Long tableId); +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableService.java new file mode 100644 index 0000000..ca1811d --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/GenTableService.java @@ -0,0 +1,73 @@ +package xtools.app.gen.service; + +import xtools.app.gen.model.dto.req.GenTableAddReq; +import xtools.app.gen.model.dto.req.GenTablePageReq; +import xtools.app.gen.model.dto.req.GenTableUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : GenTableService

+ *

Description : GenTableService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:20 + */ +public interface GenTableService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(GenTableAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(GenTableUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 根据数据源 ID 删除 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + boolean deleteByDatasourceId(Long datasourceId); +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenDatasourceBaseService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenDatasourceBaseService.java new file mode 100644 index 0000000..aab6552 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenDatasourceBaseService.java @@ -0,0 +1,21 @@ +package xtools.app.gen.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.gen.mapper.GenDatasourceMapper; +import xtools.app.gen.model.entity.GenDatasource; + +/** + *

Title : GenDatasourceBaseService

+ *

Description : GenDatasourceBaseService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:13 + */ +@Component +public class GenDatasourceBaseService extends ServiceImpl { +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableBaseService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableBaseService.java new file mode 100644 index 0000000..dc3319e --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableBaseService.java @@ -0,0 +1,21 @@ +package xtools.app.gen.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.gen.mapper.GenTableMapper; +import xtools.app.gen.model.entity.GenTable; + +/** + *

Title : GenTableBaseService

+ *

Description : GenTableBaseService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:15 + */ +@Component +public class GenTableBaseService extends ServiceImpl { +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableColumnBaseService.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableColumnBaseService.java new file mode 100644 index 0000000..03afe89 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/base/GenTableColumnBaseService.java @@ -0,0 +1,21 @@ +package xtools.app.gen.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.gen.mapper.GenTableColumnMapper; +import xtools.app.gen.model.entity.GenTableColumn; + +/** + *

Title : GenTableColumnBaseService

+ *

Description : GenTableColumnBaseService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 11:05 + */ +@Component +public class GenTableColumnBaseService extends ServiceImpl { +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenDatasourceServiceImpl.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenDatasourceServiceImpl.java new file mode 100644 index 0000000..ffa7af0 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenDatasourceServiceImpl.java @@ -0,0 +1,201 @@ +package xtools.app.gen.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.gen.convert.GenDatasourceConvert; +import xtools.app.gen.model.dto.req.GenDatasourceAddReq; +import xtools.app.gen.model.dto.req.GenDatasourcePageReq; +import xtools.app.gen.model.dto.req.GenDatasourceUpdateReq; +import xtools.app.gen.model.dto.resp.GenDatasourceResp; +import xtools.app.gen.model.entity.GenDatasource; +import xtools.app.gen.service.GenDatasourceService; +import xtools.app.gen.service.GenService; +import xtools.app.gen.service.base.GenDatasourceBaseService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : GenDatasourceServiceImpl

+ *

Description : GenDatasourceServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/17 13:14 + */ +@Primary +@Service +@RequiredArgsConstructor +public class GenDatasourceServiceImpl implements GenDatasourceService { + + private final GenService genService; + + private final GenDatasourceBaseService genDatasourceBaseService; + + private final GenDatasourceConvert genDatasourceConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), genDatasourceConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + GenDatasource data = genDatasourceBaseService.getById(id); + return Result.ok(genDatasourceConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(GenDatasourceAddReq req) { + GenDatasource entity = genDatasourceConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genDatasourceBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(GenDatasourceUpdateReq req) { + GenDatasource entity = genDatasourceConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genDatasourceBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + boolean removed = genDatasourceBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + idList.forEach(item -> { + genService.delTableByDatasourceId(item); + genService.delTableColumnByDatasourceId(item); + }); + return Result.ok(true); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, GenDatasourcePageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + GenDatasource::getId, + GenDatasource::getDbName, + GenDatasource::getDbType, + GenDatasource::getModuleName, + GenDatasource::getStatus, + GenDatasource::getMemo, + GenDatasource::getGmtCreate, + GenDatasource::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(GenDatasource::getGmtCreate); + return genDatasourceBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, GenDatasourcePageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), GenDatasource::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getDbName()), GenDatasource::getDbName, req.getDbName()); + query.eq(Objects.nonNull(req.getDbType()), GenDatasource::getDbType, req.getDbType()); + query.like(StringUtils.isNotBlank(req.getJdbcUrl()), GenDatasource::getJdbcUrl, req.getJdbcUrl()); + query.like(StringUtils.isNotBlank(req.getUsername()), GenDatasource::getUsername, req.getUsername()); + query.like(StringUtils.isNotBlank(req.getPassword()), GenDatasource::getPassword, req.getPassword()); + query.like(StringUtils.isNotBlank(req.getModuleName()), GenDatasource::getModuleName, req.getModuleName()); + query.like(StringUtils.isNotBlank(req.getSubModuleName()), GenDatasource::getSubModuleName, req.getSubModuleName()); + query.like(StringUtils.isNotBlank(req.getPackageName()), GenDatasource::getPackageName, req.getPackageName()); + query.eq(Objects.nonNull(req.getStatus()), GenDatasource::getStatus, req.getStatus()); + query.like(StringUtils.isNotBlank(req.getMemo()), GenDatasource::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), GenDatasource::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), GenDatasource::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(GenDatasource entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), GenDatasource::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getDbName()), GenDatasource::getDbName, entity.getDbName()); + return genDatasourceBaseService.exists(query); + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenServiceImpl.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenServiceImpl.java new file mode 100644 index 0000000..d71d579 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenServiceImpl.java @@ -0,0 +1,778 @@ +package xtools.app.gen.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Sequence; +import com.mysql.cj.jdbc.ConnectionImpl; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.gen.config.GenProperties; +import xtools.app.gen.convert.GenConvert; +import xtools.app.gen.convert.GenTableColumnConvert; +import xtools.app.gen.convert.GenTableConvert; +import xtools.app.gen.enums.FormTypeEnum; +import xtools.app.gen.enums.QueryTypeEnum; +import xtools.app.gen.model.dto.GenCodeDto; +import xtools.app.gen.model.dto.req.GenTableColumnUpdateReq; +import xtools.app.gen.model.dto.req.GenTableInfoReq; +import xtools.app.gen.model.dto.resp.GenTableInfoResp; +import xtools.app.gen.model.entity.GenDatasource; +import xtools.app.gen.model.entity.GenTable; +import xtools.app.gen.model.entity.GenTableColumn; +import xtools.app.gen.service.GenService; +import xtools.app.gen.service.GenTableColumnService; +import xtools.app.gen.service.GenTableService; +import xtools.app.gen.service.base.GenDatasourceBaseService; +import xtools.app.gen.service.base.GenTableBaseService; +import xtools.app.gen.service.base.GenTableColumnBaseService; +import xtools.app.gen.utils.DatasourceUtils; +import xtools.app.gen.utils.GenUtils; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.core.ArrUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.time.InstantUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + *

Title : GenServiceImpl

+ *

Description : GenServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/20 08:43 + */ +@Primary +@Service +@RequiredArgsConstructor +public class GenServiceImpl implements GenService, BaseParams { + + private final GenProperties genProperties; + + private final GenTableBaseService genTableBaseService; + + private final GenTableService genTableService; + + private final GenTableColumnBaseService genTableColumnBaseService; + + private final GenTableColumnService genTableColumnService; + + private final GenDatasourceBaseService genDatasourceBaseService; + + private final GenConvert genConvert; + + private final GenTableConvert genTableConvert; + + private final GenTableColumnConvert genTableColumnConvert; + + /** + * 删除数据源下的所有表信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + @Override + public Result delTableAndColumnByDatasourceId(Long datasourceId) { + boolean deleted = genTableService.deleteByDatasourceId(datasourceId) && genTableColumnService.deleteByDatasourceId(datasourceId); + return Result.ok(deleted); + } + + /** + * 测试连接 + * + * @param id 数据源 ID + * @return 测试结果 + */ + @Override + public Result testDb(Long id) { + // 获取数据源 + GenDatasource entity = genDatasourceBaseService.getById(id); + if (entity == null) { + throw new BizError("数据源不存在"); + } + boolean checked = DatasourceUtils.checkConnection(entity.getJdbcUrl(), entity.getUsername(), entity.getPassword()); + if (checked) { + return Result.ok(true); + } else { + throw new BizError("数据源连接失败"); + } + } + + /** + * 同步数据库 + * + * @param id 数据源 ID + * @return 同步结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result syncDb(Long id) { + // 获取数据源 + GenDatasource datasource = genDatasourceBaseService.getById(id); + if (Objects.isNull(datasource)) { + throw new BizError("数据源不存在"); + } + boolean checked = DatasourceUtils.checkConnection(datasource.getJdbcUrl(), datasource.getUsername(), datasource.getPassword()); + if (!checked) { + throw new BizError("数据源连接失败"); + } + // 删除数据源下的所有表信息 + genTableService.deleteByDatasourceId(id); + // 删除数据源下的所有表字段信息 + genTableColumnService.deleteByDatasourceId(id); + + // 获取所有表信息 + List tableList = getTableList(datasource); + for (GenTable table : tableList) { + genTableBaseService.save(table); + Long tableId = table.getId(); + if (Objects.isNull(tableId)) { + continue; + } + List columnList = getColumnList(datasource, tableId, table.getTableName()); + if (CollectionUtils.isEmpty(columnList)) { + continue; + } + genTableColumnBaseService.saveBatch(columnList); + } + return Result.ok(true); + } + + /** + * 同步表字段 + * + * @param id 表 ID + * @return 同步结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result syncColumn(Long id) { + GenTable table = genTableBaseService.getById(id); + if (Objects.isNull(table)) { + throw new BizError("表不存在"); + } + GenDatasource datasource = genDatasourceBaseService.getById(table.getDatasourceId()); + if (Objects.isNull(datasource)) { + throw new BizError("数据源不存在"); + } + boolean checked = DatasourceUtils.checkConnection(datasource.getJdbcUrl(), datasource.getUsername(), datasource.getPassword()); + if (!checked) { + throw new BizError("数据源连接失败"); + } + genTableColumnService.deleteByTableId(id); + List columnList = getColumnList(datasource, id, table.getTableName()); + genTableColumnBaseService.saveBatch(columnList); + return Result.ok(true); + } + + /** + * 获取表信息列表 + * + * @param idList 表 ID 列表 + * @return 表信息列表 + */ + @Override + public Result> getTableList(List idList) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(GenTable::getId, idList); + List tableList = genTableBaseService.list(query); + List tableInfoList = genConvert.baseToGenTableInfoResp(tableList); + tableInfoList.forEach(item -> item.setColumnList(genTableColumnConvert.entityToRespList(getColumnListByTableId(item.getId())))); + return Result.ok(tableInfoList); + } + + /** + * 保存表信息列表 + * + * @param req 表信息列表 + * @return 保存结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result saveTableList(List req) { + req.forEach(item -> { + GenTable genTable = genTableConvert.updateReqToEntity(item); + boolean updated = genTableBaseService.updateById(genTable); + if (!updated) { + throw new BizError("保存失败"); + } + List columnList = item.getColumnList(); + List genTableColumnList = genTableColumnConvert.updateReqToEntityList(columnList); + genTableColumnBaseService.saveOrUpdateBatch(genTableColumnList); + }); + return Result.ok(true); + } + + /** + * 预览代码 + * + * @param idList 表 ID 列表 + * @return 预览结果 + */ + @Override + public Result> previewCode(List idList) { + List genCodeList = new ArrayList<>(); + idList.forEach(id -> genCodeList.addAll(genCode(id))); + return Result.ok(genCodeList); + } + + /** + * 下载代码 + * + * @param idList 表 ID 列表 + * @return 下载结果 + */ + @Override + public byte[] downloadCode(List idList) { + List genCodeList = new ArrayList<>(); + idList.forEach(id -> genCodeList.addAll(genCode(id))); + if (genCodeList.isEmpty()) { + throw new BizWarning("暂无数据"); + } + try ( + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream) + ) { + for (GenCodeDto item : genCodeList) { + ZipEntry zipEntry = new ZipEntry(item.getPath() + File.separator + item.getFileName()); + zip.putNextEntry(zipEntry); + // 写入文件内容 + zip.write(item.getContent().getBytes(StandardCharsets.UTF_8)); + // 关闭当前压缩条目 + zip.closeEntry(); + } + // 确保所有压缩数据写入输出流,避免数据残留在内存缓冲区引发的数据不完整 + zip.finish(); + return outputStream.toByteArray(); + } catch (IOException e) { + throw new BizError("压缩文件异常"); + } + } + + + /** + * 生成代码 + * + * @param tableId 表 ID + * @return 生成结果 + */ + private List genCode(Long tableId) { + List result = new ArrayList<>(); + + GenTable table = genTableBaseService.getById(tableId); + if (Objects.isNull(table)) { + return result; + } + GenDatasource datasource = genDatasourceBaseService.getById(table.getDatasourceId()); + if (Objects.isNull(datasource)) { + return result; + } + List columnList = getColumnListByTableId(tableId); + if (CollectionUtils.isEmpty(columnList)) { + return result; + } + + // 处理默认值 + GenProperties.DefaultConfig defaultConfig = genProperties.getDefaultConfig(); + if (Objects.isNull(table.getAuthor())) { + table.setAuthor(defaultConfig.getAuthor()); + } + + // 微服务Api + boolean api = Objects.equals(table.getOpenApi(), CP_NUM1); + + // Excel相关数据处理 + Integer excelOpt = table.getExcelOpt(); + boolean importExcel; + boolean exportExcel; + if (Objects.equals(excelOpt, CP_NUM1)) { + importExcel = true; + exportExcel = false; + } else if (Objects.equals(excelOpt, CP_NUM2)) { + exportExcel = true; + importExcel = false; + } else if (Objects.equals(excelOpt, CP_NUM3)) { + importExcel = true; + exportExcel = true; + } else { + importExcel = false; + exportExcel = false; + } + + // 处理数据 + String subModuleName = datasource.getSubModuleName(); + String tableName = table.getTableName(); + // 获取uri + int indexOf = tableName.indexOf("_"); + String uri; + if (indexOf > CP_NEGATIVE1) { + uri = tableName.substring(CP_NUM0, indexOf) + CP_SLASH + tableName.substring(indexOf + CP_NUM1).replaceAll("_", CP_LINE); + } else { + uri = tableName; + } + // 获取按钮权限前缀 + String btnPermPrefix = uri.replaceAll(CP_SLASH, CP_COLON); + + // 获取dbid + List dbIdList = getDbIdList(CP_NUM20); + // 获取父级菜单ID和树路径 + String parentMenuId = table.getParentMenuId(); + String treePath; + String parentId; + if (StringUtils.isNotBlank(parentMenuId)) { + parentId = ArrUtils.toStringList(parentMenuId).getLast(); + treePath = parentMenuId; + } else { + parentId = "parentId"; + treePath = "treePath"; + } + String component = subModuleName + CP_SLASH + tableName.replace("_", "-") + CP_SLASH + "index"; + + // 根据配置文件生成模板 + Map templateConfigs = genProperties.getTemplateConfigs(); + + // 特殊处理模板key + String keyExcel = "Excel"; + String keyJavaApi = "Api"; + String keyCall = "Call"; + + templateConfigs.forEach((key, value) -> { + if (!importExcel && !exportExcel && Objects.equals(key, keyExcel)) { + return; + } + if (!api) { + if (Objects.equals(key, keyJavaApi) || Objects.equals(key, keyCall)) { + return; + } + } + + // 判断 Java 引入的头部包 + Map importMap = new HashMap<>(16); + // 字典列表 + List dictList = new ArrayList<>(); + // 脱敏列表 + List maskList = new ArrayList<>(); + for (GenTableColumn item : columnList) { + String fieldName = item.getFieldName(); + if (Objects.equals(fieldName, "gmtCreate") || Objects.equals(fieldName, "gmtModified")) { + continue; + } + String fieldType = item.getFieldType(); + if (Objects.equals(fieldType, "Instant")) { + importMap.put("hasInstant", true); + } + if (Objects.equals(fieldType, "BigDecimal")) { + importMap.put("hasBigDecimal", true); + } + if (Objects.equals(QueryTypeEnum.LIKE.code(), item.getQueryType())) { + importMap.put("hasStringUtils", true); + } + if (Objects.nonNull(item.getDictType())) { + dictList.add(item); + } + if (!Objects.equals(item.getMaskType(), "OFF")) { + maskList.add(item); + } + } + + // 模板数据 + Map map = new HashMap<>(16); + // 表和字段数据 + map.put("table", table); + map.put("columnList", columnList); + map.put("dictList", dictList); + map.put("maskList", maskList); + + // 版本,时间等信息 + map.put("version", defaultConfig.getVersion()); + map.put("date", InstantUtils.format(Instant.now())); + + // 是否需要微服务接口 + map.put("api", api); + + // 表格操作 + map.put("importExcel", importExcel); + map.put("exportExcel", exportExcel); + + map.put("importMap", importMap); + map.put("subModuleName", subModuleName); + map.put("subPackageName", value.getSubPackageName()); + map.put("uri", uri); + map.put("btnPermPrefix", btnPermPrefix); + map.put("apiPath", tableName.replace("_", "-") + "-api"); + + map.put("dbIds", dbIdList); + map.put("parentId", parentId); + map.put("treePath", treePath); + map.put("component", component); + + // 生成模板 + String content = GenUtils.render(map, value.getTemplatePath()); + + String fileName = getFileName(key, value.getExtension(), table); + String path = getPath(value.getExtension(), value.getProjectModule(), table.getModuleName(), subModuleName, table.getPackageName(), value.getSubPackageName(), tableName); + + // 数据封装 + GenCodeDto dto = new GenCodeDto(); + dto.setPath(path); + dto.setFileName(fileName); + dto.setContent(content); + result.add(dto); + }); + return result; + } + + /** + * 获取数据库 ID 列表 + * + * @param count 获取个数 + * @return 数据库 ID 列表 + */ + private List getDbIdList(int count) { + InetAddress localHost; + try { + localHost = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + throw new BizError("获取本地 IP 异常"); + } + Sequence sequence = new Sequence(localHost); + List dbIdList = new ArrayList<>(count); + for (int i = 0; i < count; i++) { + dbIdList.add(sequence.nextId()); + } + return dbIdList; + } + + /** + * 获取文件名 + * + * @param type 模板类型 + * @param extension 文件扩展名 + * @param table 表信息 + * @return 文件名 + */ + private String getFileName(String type, String extension, GenTable table) { + String entityName = table.getEntityName(); + String tableName = table.getTableName(); + + return switch (type) { + case "Entity", "Sql" -> entityName + extension; + case "TS_API" -> tableName.replace("_", "-") + "-api" + extension; + case "VUE_VIEW" -> "index" + extension; + default -> entityName + type + extension; + }; + } + + /** + * 获取输出路径 + * + * @param extension 扩展名 + * @param projectModule 项目模块名 + * @param moduleName 模块名 + * @param subModuleName 子模块名 + * @param packageName 包名 + * @param subPackageName 子包名 + * @param tableName 表明 + * @return 输出路径 + */ + private String getPath(String extension, String projectModule, String moduleName, String subModuleName, String packageName, String subPackageName, String tableName) { + StringJoiner joiner = new StringJoiner(CP_SLASH); + switch (extension) { + case ".java" -> { + joiner.add(genProperties.getBackendAppName()); + joiner.add(moduleName); + joiner.add(moduleName + "-" + projectModule); + joiner.add("src"); + joiner.add("main"); + joiner.add("java"); + joiner.add(packageName.replace(CP_DOT, CP_SLASH)); + joiner.add(subPackageName.replace(CP_DOT, CP_SLASH)); + } + case ".ts" -> { + joiner.add(genProperties.getFrontendAppName()); + joiner.add("src"); + joiner.add(subPackageName.replace(CP_DOT, CP_SLASH)); + joiner.add(subModuleName); + } + case ".vue" -> { + joiner.add(genProperties.getFrontendAppName()); + joiner.add("src"); + joiner.add(subPackageName.replace(CP_DOT, CP_SLASH)); + joiner.add(subModuleName); + joiner.add(tableName.replace("_", "-")); + } + case ".sql" -> joiner.add("sql"); + default -> joiner.add(CP_EMPTY); + } + return CP_SLASH + joiner; + } + + /** + * 根据数据源 ID 删除所有表信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + @Override + public boolean delTableByDatasourceId(Long datasourceId) { + return genTableService.deleteByDatasourceId(datasourceId); + } + + /** + * 根据数据源 ID 删除所有表字段信息 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + @Override + public boolean delTableColumnByDatasourceId(Long datasourceId) { + return genTableColumnService.deleteByDatasourceId(datasourceId); + } + + /** + * 根据表 ID 删除所有表字段信息 + * + * @param tableId 表 ID + * @return 删除结果 + */ + @Override + public boolean delTableColumnByTableId(Long tableId) { + return genTableColumnService.deleteByTableId(tableId); + } + + + /** + * 获取所有表信息 + * + * @param datasource 数据源 + * @return 表信息 + */ + private List getTableList(GenDatasource datasource) { + Long datasourceId = datasource.getId(); + String jdbcUrl = datasource.getJdbcUrl(); + String username = datasource.getUsername(); + String password = datasource.getPassword(); + Integer dbType = datasource.getDbType(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password)) { + DatabaseMetaData metaData = connection.getMetaData(); + String schema = connection.getSchema(); + if (Objects.equals(dbType, CP_NUM1)) { + schema = ((ConnectionImpl) connection).getDatabase(); + } + // 获取所有表信息 + ResultSet tables = metaData.getTables(schema, schema, "%", new String[]{"TABLE"}); + + List genTables = new ArrayList<>(); + while (tables.next()) { + String tableName = tables.getString("TABLE_NAME"); + String tableComment = tables.getString("REMARKS"); + + // 排除表 + if (genProperties.getExcludeTables().contains(tableName)) { + continue; + } + + // 封装信息 + GenTable table = new GenTable(); + table.setDatasourceId(datasourceId); + table.setTableName(tableName); + table.setEntityName(GenUtils.stringToNameB(tableName)); + table.setBusinessName(tableComment); + table.setPropName(GenUtils.stringToNameA(tableName)); + table.setModuleName(datasource.getModuleName()); + table.setPackageName(datasource.getPackageName()); + genTables.add(table); + } + return genTables; + } catch (SQLException e) { + throw new BizError("数据库连接异常"); + } + } + + /** + * 获取所有表字段信息 + * + * @param datasource 数据源 + * @param tableId 表 ID + * @param tableName 表名称 + * @return 表字段信息 + */ + private List getColumnList(GenDatasource datasource, Long tableId, String tableName) { + Long datasourceId = datasource.getId(); + String jdbcUrl = datasource.getJdbcUrl(); + String username = datasource.getUsername(); + String password = datasource.getPassword(); + Integer dbType = datasource.getDbType(); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password)) { + DatabaseMetaData metaData = connection.getMetaData(); + String schema = connection.getSchema(); + if (Objects.equals(dbType, CP_NUM1)) { + schema = ((ConnectionImpl) connection).getDatabase(); + } + // 获取表的列信息 + ResultSet columns = metaData.getColumns(schema, schema, tableName, "%"); + // 获取表的主键信息 + ResultSet primaryKeys = metaData.getPrimaryKeys(schema, schema, tableName); + Set setPrimaryKeys = new HashSet<>(); + while (primaryKeys.next()) { + String columnName = primaryKeys.getString("COLUMN_NAME"); + setPrimaryKeys.add(columnName); + } + primaryKeys.close(); + + // 获取表的字段信息 + List columnList = new ArrayList<>(); + int sortOrder = CP_NUM1; + while (columns.next()) { + String columnName = columns.getString("COLUMN_NAME"); + String columnType = columns.getString("TYPE_NAME"); + String columnRemarks = columns.getString("REMARKS"); + int columnSize = columns.getInt("COLUMN_SIZE"); + int dataType = columns.getInt("DATA_TYPE"); + int isNullable = columns.getInt("NULLABLE"); + // 是否是主键 + boolean primaryKey = setPrimaryKeys.contains(columnName); + + // 处理数据 + List filterRemarks = genProperties.getFilterConfig().getColumnRemarks(); + for (String remark : filterRemarks) { + columnRemarks = Pattern.compile(remark).matcher(columnRemarks).replaceAll(CP_EMPTY); + } + + // 封装信息 + GenTableColumn column = new GenTableColumn(); + + column.setDatasourceId(datasourceId); + column.setTableId(tableId); + + column.setIsPk(primaryKey ? CP_NUM1 : CP_NUM0); + column.setColumnName(columnName); + column.setColumnType(columnType); + + column.setFieldName(GenUtils.stringToNameA(columnName)); + column.setFieldType(GenUtils.columnTypeToJavaType(dataType)); + column.setFieldSort(sortOrder++); + column.setFieldComment(Objects.nonNull(columnRemarks) ? columnRemarks : columnName); + + column.setFunName(GenUtils.stringToNameB(columnName)); + + if (primaryKey) { + column.setIsRequired(CP_NUM1); + column.setIsShowInList(CP_NUM0); + column.setIsShowInForm(CP_NUM0); + column.setIsShowInQuery(CP_NUM0); + } else { + column.setIsRequired(isNullable == CP_NUM0 ? CP_NUM1 : CP_NUM0); + column.setIsShowInList(CP_NUM1); + column.setIsShowInForm(CP_NUM1); + column.setIsShowInQuery(CP_NUM1); + } + + column.setColumnLength(columnSize); + column.setMaxLength(columnSize); + + column.setQueryType(getQueryType(column.getFieldType()).code()); + FormTypeEnum formType = getFormType(column.getFieldType(), columnType, columnSize); + column.setFormType(formType.code()); + column.setDictType(getDictType(formType)); + column.setMaskType("OFF"); + + columnList.add(column); + } + return columnList; + } catch (SQLException e) { + throw new BizError("数据库连接异常"); + } + } + + /** + * 获取查询方式 + * + * @param fieldType 字段类型 + * @return 查询方式 + */ + private QueryTypeEnum getQueryType(String fieldType) { + return switch (fieldType) { + case "String" -> QueryTypeEnum.LIKE; + case "Instant" -> QueryTypeEnum.TIME_RANGE; + default -> QueryTypeEnum.EQ; + }; + } + + /** + * 获取表单类型 + * + * @param fieldType 字段类型 + * @return 表单类型 + */ + private FormTypeEnum getFormType(String fieldType, String columnType, int maxLength) { + String tinyint = "TINYINT"; + if (Objects.equals(columnType, tinyint) && maxLength <= CP_NUM3) { + return FormTypeEnum.SELECT; + } + return switch (fieldType) { + case "Instant" -> FormTypeEnum.DATE_TIME; + case "Boolean" -> FormTypeEnum.SELECT; + default -> FormTypeEnum.INPUT; + }; + } + + /** + * 获取字典类型 + * + * @param formType 表单类型 + * @return 字典类型 + */ + private String getDictType(FormTypeEnum formType) { + if (!Objects.equals(formType, FormTypeEnum.SELECT)) { + return null; + } + return "DEF_YN"; + } + + /** + * 获取表字段信息 + * + * @param tableId 表 ID + * @return 表字段信息 + */ + private List getColumnListByTableId(Long tableId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.orderByAsc(GenTableColumn::getFieldSort); + query.eq(GenTableColumn::getTableId, tableId); + return genTableColumnBaseService.list(query); + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableColumnServiceImpl.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..55c56a3 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableColumnServiceImpl.java @@ -0,0 +1,216 @@ +package xtools.app.gen.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.gen.convert.GenTableColumnConvert; +import xtools.app.gen.model.dto.req.GenTableColumnAddReq; +import xtools.app.gen.model.dto.req.GenTableColumnPageReq; +import xtools.app.gen.model.dto.req.GenTableColumnUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableColumnResp; +import xtools.app.gen.model.entity.GenTableColumn; +import xtools.app.gen.service.GenTableColumnService; +import xtools.app.gen.service.base.GenTableColumnBaseService; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : GenTableColumnServiceImpl

+ *

Description : GenTableColumnServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 11:15 + */ +@Primary +@Service +@RequiredArgsConstructor +public class GenTableColumnServiceImpl implements GenTableColumnService { + + private final GenTableColumnBaseService genTableColumnBaseService; + + private final GenTableColumnConvert genTableColumnConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), genTableColumnConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + GenTableColumn data = genTableColumnBaseService.getById(id); + return Result.ok(genTableColumnConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(GenTableColumnAddReq req) { + GenTableColumn entity = genTableColumnConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genTableColumnBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(GenTableColumnUpdateReq req) { + GenTableColumn entity = genTableColumnConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genTableColumnBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + public Result delById(List idList) { + return Result.ok(genTableColumnBaseService.removeByIds(idList)); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, GenTableColumnPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByAsc(GenTableColumn::getFieldSort); + query.orderByDesc(GenTableColumn::getGmtCreate); + return genTableColumnBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, GenTableColumnPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), GenTableColumn::getId, req.getId()); + query.eq(Objects.nonNull(req.getDatasourceId()), GenTableColumn::getDatasourceId, req.getDatasourceId()); + query.eq(Objects.nonNull(req.getTableId()), GenTableColumn::getTableId, req.getTableId()); + query.eq(Objects.nonNull(req.getIsPk()), GenTableColumn::getIsPk, req.getIsPk()); + query.like(StringUtils.isNotBlank(req.getColumnName()), GenTableColumn::getColumnName, req.getColumnName()); + query.like(StringUtils.isNotBlank(req.getColumnType()), GenTableColumn::getColumnType, req.getColumnType()); + query.eq(Objects.nonNull(req.getColumnLength()), GenTableColumn::getColumnLength, req.getColumnLength()); + query.like(StringUtils.isNotBlank(req.getFieldName()), GenTableColumn::getFieldName, req.getFieldName()); + query.like(StringUtils.isNotBlank(req.getFieldType()), GenTableColumn::getFieldType, req.getFieldType()); + query.eq(Objects.nonNull(req.getFieldSort()), GenTableColumn::getFieldSort, req.getFieldSort()); + query.like(StringUtils.isNotBlank(req.getFieldComment()), GenTableColumn::getFieldComment, req.getFieldComment()); + query.like(StringUtils.isNotBlank(req.getFunName()), GenTableColumn::getFunName, req.getFunName()); + query.eq(Objects.nonNull(req.getMaxLength()), GenTableColumn::getMaxLength, req.getMaxLength()); + query.eq(Objects.nonNull(req.getIsRequired()), GenTableColumn::getIsRequired, req.getIsRequired()); + query.eq(Objects.nonNull(req.getIsShowInList()), GenTableColumn::getIsShowInList, req.getIsShowInList()); + query.eq(Objects.nonNull(req.getIsShowInForm()), GenTableColumn::getIsShowInForm, req.getIsShowInForm()); + query.eq(Objects.nonNull(req.getIsShowInQuery()), GenTableColumn::getIsShowInQuery, req.getIsShowInQuery()); + query.eq(Objects.nonNull(req.getQueryType()), GenTableColumn::getQueryType, req.getQueryType()); + query.eq(Objects.nonNull(req.getFormType()), GenTableColumn::getFormType, req.getFormType()); + query.like(StringUtils.isNotBlank(req.getDictType()), GenTableColumn::getDictType, req.getDictType()); + query.like(StringUtils.isNotBlank(req.getMaskType()), GenTableColumn::getMaskType, req.getMaskType()); + query.eq(Objects.nonNull(req.getExt()), GenTableColumn::getExt, req.getExt()); + query.like(StringUtils.isNotBlank(req.getMemo()), GenTableColumn::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), GenTableColumn::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), GenTableColumn::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(GenTableColumn entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), GenTableColumn::getId, entity.getId()); + // 根据表 ID 和字段名校验数据是否存在 + query.eq(Objects.nonNull(entity.getTableId()), GenTableColumn::getTableId, entity.getTableId()) + .eq(StringUtils.isNotBlank(entity.getFieldName()), GenTableColumn::getFieldName, entity.getFieldName()); + return genTableColumnBaseService.exists(query); + } + + /** + * 根据数据源 ID 删除 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + @Override + public boolean deleteByDatasourceId(Long datasourceId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(GenTableColumn::getDatasourceId, datasourceId); + return genTableColumnBaseService.remove(query); + } + + /** + * 根据表 ID 删除 + * + * @param tableId 表 ID + * @return 删除结果 + */ + @Override + public boolean deleteByTableId(Long tableId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(GenTableColumn::getTableId, tableId); + return genTableColumnBaseService.remove(query); + } +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableServiceImpl.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableServiceImpl.java new file mode 100644 index 0000000..867c06a --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/service/impl/GenTableServiceImpl.java @@ -0,0 +1,202 @@ +package xtools.app.gen.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.gen.convert.GenTableConvert; +import xtools.app.gen.model.dto.req.GenTableAddReq; +import xtools.app.gen.model.dto.req.GenTablePageReq; +import xtools.app.gen.model.dto.req.GenTableUpdateReq; +import xtools.app.gen.model.dto.resp.GenTableResp; +import xtools.app.gen.model.entity.GenTable; +import xtools.app.gen.service.GenTableService; +import xtools.app.gen.service.base.GenTableBaseService; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : GenTableServiceImpl

+ *

Description : GenTableServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/18 10:25 + */ +@Primary +@Service +@RequiredArgsConstructor +public class GenTableServiceImpl implements GenTableService { + + private final GenTableBaseService genTableBaseService; + + private final GenTableConvert genTableConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), genTableConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + GenTable data = genTableBaseService.getById(id); + return Result.ok(genTableConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(GenTableAddReq req) { + GenTable entity = genTableConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genTableBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(GenTableUpdateReq req) { + GenTable entity = genTableConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(genTableBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + public Result delById(List idList) { + return Result.ok(genTableBaseService.removeByIds(idList)); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, GenTablePageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + GenTable::getId, + GenTable::getDatasourceId, + GenTable::getTableName, + GenTable::getBusinessName, + GenTable::getParentMenuId, + GenTable::getGmtCreate, + GenTable::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(GenTable::getGmtCreate); + return genTableBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, GenTablePageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), GenTable::getId, req.getId()); + query.eq(Objects.nonNull(req.getDatasourceId()), GenTable::getDatasourceId, req.getDatasourceId()); + query.like(StringUtils.isNotBlank(req.getTableName()), GenTable::getTableName, req.getTableName()); + query.like(StringUtils.isNotBlank(req.getModuleName()), GenTable::getModuleName, req.getModuleName()); + query.like(StringUtils.isNotBlank(req.getPackageName()), GenTable::getPackageName, req.getPackageName()); + query.like(StringUtils.isNotBlank(req.getBusinessName()), GenTable::getBusinessName, req.getBusinessName()); + query.like(StringUtils.isNotBlank(req.getEntityName()), GenTable::getEntityName, req.getEntityName()); + query.like(StringUtils.isNotBlank(req.getPropName()), GenTable::getPropName, req.getPropName()); + query.like(StringUtils.isNotBlank(req.getAuthor()), GenTable::getAuthor, req.getAuthor()); + query.eq(Objects.nonNull(req.getParentMenuId()), GenTable::getParentMenuId, req.getParentMenuId()); + query.like(StringUtils.isNotBlank(req.getRemoveTablePrefix()), GenTable::getRemoveTablePrefix, req.getRemoveTablePrefix()); + query.like(StringUtils.isNotBlank(req.getPageType()), GenTable::getPageType, req.getPageType()); + query.like(StringUtils.isNotBlank(req.getMemo()), GenTable::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), GenTable::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), GenTable::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(GenTable entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), GenTable::getId, entity.getId()); + // 根据表名校验数据是否存在 + query.eq(Objects.nonNull(entity.getDatasourceId()), GenTable::getDatasourceId, entity.getDatasourceId()); + query.eq(StringUtils.isNotBlank(entity.getTableName()), GenTable::getTableName, entity.getTableName()); + return genTableBaseService.exists(query); + } + + /** + * 根据数据源 ID 删除 + * + * @param datasourceId 数据源 ID + * @return 删除结果 + */ + @Override + public boolean deleteByDatasourceId(Long datasourceId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(GenTable::getDatasourceId, datasourceId); + return genTableBaseService.remove(query); + } +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/DatasourceUtils.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/DatasourceUtils.java new file mode 100644 index 0000000..6798f3c --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/DatasourceUtils.java @@ -0,0 +1,50 @@ +package xtools.app.gen.utils; + +import xtools.boot.api.exection.BizError; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +/** + *

Title : DatasourceUtils

+ *

Description : DatasourceUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +public class DatasourceUtils { + + + /** + * 检查数据库连接是否正常 + * + * @param jdbcUrl 数据库连接 URL + * @param username 数据库用户名 + * @param password 数据库密码 + * @return 是否正常 + */ + public static boolean checkConnection(String jdbcUrl, String username, String password) { + // 设置连接属性 + Properties props = new Properties(); + props.setProperty("user", username); + props.setProperty("password", password); + // 10秒连接超时 + props.setProperty("connectTimeout", "10000"); + // 30秒读取超时 + props.setProperty("socketTimeout", "30000"); + + try (Connection connection = DriverManager.getConnection(jdbcUrl, props)) { + // 尝试执行简单查询验证连接 + return connection.isValid(10); + } catch (SQLException e) { + throw new BizError("数据库连接异常"); + } + } + +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/GenUtils.java b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/GenUtils.java new file mode 100644 index 0000000..dc50ff8 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/java/xtools/app/gen/utils/GenUtils.java @@ -0,0 +1,102 @@ +package xtools.app.gen.utils; + +import org.apache.commons.lang3.StringUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import xtools.boot.core.utils.SpringContextUtils; + +import java.io.StringWriter; +import java.sql.Types; +import java.util.Map; + +/** + *

Title : GenUtils

+ *

Description : GenUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/20 09:22 + */ +public class GenUtils { + + /** + * 转换字符串(将aa_bb_cc转换为aaBbCc) + * + * @param string 字符串 + * @return 处理后的字符串 + */ + public static String stringToNameA(String string) { + String lowerCaseStr = string.toLowerCase(); + String[] noDashArray = StringUtils.split(lowerCaseStr, '_'); + StringBuilder noDash = new StringBuilder(noDashArray[0]); + for (int i = 1; i < noDashArray.length; i++) { + noDash.append(StringUtils.capitalize(noDashArray[i])); + } + return noDash.toString(); + } + + /** + * 转换字符串(将aa_bb_cc转换为AaBbCc) + * + * @param string 字符串 + * @return 处理后的字符串 + */ + public static String stringToNameB(String string) { + return StringUtils.capitalize(stringToNameA(string)); + } + + /** + * 转换字符串(将aa_bb_cc转换为AA_BB_CC) + * + * @param string 字符串 + * @return 处理后的字符串 + */ + public static String stringToNameC(String string) { + return string.toUpperCase(); + } + + /** + * 根据数据库字段类型映射 Java 类型 + * + * @param dataType 数据库字段类型 + * @return Java 类型 + */ + public static String columnTypeToJavaType(int dataType) { + return switch (dataType) { + case Types.INTEGER, Types.SMALLINT, Types.TINYINT -> "Integer"; + case Types.BIGINT -> "Long"; + case Types.DOUBLE, Types.FLOAT, Types.REAL -> "Double"; + case Types.DECIMAL, Types.NUMERIC -> "BigDecimal"; + case Types.VARCHAR, Types.CHAR, Types.LONGVARCHAR, Types.NVARCHAR, Types.NCHAR, Types.LONGNVARCHAR -> + "String"; + case Types.DATE, Types.TIME, Types.TIMESTAMP -> "Instant"; + case Types.BOOLEAN, Types.BIT -> "Boolean"; + default -> "Object"; + }; + } + + /** + * 渲染模板 + * + * @param map 数据 + * @param templatePath 模板路径 + * @return 渲染后的模板 + */ + public static String render(Map map, String templatePath) { + // 获取模板引擎 + VelocityEngine velocityEngine = SpringContextUtils.getBean(VelocityEngine.class); + // 创建上下文 + VelocityContext velocityContext = new VelocityContext(map); + // 获取模板(从classpath的templates目录下) + Template template = velocityEngine.getTemplate("templates/" + templatePath); + // 渲染 + StringWriter writer = new StringWriter(); + template.merge(velocityContext, writer); + return writer.toString(); + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/api/api.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/api/api.java.vm new file mode 100644 index 0000000..6dbe141 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/api/api.java.vm @@ -0,0 +1,14 @@ +package ${table.packageName}.${subPackageName}; + +/** + *

Title : ${table.entityName}Api

+ *

Description : $!{table.businessName} Api

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +public interface ${table.entityName}Api { + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/call/call.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/call/call.java.vm new file mode 100644 index 0000000..02ac07d --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/call/call.java.vm @@ -0,0 +1,18 @@ +package ${table.packageName}.${subPackageName}; + +import org.springframework.web.service.annotation.HttpExchange; +import ${table.packageName}.api.${table.entityName}Api; + +/** + *

Title : ${table.entityName}Call

+ *

Description : $!{table.businessName} Call

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@HttpExchange("/${uri}") +public interface ${table.entityName}Call extends ${table.entityName}Api { + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/controller/controller.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/controller/controller.java.vm new file mode 100644 index 0000000..6e51cbf --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/controller/controller.java.vm @@ -0,0 +1,137 @@ +package ${table.packageName}.${subPackageName}; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import ${table.packageName}.model.dto.req.${table.entityName}AddReq; +import ${table.packageName}.model.dto.req.${table.entityName}PageReq; +import ${table.packageName}.model.dto.req.${table.entityName}UpdateReq; +import ${table.packageName}.model.dto.resp.${table.entityName}Resp; +import ${table.packageName}.service.${table.entityName}Service; +#if($api) +import ${table.packageName}.api.${table.entityName}Api; +#end +#if($exportExcel || $importExcel) +import ${table.packageName}.model.dto.excel.${table.entityName}Excel; +import xtools.extend.office.FesodUtils; +import xtools.boot.api.exection.BizError; + +import java.io.IOException; +#end +#if($exportExcel) +import java.util.List; + +import xtools.web.HttpServletUtils; +import jakarta.servlet.http.HttpServletResponse; +#end +#if($importExcel) +import org.springframework.web.multipart.MultipartFile; +import xtools.core.CollectionUtils; +import xtools.boot.api.exection.BizWarning; +import org.springframework.web.bind.annotation.RequestParam; +#end + +/** + *

Title : ${table.entityName}Controller

+ *

Description : $!{table.businessName} Controller

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@RequiredArgsConstructor +@Tag(name = "$!{table.businessName}") +@RestController +@RequestMapping("/${uri}") +public class ${table.entityName}Controller #if($api)implements ${table.entityName}Api #end{ + + private final ${table.entityName}Service ${table.propName}Service; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq<${table.entityName}PageReq> pageReq) { + return ${table.propName}Service.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result<${table.entityName}Resp> getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return ${table.propName}Service.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid ${table.entityName}AddReq req) { + return ${table.propName}Service.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid ${table.entityName}UpdateReq req) { + return ${table.propName}Service.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return ${table.propName}Service.delById(req); + } + + #if($exportExcel) + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid ${table.entityName}PageReq req, HttpServletResponse response) { + String sheetName = "$!{table.businessName}" ; + String filename = sheetName + ".xlsx" ; + List<${table.entityName}Excel> dataList = ${table.propName}Service.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), ${table.entityName}Excel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + #end + #if($importExcel) + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List<${table.entityName}Excel> dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), ${table.entityName}Excel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + ${table.propName}Service.importExcel(dataList); + return Result.ok(true); + } + + #end +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/convert/convert.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/convert/convert.java.vm new file mode 100644 index 0000000..2283f8d --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/convert/convert.java.vm @@ -0,0 +1,78 @@ +package ${table.packageName}.${subPackageName}; + +import org.mapstruct.Mapper; +import ${table.packageName}.model.dto.req.${table.entityName}AddReq; +import ${table.packageName}.model.dto.req.${table.entityName}UpdateReq; +import ${table.packageName}.model.dto.resp.${table.entityName}Resp; +import ${table.packageName}.model.entity.${table.entityName}; +#if($exportExcel || $importExcel) +import ${table.packageName}.model.dto.excel.${table.entityName}Excel; +#end + +import java.util.List; + +/** + *

Title : ${table.entityName}Convert

+ *

Description : $!{table.businessName} Convert

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Mapper(componentModel = "spring") +public interface ${table.entityName}Convert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + ${table.entityName} addReqToEntity(${table.entityName}AddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + ${table.entityName} updateReqToEntity(${table.entityName}UpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + ${table.entityName}Resp entityToResp(${table.entityName} data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List<${table.entityName}Resp> entityToRespList(List<${table.entityName}> dataList); + + #if($exportExcel) + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + ${table.entityName}Excel entityToExcel(${table.entityName} data); + + #end + #if($importExcel) + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + ${table.entityName} excelToEntity(${table.entityName}Excel data); + + #end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/mapper/mapper.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/mapper/mapper.java.vm new file mode 100644 index 0000000..cd29f06 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/mapper/mapper.java.vm @@ -0,0 +1,20 @@ +package ${table.packageName}.${subPackageName}; + +import org.apache.ibatis.annotations.Mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import ${table.packageName}.model.entity.${table.entityName}; + +/** + *

Title : ${table.entityName}Mapper

+ *

Description : $!{table.businessName} Mapper 接口

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Mapper +public interface ${table.entityName}Mapper extends BaseMapper<${table.entityName}> { + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/addReq.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/addReq.java.vm new file mode 100644 index 0000000..fb742eb --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/addReq.java.vm @@ -0,0 +1,41 @@ +package ${table.packageName}.${subPackageName}; + +#if($importMap.hasInstant) +import java.time.Instant; +#end +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; + +/** + *

Title : ${table.entityName}AddReq

+ *

Description : $!{table.businessName}添加请求对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ${table.entityName}AddReq implements Serializable { + +#foreach($column in ${columnList}) + #if(!$column.isPk.equals(1) && !$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + #if("$!column.fieldComment" != "") + /** + * ${column.fieldComment} + */ + @Schema(description = "${column.fieldComment}") + #end + private ${column.fieldType} ${column.fieldName}; + + #end +#end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/excel.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/excel.java.vm new file mode 100644 index 0000000..e00aebf --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/excel.java.vm @@ -0,0 +1,39 @@ +package ${table.packageName}.${subPackageName}; + +#if($importMap.hasInstant) +import java.time.Instant; +#end +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; +import java.io.Serializable; + +/** + *

Title : ${table.entityName}Excel

+ *

Description : $!{table.businessName}Excel对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ${table.entityName}Excel implements Serializable { + +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + /** + * ${column.fieldComment} + */ + @ExcelProperty("${column.fieldComment}") + private ${column.fieldType} ${column.fieldName}; + + #end +#end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/pageReq.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/pageReq.java.vm new file mode 100644 index 0000000..e51236b --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/pageReq.java.vm @@ -0,0 +1,53 @@ +package ${table.packageName}.${subPackageName}; + +import java.time.Instant; +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; + +/** + *

Title : ${table.entityName}PageReq

+ *

Description : $!{table.businessName}分页请求对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ${table.entityName}PageReq implements Serializable { + +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + /** + * ${column.fieldComment} + */ + #if($column.fieldType.equals("Instant")) + @Schema(description = "${column.fieldComment}(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private ${column.fieldType}[] ${column.fieldName}Range; + #else + @Schema(description = "${column.fieldComment}") + private ${column.fieldType} ${column.fieldName}; + #end + + #end +#end + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/resp.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/resp.java.vm new file mode 100644 index 0000000..d92d4eb --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/resp.java.vm @@ -0,0 +1,48 @@ +package ${table.packageName}.${subPackageName}; + +#if($maskList.size() > 0) +import xtools.boot.mask.anntation.Mask; +import xtools.boot.mask.enums.MaskType; +#end +#if($importMap.hasInstant) +import java.time.Instant; +#end +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import io.swagger.v3.oas.annotations.media.Schema; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : ${table.entityName}Resp

+ *

Description : $!{table.businessName}响应对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class ${table.entityName}Resp extends BaseEntity { + +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + /** + * ${column.fieldComment} + */ + @Schema(description = "${column.fieldComment}") + #if("$!column.maskType" != "OFF") + @Mask(MaskType.${column.maskType}) + #end + private ${column.fieldType} ${column.fieldName}; + + #end +#end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/updateReq.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/updateReq.java.vm new file mode 100644 index 0000000..75244d0 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/dto/updateReq.java.vm @@ -0,0 +1,41 @@ +package ${table.packageName}.${subPackageName}; + +#if($importMap.hasInstant) +import java.time.Instant; +#end +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; + +/** + *

Title : ${table.entityName}UpdateReq

+ *

Description : $!{table.businessName}更新请求对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ${table.entityName}UpdateReq implements Serializable { + +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + #if("$!column.fieldComment" != "") + /** + * ${column.fieldComment} + */ + @Schema(description = "${column.fieldComment}") + #end + private ${column.fieldType} ${column.fieldName}; + + #end +#end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/entity/entity.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/entity/entity.java.vm new file mode 100644 index 0000000..6a51675 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/model/entity/entity.java.vm @@ -0,0 +1,51 @@ +package ${table.packageName}.${subPackageName}; + +#if($importMap.hasInstant) +import java.time.Instant; +#end +#if($importMap.hasBigDecimal) +import java.math.BigDecimal; +#end +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : ${table.entityName}

+ *

Description : $!{table.businessName}实体对象

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("${table.tableName}") +public class ${table.entityName} extends BaseEntity { + +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + /** + * ${column.fieldComment} + */ + @Schema(description = "${column.fieldComment}") + #if($column.isPk.equals(1)) + @TableId(value = "${column.columnName}", type = IdType.ASSIGN_ID) + #else + @TableField(value = "${column.columnName}") + #end + private ${column.fieldType} ${column.fieldName}; + + #end +#end +} \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/service.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/service.java.vm new file mode 100644 index 0000000..5fc77de --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/service.java.vm @@ -0,0 +1,91 @@ +package ${table.packageName}.${subPackageName}; + +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import ${table.packageName}.model.dto.req.${table.entityName}AddReq; +import ${table.packageName}.model.dto.req.${table.entityName}PageReq; +import ${table.packageName}.model.dto.req.${table.entityName}UpdateReq; +import ${table.packageName}.model.dto.resp.${table.entityName}Resp; +#if($api) +import ${table.packageName}.api.${table.entityName}Api; +#end +#if($exportExcel || $importExcel) +import ${table.packageName}.model.dto.excel.${table.entityName}Excel; +#end +#if($exportExcel) +import java.util.List; +#end + +/** + *

Title : ${table.entityName}Service

+ *

Description : $!{table.businessName} Service

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +public interface ${table.entityName}Service #if($api)extends ${table.entityName}Api #end{ + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq<${table.entityName}PageReq> pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result<${table.entityName}Resp> getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(${table.entityName}AddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(${table.entityName}UpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(IdListReq req); + + #if($exportExcel) + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List<${table.entityName}Excel> exportExcel(${table.entityName}PageReq req); + + #end + #if($importExcel) + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List<${table.entityName}Excel> dataList); + + #end +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceBase.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceBase.java.vm new file mode 100644 index 0000000..11b75d6 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceBase.java.vm @@ -0,0 +1,20 @@ +package ${table.packageName}.${subPackageName}; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; + +import ${table.packageName}.mapper.${table.entityName}Mapper; +import ${table.packageName}.model.entity.${table.entityName}; + +/** + *

Title : ${table.entityName}BaseService

+ *

Description : $!{table.businessName} BaseService

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Component +public class ${table.entityName}BaseService extends ServiceImpl<${table.entityName}Mapper, ${table.entityName}> { +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceImpl.java.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceImpl.java.vm new file mode 100644 index 0000000..2e994c0 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/service/serviceImpl.java.vm @@ -0,0 +1,255 @@ +package ${table.packageName}.${subPackageName}; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +#if($importMap.hasStringUtils) +import xtools.core.StringUtils; +#end +import ${table.packageName}.convert.${table.entityName}Convert; +import ${table.packageName}.model.dto.req.${table.entityName}AddReq; +import ${table.packageName}.model.dto.req.${table.entityName}PageReq; +import ${table.packageName}.model.dto.req.${table.entityName}UpdateReq; +import ${table.packageName}.model.dto.resp.${table.entityName}Resp; +import ${table.packageName}.model.entity.${table.entityName}; +#if($exportExcel || $importExcel) +import ${table.packageName}.model.dto.excel.${table.entityName}Excel; +#end +import ${table.packageName}.service.${table.entityName}Service; +import ${table.packageName}.service.base.${table.entityName}BaseService; +import java.util.Objects; +#if($exportExcel) +import java.util.List; +#end + +/** + *

Title : ${table.entityName}ServiceImpl

+ *

Description : $!{table.businessName} ServiceImpl

+ *

Company : org.xujun

+ * + * @author : ${table.author} + * @version : ${version} + * @date : ${date} + */ +@Primary +@Service +@RequiredArgsConstructor +public class ${table.entityName}ServiceImpl implements ${table.entityName}Service { + + private final ${table.entityName}BaseService ${table.propName}BaseService; + + private final ${table.entityName}Convert ${table.propName}Convert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq<${table.entityName}PageReq> pageReq) { + // 分页查询 + Page<${table.entityName}> page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp<${table.entityName}Resp> pageResp = new PageResp<>(pageReq, page.getTotal(), ${table.propName}Convert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result<${table.entityName}Resp> getById(Long id) { + ${table.entityName} data = ${table.propName}BaseService.getById(id); + return Result.ok(${table.propName}Convert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(${table.entityName}AddReq req) { + ${table.entityName} entity = ${table.propName}Convert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(${table.propName}BaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(${table.entityName}UpdateReq req) { + ${table.entityName} entity = ${table.propName}Convert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(${table.propName}BaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + boolean removed = ${table.propName}BaseService.removeByIds(req.getIdList()); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + #if($exportExcel) + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List<${table.entityName}Excel> exportExcel(${table.entityName}PageReq req) { + // 创建查询条件 + LambdaQueryWrapper<${table.entityName}> query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + #foreach($column in ${columnList}) + #if($foreach.index.equals(0)) + ${table.entityName}::get${column.funName} + #else + , ${table.entityName}::get${column.funName} + #end + #end + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(${table.entityName}::getGmtCreate); + List<${table.entityName}> dataList = ${table.propName}BaseService.list(query); + return dataList.stream().map(item -> ${table.propName}Convert.entityToExcel(item)).toList(); + } + + #end + #if($importExcel) + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List<${table.entityName}Excel> dataList) { + for (${table.entityName}Excel excel : dataList) { + ${table.entityName} item = ${table.propName}Convert.excelToEntity(excel); + ${table.entityName} dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + ${table.propName}BaseService.save(item); + } else { + // 修改 + item.setId(dbItem.getId()); + ${table.propName}BaseService.updateById(item); + } + } + } + + #end + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page<${table.entityName}> getPageData(Integer currentPage, Integer pageSize, ${table.entityName}PageReq req) { + // 创建查询条件 + LambdaQueryWrapper<${table.entityName}> query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + #foreach($column in ${columnList}) + #if($foreach.index.equals(0)) + ${table.entityName}::get${column.funName} + #else + , ${table.entityName}::get${column.funName} + #end + #end + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(${table.entityName}::getGmtCreate); + return ${table.propName}BaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper<${table.entityName}> query, ${table.entityName}PageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + #foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + #if($column.queryType.equals(1)) + query.eq(Objects.nonNull(req.get${column.funName}()), ${table.entityName}::get${column.funName}, req.get${column.funName}()); + #end + #if($column.queryType.equals(2)) + query.like(StringUtils.isNotBlank(req.get${column.funName}()), ${table.entityName}::get${column.funName}, req.get${column.funName}()); + #end + #if($column.queryType.equals(12)) + QueryUtils.addTimeRange(query, req.get${column.funName}Range(), ${table.entityName}::get${column.funName}); + #end + #end + #end + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), ${table.entityName}::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), ${table.entityName}::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private ${table.entityName} existsEntity(${table.entityName} entity) { + // 创建查询条件 + LambdaQueryWrapper<${table.entityName}> query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(${table.entityName}::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), ${table.entityName}::getId, entity.getId()); + // 校验数据时候存在的条件 + return ${table.propName}BaseService.getOne(query); + } + +} diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/sql/db.sql.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/sql/db.sql.vm new file mode 100644 index 0000000..0612f4f --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/sql/db.sql.vm @@ -0,0 +1,27 @@ +-- 主菜单 +INSERT INTO sys_menu (`id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `route_name`, `route_path`, `component`, `menu_cache`) VALUES (${dbIds[0]}, ${parentId}, '${treePath}', '${table.businessName}', 'Link', 'M', '${table.entityName}', '/${uri}', '${component}', 1); +-- 分页查询-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[1]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '分页查询', 'Link', 'I', 1, '2', '/${uri}/page' ); +-- 获取数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[2]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '获取数据', 'Link', 'I', 2, '1', '/${uri}/base/*' ); +-- 新增数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[3]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '新增数据', 'Link', 'I', 3, '2', '/${uri}/base' ); +-- 修改数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[4]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '修改数据', 'Link', 'I', 4, '3', '/${uri}/base' ); +-- 删除数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[5]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '删除数据', 'Link', 'I', 5, '4', '/${uri}/base' ); +-- 按钮权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[6]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '查看按钮', 'Pointer', 'B', 6, '${btnPermPrefix}:view' ); +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[7]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '新增按钮', 'Pointer', 'B', 7, '${btnPermPrefix}:add' ); +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[8]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '修改按钮', 'Pointer', 'B', 8, '${btnPermPrefix}:edit' ); +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[9]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '删除按钮', 'Pointer', 'B', 9, '${btnPermPrefix}:delete' ); +#if($exportExcel) +-- 导出数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[10]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '导出数据', 'Link', 'I', 10, '2', '/${uri}/export' ); +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[11]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '导出按钮', 'Pointer', 'B', 11, '${btnPermPrefix}:export' ); +#end +#if($importExcel) +-- 导入数据-接口权限 +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `interface_perm_type`, `interface_perm_uri` ) VALUES ( ${dbIds[12]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '导入数据', 'Link', 'I', 12, '2', '/${uri}/import' ); +INSERT INTO sys_menu ( `id`, `parent_id`, `tree_path`, `menu_name`, `menu_icon`, `menu_type`, `sort`, `btn_perm` ) VALUES ( ${dbIds[13]}, ${dbIds[0]}, '${treePath},${dbIds[0]}', '导入按钮', 'Pointer', 'B', 13, '${btnPermPrefix}:import' ); +#end \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/ts/api.ts.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/ts/api.ts.vm new file mode 100644 index 0000000..d2bde83 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/ts/api.ts.vm @@ -0,0 +1,142 @@ +import {PageReq, PageResult} from "@/types/global"; +import http from "@/plugins/axios"; + +// 基本的请求路径 +const BASE_URL = "/${uri}"; + +// 基本实体类 +interface BaseVo { +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + // ${column.fieldComment} + ${column.fieldName}?: string; + #end +#end +} + +// 分页搜索实体 +export interface PageQuery extends BaseVo { +#foreach($column in ${columnList}) + #if(!$column.fieldName.equals("gmtCreate") && !$column.fieldName.equals("gmtModified")) + #if($column.fieldType.equals("Instant")) + // ${column.fieldComment} + ${column.fieldName}Range?: Array; + #end + #end +#end + // 更新时间 + gmtModifiedRange?: Array; + // 创建时间 + gmtCreateRange?: Array; +} + +// 分页响应实体类 +export interface PageResp extends BaseVo { + // 创建时间 + gmtCreate?: string; + // 更新时间 + gmtModified?: string; +} + +// 编辑表单实体 +export interface EditForm extends BaseVo { +} + +// api +const api = { + /** + * 分页列表 + * @param queryParams 搜索表单 + */ + getPage(queryParams?: PageReq) { + return http>({ + url: `${BASE_URL}/page`, + method: "post", + data: queryParams, + }); + }, + + /** + * 根据ID查询 + * @param id ID + * @param cancelToken 取消请求标识 + */ + getById(id: number, cancelToken?: any) { + return http({ + url: `${BASE_URL}/base/${id}`, + method: "get", + cancelToken, + }); + }, + + /** + * 新增数据 + * @param data 表单数据 + */ + add(data: EditForm) { + return http({ + url: `${BASE_URL}/base`, + method: "post", + data + }); + }, + + /** + * 修改数据 + * @param data 表单数据 + */ + update(data: EditForm) { + return http({ + url: `${BASE_URL}/base`, + method: "put", + data + }); + }, + + /** + * 根据ID集合删除 + * @param ids ID集合 + */ + deleteByIds(ids: Array) { + return http({ + url: `${BASE_URL}/base`, + method: "delete", + data: { + idList: ids, + }, + }); + }, + + #if($exportExcel) + /** + * 导出 + * @param queryParams 搜索表单 + */ + export(queryParams?: PageQuery) { + return http({ + url: `${BASE_URL}/export`, + method: "post", + data: queryParams, + responseType: "blob", + }); + }, + + #end + #if($importExcel) + /** + * 导入 + * @param formData 表单数据 + */ + import(formData: any) { + return http({ + url: `${BASE_URL}/import`, + method: "post", + data: formData, + headers: {"Content-Type": "multipart/form-data"}, + }); + }, + + #end +} + +export default api; \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/vue/index.vue.vm b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/vue/index.vue.vm new file mode 100644 index 0000000..29a5357 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-biz/src/main/resources/templates/gen/vue/index.vue.vm @@ -0,0 +1,687 @@ + + + diff --git a/xtools-app-gen/xtools-app-gen-boot/Dockerfile b/xtools-app-gen/xtools-app-gen-boot/Dockerfile new file mode 100644 index 0000000..dbedb61 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/Dockerfile @@ -0,0 +1,10 @@ +FROM registry.cn-hangzhou.aliyuncs.com/xujun-public/liberica-openjdk-rocky:25.0.1-11 +MAINTAINER org.xujun + +ENV JVM_OPTS="" + +RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone +WORKDIR /data0/app +COPY target/xtools-app-gen-boot-1.0.0.jar /data0/app/xtools-app-gen-boot.jar + +ENTRYPOINT ["/bin/sh", "-c", "java ${JVM_OPTS} -jar /data0/app/xtools-app-gen-boot.jar"] \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-boot/pom.xml b/xtools-app-gen/xtools-app-gen-boot/pom.xml new file mode 100644 index 0000000..39fcd9b --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.xujun + xtools-app-gen + 1.0.0 + + xtools-app-gen-boot + + + + + + org.xujun + xtools-app-gen-biz + + + org.xujun + xtools-app-sys-call + + + + + + + org.xujun + xtools-app-common-sentinel + + + + org.xujun + xtools-app-monitor-client + + + + + + org.xujun + xtools-cloud-alibaba-nacos + + + + org.xujun + xtools-cloud-alibaba-sentinel + + + + + + + + org.cyclonedx + cyclonedx-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-boot/src/main/java/xtools/app/GenApplication.java b/xtools-app-gen/xtools-app-gen-boot/src/main/java/xtools/app/GenApplication.java new file mode 100644 index 0000000..08c4718 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/src/main/java/xtools/app/GenApplication.java @@ -0,0 +1,45 @@ +package xtools.app; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.util.StopWatch; +import xtools.boot.core.utils.AppUtils; + +/** + *

Title : GenApplication

+ *

Description : GenApplication

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Slf4j +@SpringBootApplication +public class GenApplication { + + /** + * Main + * + * @param args 参数 + */ + static void main(String[] args) { + StopWatch sw = new StopWatch(); + sw.start(); + runApp(args); + sw.stop(); + log.info(AppUtils.info(sw.getTotalTimeMillis())); + } + + /** + * 运行 App + * + * @param args 参数 + */ + public static void runApp(String[] args) { + SpringApplication.run(GenApplication.class, args); + } +} diff --git a/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-app-gen.yml b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-app-gen.yml new file mode 100644 index 0000000..271d18a --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-app-gen.yml @@ -0,0 +1,82 @@ +# 代码生成器配置 +gen: + # 下载代码文件名称 + downloadFileName: xtools-code.zip + # 后端项目名称 + backendAppName: xtools-app + # 前端项目名称 + frontendAppName: xtools-manager + # 排除数据表 + excludeTables: + - log + # 默认配置 + defaultConfig: + # 作者 + author: xujun + # 版本 + version: 1.0.0 + # 模块名称 + moduleName: system + # 过滤配置 + filterConfig: + # 列注释过滤(正则) + columnRemarks: + - '\[.*?]' + # 模板配置 + templateConfigs: + TS_API: + templatePath: gen/ts/api.ts.vm + subPackageName: api + extension: .ts + VUE_VIEW: + templatePath: gen/vue/index.vue.vm + subPackageName: view + extension: .vue + Api: + templatePath: gen/api/api.java.vm + subPackageName: api + projectModule: api + Call: + templatePath: gen/call/call.java.vm + subPackageName: call + projectModule: call + Controller: + templatePath: gen/controller/controller.java.vm + subPackageName: controller + Convert: + templatePath: gen/convert/convert.java.vm + subPackageName: convert + BaseService: + templatePath: gen/service/serviceBase.java.vm + subPackageName: service.base + Service: + templatePath: gen/service/service.java.vm + subPackageName: service + ServiceImpl: + templatePath: gen/service/serviceImpl.java.vm + subPackageName: service.impl + Mapper: + templatePath: gen/mapper/mapper.java.vm + subPackageName: mapper + Entity: + templatePath: gen/model/entity/entity.java.vm + subPackageName: model.entity + PageReq: + templatePath: gen/model/dto/pageReq.java.vm + subPackageName: model.dto.req + AddReq: + templatePath: gen/model/dto/addReq.java.vm + subPackageName: model.dto.req + UpdateReq: + templatePath: gen/model/dto/updateReq.java.vm + subPackageName: model.dto.req + Resp: + templatePath: gen/model/dto/resp.java.vm + subPackageName: model.dto.resp + Excel: + templatePath: gen/model/dto/excel.java.vm + subPackageName: model.dto.excel + Sql: + templatePath: gen/sql/db.sql.vm + subPackageName: + extension: .sql diff --git a/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-nacos.yml b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-nacos.yml new file mode 100644 index 0000000..fc864a5 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application-nacos.yml @@ -0,0 +1,45 @@ +# Spring 信息 +spring: + cloud: + # Nacos 配置信息 + nacos: + # Nacos 发现配置信息 + discovery: + # Nacos 发现服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 发现服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 发现服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 发现服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_DISCOVERY_NAMESPACE:xtools-cloud} + # 仅ipv4模式 + ip-type: IPv4 + # Nacos 配置中心信息 + config: + # Nacos 配置服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 配置服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 配置服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 配置服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_CONFIG_NAMESPACE:xtools-cloud} + # 配置文件 + config: + import: + # Boot配置文件 + - nacos:application-boot-base.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-db.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-druid.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-knife4j.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-log.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-mybatis-plus.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-monitor.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-rabbitmq.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-redis.yaml?refreshEnabled=true&group=BOOT + # Cloud配置文件 + - nacos:application-cloud-sentinel.yaml?refreshEnabled=true&group=CLOUD + # Customizer配置文件 + - nacos:application-customizer-log.yaml?refreshEnabled=true&group=CUSTOMIZER + # App配置文件 \ No newline at end of file diff --git a/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application.yml b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application.yml new file mode 100644 index 0000000..1e77674 --- /dev/null +++ b/xtools-app-gen/xtools-app-gen-boot/src/main/resources/application.yml @@ -0,0 +1,17 @@ +# Spring 配置 +spring: + # 应用配置 + application: + # 应用名称 + name: xtools-app-gen + # 环境配置 + profiles: + active: + - info + - nacos + - app-gen + +# 服务器配置 +server: + # 端口 + port: ${GEN_SERVICE_PORT:18002} \ No newline at end of file diff --git a/xtools-app-monitor/pom.xml b/xtools-app-monitor/pom.xml new file mode 100644 index 0000000..a1d3e28 --- /dev/null +++ b/xtools-app-monitor/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.xujun + xtools-app + 1.0.0 + + pom + xtools-app-monitor + + + + xtools-app-monitor-boot + xtools-app-monitor-client + + + \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/Dockerfile b/xtools-app-monitor/xtools-app-monitor-boot/Dockerfile new file mode 100644 index 0000000..1777cad --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/Dockerfile @@ -0,0 +1,10 @@ +FROM registry.cn-hangzhou.aliyuncs.com/xujun-public/liberica-openjdk-rocky:25.0.1-11 +MAINTAINER org.xujun + +ENV JVM_OPTS="" + +RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone +WORKDIR /data0/app +COPY target/xtools-app-monitor-boot-1.0.0.jar /data0/app/xtools-app-monitor-boot.jar + +ENTRYPOINT ["/bin/sh", "-c", "java ${JVM_OPTS} -jar /data0/app/xtools-app-monitor-boot.jar"] \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/pom.xml b/xtools-app-monitor/xtools-app-monitor-boot/pom.xml new file mode 100644 index 0000000..a4956c6 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + org.xujun + xtools-app-monitor + 1.0.0 + + xtools-app-monitor-boot + + + + + + org.xujun + xtools-cloud-alibaba-nacos + + + + + + de.codecentric + spring-boot-admin-starter-server + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-web + + + org.hibernate.validator + hibernate-validator + + + + + + + + + + + org.cyclonedx + cyclonedx-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/MonitorApplication.java b/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/MonitorApplication.java new file mode 100644 index 0000000..5ef232d --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/MonitorApplication.java @@ -0,0 +1,48 @@ +package xtools.app; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.util.StopWatch; +import xtools.boot.core.utils.AppUtils; + +/** + *

Title : MonitorApplication

+ *

Description : MonitorApplication

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Slf4j +@EnableAdminServer +@SpringBootApplication +public class MonitorApplication { + + /** + * Main + * + * @param args 参数 + */ + static void main(String[] args) { + StopWatch sw = new StopWatch(); + sw.start(); + runApp(args); + sw.stop(); + log.info(AppUtils.info(sw.getTotalTimeMillis())); + } + + /** + * 运行App + * + * @param args 参数 + */ + public static void runApp(String[] args) { + SpringApplication.run(MonitorApplication.class, args); + } + +} \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/monitor/boot/config/SecurityConfig.java b/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/monitor/boot/config/SecurityConfig.java new file mode 100644 index 0000000..a5abfb0 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/java/xtools/app/monitor/boot/config/SecurityConfig.java @@ -0,0 +1,77 @@ +package xtools.app.monitor.boot.config; + +import de.codecentric.boot.admin.server.config.AdminServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; + +/** + *

Title : SecurityConfig

+ *

Description : SecurityConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Configuration +public class SecurityConfig { + + /** + * Admin配置信息 + **/ + private final String adminContextPath; + + /** + * 构造方法 + * + * @param adminServerProperties AdminServer配置信息 + */ + public SecurityConfig(AdminServerProperties adminServerProperties) { + this.adminContextPath = adminServerProperties.getContextPath(); + } + + /** + * 自定义Security过滤链 + * + * @param httpSecurity HttpSecurity + * @return Security过滤链 + */ + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) { + // 登录成功处理类 + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successHandler.setTargetUrlParameter("redirectTo"); + successHandler.setDefaultTargetUrl(adminContextPath + "/"); + + // 无需授权的资源 + String[] urls = { + // 静态文件 + adminContextPath + "/assets/**", + // 登录页面 + adminContextPath + "/login" + }; + + httpSecurity + .headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) + // 授权机制 + .authorizeHttpRequests(auth -> auth.requestMatchers(urls).permitAll().anyRequest().authenticated()) + // 登录页面配置,用于替换security默认页面 + .formLogin(req -> req.loginPage(adminContextPath + "/login").successHandler(successHandler)) + // 登出页面配置,用于替换security默认页面 + .logout(req -> req.logoutUrl(adminContextPath + "/logout")) + // 启用httpBasic认证模式 + .httpBasic(httpBasic -> { + }) + // 禁用csrf + .csrf(AbstractHttpConfigurer::disable); + return httpSecurity.build(); + } + +} \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-app-monitor.yaml b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-app-monitor.yaml new file mode 100644 index 0000000..49f4336 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-app-monitor.yaml @@ -0,0 +1,9 @@ +spring: + boot: + admin: + # UI配置 + ui: + # 页面标题 + title: ${MONITOR_UI_TITLE:xToolsMonitor} + # 导航栏中显示的品牌 + brand: ${MONITOR_UI_BRAND:xToolsMonitor} \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-info.yml b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-info.yml new file mode 100644 index 0000000..6d74815 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-info.yml @@ -0,0 +1,15 @@ +# App信息 +info: + app: + # 作者 + author: '@project.organization.name@' + # 项目名 + name: '@project.artifactId@' + # 版本号 + version: '@project.version@' + # 项目编码 + encoding: '@project.build.sourceEncoding@' + # Url + url: '@project.organization.url@' + # Java版本 + java: '@java.version@' diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-nacos.yml b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-nacos.yml new file mode 100644 index 0000000..ea1a6c1 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application-nacos.yml @@ -0,0 +1,35 @@ +# Spring 信息 +spring: + cloud: + # Nacos 配置信息 + nacos: + # Nacos 发现配置信息 + discovery: + # Nacos 发现服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 发现服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 发现服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 发现服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_DISCOVERY_NAMESPACE:xtools-cloud} + # 仅ipv4模式 + ip-type: IPv4 + # Nacos 配置中心信息 + config: + # Nacos 配置服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 配置服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 配置服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 配置服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_CONFIG_NAMESPACE:xtools-cloud} + # 配置文件 + config: + import: + # Boot配置文件 + - nacos:application-boot-log.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-monitor.yaml?refreshEnabled=true&group=BOOT + # App配置文件 + - nacos:application-app-monitor.yaml?refreshEnabled=true&group=APP \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application.yml b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application.yml new file mode 100644 index 0000000..826126d --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-boot/src/main/resources/application.yml @@ -0,0 +1,16 @@ +# Spring 配置 +spring: + # 应用配置 + application: + # 应用名称 + name: xtools-app-monitor + # 环境配置 + profiles: + active: + - info + - nacos + +# 服务器配置 +server: + # 端口 + port: ${MONITOR_SERVICE_PORT:18100} \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-client/pom.xml b/xtools-app-monitor/xtools-app-monitor-client/pom.xml new file mode 100644 index 0000000..9e14513 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-client/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.xujun + xtools-app-monitor + 1.0.0 + + xtools-app-monitor-client + + + + + + + org.xujun + xtools-boot-core + + + + + + + de.codecentric + spring-boot-admin-starter-client + + + + org.springframework.boot + spring-boot-starter-security + + + + + \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminFilterWhitelist.java b/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminFilterWhitelist.java new file mode 100644 index 0000000..cb4ab30 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminFilterWhitelist.java @@ -0,0 +1,33 @@ +package xtools.app.monitor.client.config; + +import org.springframework.stereotype.Component; +import xtools.boot.core.interfaces.FilterWhitelist; + +import java.util.Set; + +/** + *

Title : BootAdminFilterWhitelist

+ *

Description : BootAdminFilterWhitelist

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/8 12:28 + */ +@Component +public class BootAdminFilterWhitelist implements FilterWhitelist { + + /** + * 添加过滤器白名单 + * + * @return 过滤器白名单 + */ + @Override + public Set add() { + return Set.of( + "/actuator/**" + ); + } +} diff --git a/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminSecurityConfig.java b/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminSecurityConfig.java new file mode 100644 index 0000000..e4243b5 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-client/src/main/java/xtools/app/monitor/client/config/BootAdminSecurityConfig.java @@ -0,0 +1,43 @@ +package xtools.app.monitor.client.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; + +/** + *

Title : SecurityConfig

+ *

Description : SecurityConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Configuration +//@AutoConfiguration(before = ManagementWebSecurityAutoConfiguration.class) +public class BootAdminSecurityConfig { + + /** + * 自定义Security过滤链 + * + * @param httpSecurity HttpSecurity + * @return Security过滤链 + */ + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) { + httpSecurity + // [/actuator/**]下的所有请求需要权限,其他请求全部允许 + .authorizeHttpRequests( + auth -> auth.requestMatchers("/actuator/**").authenticated().anyRequest().permitAll()) + // 启用httpBasic认证模式 + .httpBasic(_ -> { + }) + // 禁用csrf + .csrf(AbstractHttpConfigurer::disable); + return httpSecurity.build(); + } +} \ No newline at end of file diff --git a/xtools-app-monitor/xtools-app-monitor-client/src/main/resources/application-info.yml b/xtools-app-monitor/xtools-app-monitor-client/src/main/resources/application-info.yml new file mode 100644 index 0000000..6d74815 --- /dev/null +++ b/xtools-app-monitor/xtools-app-monitor-client/src/main/resources/application-info.yml @@ -0,0 +1,15 @@ +# App信息 +info: + app: + # 作者 + author: '@project.organization.name@' + # 项目名 + name: '@project.artifactId@' + # 版本号 + version: '@project.version@' + # 项目编码 + encoding: '@project.build.sourceEncoding@' + # Url + url: '@project.organization.url@' + # Java版本 + java: '@java.version@' diff --git a/xtools-app-standalone/Dockerfile b/xtools-app-standalone/Dockerfile new file mode 100644 index 0000000..44eba10 --- /dev/null +++ b/xtools-app-standalone/Dockerfile @@ -0,0 +1,10 @@ +FROM registry.cn-hangzhou.aliyuncs.com/xujun-public/liberica-openjdk-rocky:25.0.1-11 +MAINTAINER org.xujun + +ENV JVM_OPTS="" + +RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone +WORKDIR /data0/app +COPY target/xtools-app-standalone-1.0.0.jar /data0/app/xtools-app-standalone.jar + +ENTRYPOINT ["/bin/sh", "-c", "java ${JVM_OPTS} -jar /data0/app/xtools-app-standalone.jar"] \ No newline at end of file diff --git a/xtools-app-standalone/pom.xml b/xtools-app-standalone/pom.xml new file mode 100644 index 0000000..66fd0ea --- /dev/null +++ b/xtools-app-standalone/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.xujun + xtools-app + 1.0.0 + + xtools-app-standalone + + + + + + org.xujun + xtools-app-sys-biz + + + org.xujun + xtools-app-gen-biz + + + + + + + + + + + org.xujun + xtools-app-sys-scheduled + + + org.xujun + xtools-app-sys-log-bus-elasticsearch + + + + + + + + + org.xujun + xtools-boot-storage-s3 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/xtools-app-standalone/src/main/java/xtools/app/StandaloneApplication.java b/xtools-app-standalone/src/main/java/xtools/app/StandaloneApplication.java new file mode 100644 index 0000000..2142be4 --- /dev/null +++ b/xtools-app-standalone/src/main/java/xtools/app/StandaloneApplication.java @@ -0,0 +1,46 @@ +package xtools.app; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.util.StopWatch; +import xtools.boot.core.utils.AppUtils; + +/** + *

Title : StandaloneApplication

+ *

Description : StandaloneApplication

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Slf4j +@SpringBootApplication +public class StandaloneApplication { + + /** + * Main + * + * @param args 参数 + */ + static void main(String[] args) { + StopWatch sw = new StopWatch(); + sw.start(); + runApp(args); + sw.stop(); + log.info(AppUtils.info(sw.getTotalTimeMillis())); + + } + + /** + * 运行 App + * + * @param args 参数 + */ + public static void runApp(String[] args) { + SpringApplication.run(StandaloneApplication.class, args); + } +} diff --git a/xtools-app-standalone/src/main/resources/application-app-gen.yml b/xtools-app-standalone/src/main/resources/application-app-gen.yml new file mode 100644 index 0000000..271d18a --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-app-gen.yml @@ -0,0 +1,82 @@ +# 代码生成器配置 +gen: + # 下载代码文件名称 + downloadFileName: xtools-code.zip + # 后端项目名称 + backendAppName: xtools-app + # 前端项目名称 + frontendAppName: xtools-manager + # 排除数据表 + excludeTables: + - log + # 默认配置 + defaultConfig: + # 作者 + author: xujun + # 版本 + version: 1.0.0 + # 模块名称 + moduleName: system + # 过滤配置 + filterConfig: + # 列注释过滤(正则) + columnRemarks: + - '\[.*?]' + # 模板配置 + templateConfigs: + TS_API: + templatePath: gen/ts/api.ts.vm + subPackageName: api + extension: .ts + VUE_VIEW: + templatePath: gen/vue/index.vue.vm + subPackageName: view + extension: .vue + Api: + templatePath: gen/api/api.java.vm + subPackageName: api + projectModule: api + Call: + templatePath: gen/call/call.java.vm + subPackageName: call + projectModule: call + Controller: + templatePath: gen/controller/controller.java.vm + subPackageName: controller + Convert: + templatePath: gen/convert/convert.java.vm + subPackageName: convert + BaseService: + templatePath: gen/service/serviceBase.java.vm + subPackageName: service.base + Service: + templatePath: gen/service/service.java.vm + subPackageName: service + ServiceImpl: + templatePath: gen/service/serviceImpl.java.vm + subPackageName: service.impl + Mapper: + templatePath: gen/mapper/mapper.java.vm + subPackageName: mapper + Entity: + templatePath: gen/model/entity/entity.java.vm + subPackageName: model.entity + PageReq: + templatePath: gen/model/dto/pageReq.java.vm + subPackageName: model.dto.req + AddReq: + templatePath: gen/model/dto/addReq.java.vm + subPackageName: model.dto.req + UpdateReq: + templatePath: gen/model/dto/updateReq.java.vm + subPackageName: model.dto.req + Resp: + templatePath: gen/model/dto/resp.java.vm + subPackageName: model.dto.resp + Excel: + templatePath: gen/model/dto/excel.java.vm + subPackageName: model.dto.excel + Sql: + templatePath: gen/sql/db.sql.vm + subPackageName: + extension: .sql diff --git a/xtools-app-standalone/src/main/resources/application-app-sys.yaml b/xtools-app-standalone/src/main/resources/application-app-sys.yaml new file mode 100644 index 0000000..24f9fbf --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-app-sys.yaml @@ -0,0 +1,10 @@ +# 系统配置 +sys: + # 用户配置 + user: + # 初始化密码 + passwd: ${SYS_USER_PASSWD:xtools} + # 日志配置 + log: + # 存储类型(elasticsearch|mysql) + type: ${SYS_LOG_TYPE:elasticsearch} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-base.yaml b/xtools-app-standalone/src/main/resources/application-boot-base.yaml new file mode 100644 index 0000000..a851251 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-base.yaml @@ -0,0 +1,10 @@ +# Spring 配置 +spring: + # 虚拟线程配置 + threads: + virtual: + enabled: true + # jackson配置 + jackson: + # 不输出null + default-property-inclusion: non_null \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-db.yaml b/xtools-app-standalone/src/main/resources/application-boot-db.yaml new file mode 100644 index 0000000..2a0930e --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-db.yaml @@ -0,0 +1,41 @@ +# 数据库配置 +spring: + datasource: + # 数据源名称 + name: mysqlDataSource + # 数据库驱动 + driverClassName: com.mysql.cj.jdbc.Driver + # 数据库连接地址 + url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:xtools}?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + # 数据库用户名 + username: ${DB_USERNAME:root} + # 数据库密码 + password: ${DB_PASSWORD:root} + # 数据库类型 + type: com.alibaba.druid.pool.DruidDataSource + druid: + # 连接池配置 + # 初始化时建立物理连接的个数.初始化发生在显示调用init方法,或者第一次getConnection时 + initial-size: 1 + # 最小连接池数量 + min-idle: 5 + # 最大连接池数量 + max-active: 30 + # 获取连接时最大等待时间,单位毫秒.配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁 + max-wait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + time-between-eviction-runs-millis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + min-evictable-idle-time-millis: 300000 + # 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'.如果validationQuery为null,testOnBorrow,testOnReturn,testWhileIdle都不会起作用 + validation-query: SELECT 'x' + # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 + test-on-borrow: false + # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 + test-on-return: false + # 建议配置为true,不影响性能,并且保证安全性.申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 + test-while-idle: true + # 是否缓存preparedStatement,也就是PSCache.PSCache对支持游标的数据库性能提升巨大,比如说oracle.在mysql下建议关闭 + pool-prepared-statements: false + # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true.在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 + max-pool-prepared-statement-per-connection-size: 10 \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-druid.yaml b/xtools-app-standalone/src/main/resources/application-boot-druid.yaml new file mode 100644 index 0000000..996c678 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-druid.yaml @@ -0,0 +1,35 @@ +# 数据库配置 +spring: + datasource: + druid: + # 使用的过滤器类型 + filters: stat,wall,config + + # WebStatFilter配置 + web-stat-filter: + # 是否启用WebStatFilter + enabled: true + # 过滤地址 + url-pattern: /* + # 过滤地址排除 + exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/actuator,/actuator/*,/druid/*" + + # StatViewServlet配置 + stat-view-servlet: + # 是否启用StatViewServlet + enabled: true + # 监控地址前缀 + url-pattern: /druid/* + # 能否重置数据 + reset-enable: false + # 登录用户名 + login-username: ${DRUID_USERNAME:xtools} + # 登录密码 + login-password: ${DRUID_PASSWORD:xtools321} + # IP白名单 + allow: + # IP黑名单(黑名单优先级高于白名单) + deny: + + # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔 +# aop-patterns: "xtools.app.*,*" \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-elasticsearch.yaml b/xtools-app-standalone/src/main/resources/application-boot-elasticsearch.yaml new file mode 100644 index 0000000..e198c26 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-elasticsearch.yaml @@ -0,0 +1,9 @@ +# elasticsearch配置 +spring: + elasticsearch: + # elasticsearch地址 + uris: ${ELASTICSEARCH_URIS:http://127.0.0.1:9200} + # 账号 + username: ${ELASTICSEARCH_USERNAME:elastic} + # 密码 + password: ${ELASTICSEARCH_PASSWORD:123456} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-knife4j.yaml b/xtools-app-standalone/src/main/resources/application-boot-knife4j.yaml new file mode 100644 index 0000000..a863ae1 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-knife4j.yaml @@ -0,0 +1,22 @@ +# springdoc-openapi项目配置 +springdoc: + swagger-ui: + enabled: true + path: /swagger-ui.html + tags-sorter: alpha + operations-sorter: alpha + api-docs: + enabled: true + path: /v3/api-docs + group-configs: + - group: 'default' + paths-to-match: '/**' + # packages-to-scan: xtools.app + +# knife4j的增强配置,不需要增强可以不配 +knife4j: + # 是否为生产环境,开启生产环境后swagger不可用,需要同时配置production,enable为true + production: false + enable: false + setting: + language: zh_cn \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-log.yaml b/xtools-app-standalone/src/main/resources/application-boot-log.yaml new file mode 100644 index 0000000..ad9fbee --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-log.yaml @@ -0,0 +1,4 @@ +# 日志配置 +logging: + level: + root: info diff --git a/xtools-app-standalone/src/main/resources/application-boot-monitor.yaml b/xtools-app-standalone/src/main/resources/application-boot-monitor.yaml new file mode 100644 index 0000000..ad51ecc --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-monitor.yaml @@ -0,0 +1,38 @@ +# 管理信息配置 +management: + info: + env: + # 是否显示项目信息 + enabled: true + endpoint: + health: + # health endpoint是否必须显示全部细节 + show-details: always + endpoints: + web: + exposure: + # 暴露的管理模块 + include: "*" + +spring: + # Spring安全信息配置 + security: + user: + # 用户名 + name: ${SPRING_SECURITY_USERNAME:admin} + # 密码 + password: ${SPRING_SECURITY_PASSWORD:123456} + cloud: + nacos: + discovery: + metadata: + user: + # 认证用户名 + name: ${spring.security.user.name} + # 认证密码 + password: ${spring.security.user.password} + management: + # 服务器上下文路径服务器路径改变后需要改变监控地址 + context-path: /actuator + # 服务器上下文路径服务器路径改变后需要改变心跳地址 + health: /health \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-mybatis-plus.yaml b/xtools-app-standalone/src/main/resources/application-boot-mybatis-plus.yaml new file mode 100644 index 0000000..c6b316d --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-mybatis-plus.yaml @@ -0,0 +1,8 @@ +# MyBatisPlus 配置 +mybatis-plus: + global-config: + # 控制台是否打印 LOGO + banner: false +# configuration: +# # 打印 SQL +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-rabbitmq.yaml b/xtools-app-standalone/src/main/resources/application-boot-rabbitmq.yaml new file mode 100644 index 0000000..129dbb5 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-rabbitmq.yaml @@ -0,0 +1,13 @@ +# rabbitmq 配置 +spring: + rabbitmq: + # 主机地址 + host: ${RABBITMQ_HOST:127.0.0.1} + # 端口 + port: ${RABBITMQ_PORT:5672} + # 用户名 + username: ${RABBITMQ_USERNAME:admin} + # 密码 + password: ${RABBITMQ_PASSWORD:123456} + # 虚拟主机 + virtual-host: ${RABBITMQ_VIRTUAL_HOST:xtools-app} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-redis.yaml b/xtools-app-standalone/src/main/resources/application-boot-redis.yaml new file mode 100644 index 0000000..803265e --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-redis.yaml @@ -0,0 +1,26 @@ +spring: + data: + # Redis 配置 + redis: + # 数据库索引(默认为0) + database: ${REDIS_DATABASE:0} + # 服务器地址 + host: ${REDIS_HOST:127.0.0.1} + # 服务器连接端口 + port: ${REDIS_PORT:6379} + # 服务器连接密码(默认为空) + password: ${REDIS_PASSWORD:123456} + # 连接超时时间(毫秒) + timeout: 100000 + lettuce: + # 连接池中的关闭超时时间 + shutdown-timeout: 100000 + pool: + # 连接池最大连接数(使用负值表示没有限制) + max-active: 50 + # 连接池中的最大空闲连接 + max-idle: 10 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1 + # 连接池中的最小空闲连接 + min-idle: 5 \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-boot-storage.yaml b/xtools-app-standalone/src/main/resources/application-boot-storage.yaml new file mode 100644 index 0000000..23eb66f --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-storage.yaml @@ -0,0 +1,18 @@ +# 存储配置 +storage: + # 存储类型[file|s3](并且需要引入对应的jar包) + type: ${STORAGE_TYPE:file} + # 文件类型 + file: + # 文件存储路径 + path: ${STORAGE_FILE_PATH:/data/xtools/file} + # S3类型 + s3: + # 服务类型(可为空)[rustfs] + server: ${STORAGE_S3_SERVER:rustfs} + # 地址 + host: ${STORAGE_S3_HOST:http://127.0.0.1:9000} + # 密钥ID + accessKeyId: ${STORAGE_S3_ACCESS_KEY_ID:admin} + # 密钥 + secretAccessKey: ${STORAGE_S3_SECRET_ACCESS_KEY:123456} diff --git a/xtools-app-standalone/src/main/resources/application-boot-xxl-job.yaml b/xtools-app-standalone/src/main/resources/application-boot-xxl-job.yaml new file mode 100644 index 0000000..c8408e9 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-boot-xxl-job.yaml @@ -0,0 +1,26 @@ +xxl: + job: + admin: + # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔.执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; + addresses: ${XXL_JOB_ADMIN_ADDR:http://127.0.0.1:8080/xxl-job-admin} + # 调度中心通讯TOKEN [选填]:非空时启用; + accessToken: ${XXL_JOB_ADMIN_TOKEN:xtools-app-xxl-job} + # 调度中心通讯超时时间[选填],单位秒;默认3s; + timeout: ${XXL_JOB_ADMIN_TIMEOUT:3} + executor: + # 执行器启用开关 [选填]:默认开启,关闭时不进行执行器初始化; + enabled: ${XXL_JOB_ENABLED:false} + # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + appName: ${spring.application.name} + # 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址.从而更灵活支持容器类型执行器动态IP和动态映射端口问题. + address: ${XXL_JOB_ADDR:} + # 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯使用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; + ip: ${XXL_JOB_IP:} + # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + port: ${XXL_JOB_PORT:9999} + # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + logPath: ${XXL_JOB_LOG_PATH:} + # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; + logRetentionDays: ${XXL_JOB_LOG_RETENTION_DAYS:30} + # 任务扫描排除路径 [选填] :任务扫描时忽略指定包路径下的Bean;支持配置包路径前缀,多个逗号分隔; + excludedPackage: ${XXL_JOB_EXCLUDED_PACKAGE:} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-cloud-sentinel.yaml b/xtools-app-standalone/src/main/resources/application-cloud-sentinel.yaml new file mode 100644 index 0000000..7bf0468 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-cloud-sentinel.yaml @@ -0,0 +1,14 @@ +# Sentinel配置 +spring: + cloud: + sentinel: + # 启动时立即注册 + eager: true + log: + # sentinel日志保存路径 + dir: ${SENTINEL_LOG_DIR:/data/xtools/scp}/${spring.application.name} + transport: + # dashboard服务器地址[默认值:127.0.0.1:8080] + dashboard: ${SENTINEL_DASHBOARD:127.0.0.1:8080} + # 指定客户端ip(防止ipv6的情况) + client-ip: ${CLIENT_IP:} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-customizer-api.yaml b/xtools-app-standalone/src/main/resources/application-customizer-api.yaml new file mode 100644 index 0000000..9c47d29 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-customizer-api.yaml @@ -0,0 +1,6 @@ +# api配置 +api: + # 百度api + baidu: + # 百度地图ak + ak: ${API_BAIDU_AK:abc} \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application-customizer-log.yaml b/xtools-app-standalone/src/main/resources/application-customizer-log.yaml new file mode 100644 index 0000000..9403ced --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application-customizer-log.yaml @@ -0,0 +1,22 @@ +# 系统日志配置 +sys: + log: + # 追踪配置 + track: + # 日志追踪忽略路径 + ignore-path: + - /sys/login/captcha/* + - /sys/log/* + - /sys/log/*/* + - /sys/dict/getByCode/* + - /sys/home/* + # LogBus 配置 + bus: + # 是否打印日志 + print: false + # 包含的堆栈信息(开始的包名) + include-stack-trace: + - xtools + - org.xujun + # 日志项最大长度 + logDataItemMax: -1 \ No newline at end of file diff --git a/xtools-app-standalone/src/main/resources/application.yml b/xtools-app-standalone/src/main/resources/application.yml new file mode 100644 index 0000000..a2c9cb9 --- /dev/null +++ b/xtools-app-standalone/src/main/resources/application.yml @@ -0,0 +1,32 @@ +# Spring 配置 +spring: + # 应用配置 + application: + # 应用名称 + name: xtools-app-standalone + # 环境配置 + profiles: + active: + # Boot + - boot-base + - boot-db + - boot-druid + - boot-elasticsearch + - boot-knife4j + - boot-log + - boot-mybatis-plus + - boot-rabbitmq + - boot-redis + - boot-xxl-job + - boot-storage + # Customizer + - customizer-api + - customizer-log + # App + - app-gen + - app-sys + +# 服务器配置 +server: + # 端口 + port: ${STANDALONE_SERVICE_PORT:18000} \ No newline at end of file diff --git a/xtools-app-sys/pom.xml b/xtools-app-sys/pom.xml new file mode 100644 index 0000000..27a7332 --- /dev/null +++ b/xtools-app-sys/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + org.xujun + xtools-app + 1.0.0 + + xtools-app-sys + pom + + + + xtools-app-sys-api + xtools-app-sys-auth + xtools-app-sys-biz + xtools-app-sys-boot + xtools-app-sys-call + xtools-app-sys-file + xtools-app-sys-log-bus-elasticsearch + xtools-app-sys-param + xtools-app-sys-scheduled + xtools-app-sys-risk + xtools-app-sys-file-web + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/pom.xml b/xtools-app-sys/xtools-app-sys-api/pom.xml new file mode 100644 index 0000000..64a93c7 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-api + + + + + + + org.xujun + xtools-boot-api + + + + org.xujun + xtools-boot-mask + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysAddressApi.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysAddressApi.java new file mode 100644 index 0000000..6f97de0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysAddressApi.java @@ -0,0 +1,28 @@ +package xtools.app.sys.api; + +import jakarta.validation.constraints.NotEmpty; +import xtools.app.sys.model.dto.resp.SysAddressResp; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysAddressApi

+ *

Description : 公用地址表 Api

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +public interface SysAddressApi { + + /** + * 根据code获取地址信息 + * + * @param code Code + * @return 地址信息 + */ + Result getByCode( + @NotEmpty(message = "不能为空") String code + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysDictItemApi.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysDictItemApi.java new file mode 100644 index 0000000..b918d98 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysDictItemApi.java @@ -0,0 +1,32 @@ +package xtools.app.sys.api; + +import jakarta.validation.constraints.NotEmpty; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysDictItemApi

+ *

Description : SysDictItemApi

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/27 10:36 + */ +public interface SysDictItemApi { + + /** + * 根据字典编码查询字典项 + * + * @param dictCode 字典编码 + * @return 字典项 + */ + Result> getByCode( + @NotEmpty(message = "不能为空") String dictCode + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysFileApi.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysFileApi.java new file mode 100644 index 0000000..1882a2e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysFileApi.java @@ -0,0 +1,83 @@ +package xtools.app.sys.api; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileChangeReq; +import xtools.app.sys.model.dto.req.SysFileUpdateReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysFileApi

+ *

Description : 系统文件表 Api

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +public interface SysFileApi { + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById( + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + Long id + ); + + /** + * 根据文件名查询 + * + * @param bucket 桶名称 + * @param fileName 文件名 + * @return 结果 + */ + Result getByName( + @NotBlank(message = "不能为空") + String bucket, + @NotBlank(message = "不能为空") + String fileName + ); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(@Valid SysFileAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(@Valid SysFileUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(@Valid IdListReq req); + + /** + * 改变数据类型 + * + * @param req 请求参数 + * @return 是否成功 + */ + Result changeDataTypeByIds(@Valid SysFileChangeReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysParamApi.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysParamApi.java new file mode 100644 index 0000000..f88da1a --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysParamApi.java @@ -0,0 +1,35 @@ +package xtools.app.sys.api; + +import jakarta.validation.Valid; +import xtools.app.sys.model.dto.req.SysParamAddReq; +import xtools.app.sys.model.dto.req.SysParamUpdateReq; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysParamApi

+ *

Description : 系统参数表 Api

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-26 10:15:49 + */ +public interface SysParamApi { + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(@Valid SysParamAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(@Valid SysParamUpdateReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysRiskApi.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysRiskApi.java new file mode 100644 index 0000000..777d148 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/api/SysRiskApi.java @@ -0,0 +1,61 @@ +package xtools.app.sys.api; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysRiskApi

+ *

Description : 系统风控表 Api

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +public interface SysRiskApi { + + /** + * 根据类型获取数据 + * + * @param type 类型 + * @return 数据 + */ + Result> getByType( + @NotNull(message = "不能为空") + SysRiskType type + ); + + /** + * 添加IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + Result addIp( + @NotBlank(message = "不能为空") + String sysType, + @NotBlank(message = "不能为空") + String ip + ); + + /** + * 移除IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 移除结果 + */ + Result removeIp( + @NotBlank(message = "不能为空") + String sysType, + @NotBlank(message = "不能为空") + String ip + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/enums/SysRiskType.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/enums/SysRiskType.java new file mode 100644 index 0000000..18b7c22 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/enums/SysRiskType.java @@ -0,0 +1,76 @@ +package xtools.app.sys.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysRiskType

+ *

Description : SysRiskType

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/4 16:27 + */ +public enum SysRiskType implements BaseEnum { + + // IP风控 + IP(1, "IP风控"), + // URI风控 + URI(2, "URI风控"), + ; + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + + /** + * 构造函数 + * + * @param code 编码 + * @param desc 说明 + */ + SysRiskType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileAddReq.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileAddReq.java new file mode 100644 index 0000000..c051fd5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileAddReq.java @@ -0,0 +1,129 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysFileAddReq

+ *

Description : 系统文件表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysFileAddReq implements Serializable { + + /** + * 用户id + */ + @Schema(description = "用户id") + private Long userId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + private String userName; + + /** + * 业务id + */ + @Schema(description = "业务id") + private Long bizId; + + /** + * 业务类型 + */ + @Schema(description = "业务类型") + private String bizType; + + /** + * 权限 + */ + @Schema(description = "权限") + private Integer permission; + + /** + * 桶名称 + */ + @Schema(description = "桶名称") + private String bucket; + + /** + * 桶类型 + */ + @Schema(description = "桶类型") + private String storageType; + + /** + * 文件上传时间 + */ + @Schema(description = "文件上传时间") + private Instant uploadTime; + + /** + * 文件路径 + */ + @Schema(description = "文件路径") + private String filePath; + + /** + * 文件名 + */ + @Schema(description = "文件名") + private String fileName; + + /** + * 文件大小 + */ + @Schema(description = "文件大小") + private Long fileSize; + + /** + * 文件类型 + */ + @Schema(description = "文件类型") + private String fileType; + + /** + * MD5值 + */ + @Schema(description = "MD5值") + private String md5; + + /** + * SM3值 + */ + @Schema(description = "SM3值") + private String sm3; + + /** + * 数据类型 + */ + @Schema(description = "数据类型") + private Integer dataType; + + /** + * 过期时间 + */ + @Schema(description = "过期时间") + private Instant expireTime; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileChangeReq.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileChangeReq.java new file mode 100644 index 0000000..155bf37 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileChangeReq.java @@ -0,0 +1,42 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.boot.api.enums.FileDataType; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : SysFileAddReq

+ *

Description : 系统文件表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysFileChangeReq implements Serializable { + + /** + * idList + */ + @NotNull(message = "不能为空") + @Schema(description = "Id列表") + private List idList; + + /** + * 数据类型 + */ + @Schema(description = "数据类型") + private FileDataType dataType; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileUpdateReq.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileUpdateReq.java new file mode 100644 index 0000000..a682b7e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysFileUpdateReq.java @@ -0,0 +1,135 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysFileUpdateReq

+ *

Description : 系统文件表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysFileUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 用户id + */ + @Schema(description = "用户id") + private Long userId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + private String userName; + + /** + * 业务id + */ + @Schema(description = "业务id") + private Long bizId; + + /** + * 业务类型 + */ + @Schema(description = "业务类型") + private String bizType; + + /** + * 权限 + */ + @Schema(description = "权限") + private Integer permission; + + /** + * 桶名称 + */ + @Schema(description = "桶名称") + private String bucket; + + /** + * 桶类型 + */ + @Schema(description = "桶类型") + private String storageType; + + /** + * 文件上传时间 + */ + @Schema(description = "文件上传时间") + private Instant uploadTime; + + /** + * 文件路径 + */ + @Schema(description = "文件路径") + private String filePath; + + /** + * 文件名 + */ + @Schema(description = "文件名") + private String fileName; + + /** + * 文件大小 + */ + @Schema(description = "文件大小") + private Long fileSize; + + /** + * 文件类型 + */ + @Schema(description = "文件类型") + private String fileType; + + /** + * MD5值 + */ + @Schema(description = "MD5值") + private String md5; + + /** + * SM3值 + */ + @Schema(description = "SM3值") + private String sm3; + + /** + * 数据类型 + */ + @Schema(description = "数据类型") + private Integer dataType; + + /** + * 过期时间 + */ + @Schema(description = "过期时间") + private Instant expireTime; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamAddReq.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamAddReq.java new file mode 100644 index 0000000..79adc3e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamAddReq.java @@ -0,0 +1,52 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.boot.api.anntation.IgnoreXss; + +import java.io.Serializable; + +/** + *

Title : SysParamAddReq

+ *

Description : 系统参数表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysParamAddReq implements Serializable { + + /** + * 系统参数key + */ + @Schema(description = "系统参数key") + private String paramKey; + + /** + * 系统参数值 + */ + @IgnoreXss + @Schema(description = "系统参数值") + private String data; + + /** + * 参数值类型 + */ + @Schema(description = "参数值类型") + private Integer dataType; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamUpdateReq.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamUpdateReq.java new file mode 100644 index 0000000..fac55ca --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/req/SysParamUpdateReq.java @@ -0,0 +1,58 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.boot.api.anntation.IgnoreXss; + +import java.io.Serializable; + +/** + *

Title : SysParamUpdateReq

+ *

Description : 系统参数表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysParamUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统参数key + */ + @Schema(description = "系统参数key") + private String paramKey; + + /** + * 系统参数值 + */ + @IgnoreXss + @Schema(description = "系统参数值") + private String data; + + /** + * 参数值类型 + */ + @Schema(description = "参数值类型") + private Integer dataType; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysAddressResp.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysAddressResp.java new file mode 100644 index 0000000..a40c3de --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysAddressResp.java @@ -0,0 +1,73 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysAddressResp

+ *

Description : 公用地址表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysAddressResp extends BaseEntity { + + /** + * 公用地址-ID + */ + @Schema(description = "公用地址-ID") + private Long id; + + /** + * 公用地址-父ID + */ + @Schema(description = "公用地址-父ID") + private Long parentId; + + /** + * 公用地址-唯一编码 + */ + @Schema(description = "公用地址-唯一编码") + private String code; + + /** + * 公用地址-类型 + */ + @Schema(description = "公用地址-类型") + private Integer type; + + /** + * 公用地址-名称 + */ + @Schema(description = "公用地址-名称") + private String title; + + /** + * 公用地址-经度 + */ + @Schema(description = "公用地址-经度") + private String lng; + + /** + * 公用地址-纬度 + */ + @Schema(description = "公用地址-纬度") + private String lat; + + /** + * 公用地址-备注 + */ + @Schema(description = "公用地址-备注") + private String memo; + +} diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysDictItemResp.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysDictItemResp.java new file mode 100644 index 0000000..1f5e849 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysDictItemResp.java @@ -0,0 +1,94 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDictItemResp

+ *

Description : 数据字典项表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysDictItemResp extends BaseEntity { + + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @Schema(description = "关联字典编码,与sys_dict表中的dict_code对应", example = "USER_STATUS") + private String dictCode; + + + /** + * 字典项值 + */ + @Schema(description = "字典项值", example = "1") + private String value; + + + /** + * 字典项标签 + */ + @Schema(description = "字典项标签", example = "启用") + private String label; + + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @Schema(description = "标签类型,用于前端样式展示(如success,warning等)", example = "success") + private String tagType; + + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + + /** + * 创建人ID + */ + @Schema(description = "创建人ID", example = "1") + private Long createBy; + + + /** + * 修改人ID + */ + @Schema(description = "修改人ID", example = "1") + private Long updateBy; + + + /** + * 备注 + */ + @Schema(description = "备注", example = "启用状态") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysFileResp.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysFileResp.java new file mode 100644 index 0000000..137526d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysFileResp.java @@ -0,0 +1,138 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysFileResp

+ *

Description : 系统文件表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysFileResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 用户id + */ + @Schema(description = "用户id") + private Long userId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + private String userName; + + /** + * 业务id + */ + @Schema(description = "业务id") + private Long bizId; + + /** + * 业务类型 + */ + @Schema(description = "业务类型") + private String bizType; + + /** + * 权限 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "权限") + private Integer permission; + + /** + * 桶名称 + */ + @Schema(description = "桶名称") + private String bucket; + + /** + * 桶类型 + */ + @Schema(description = "桶类型") + private String storageType; + + /** + * 文件上传时间 + */ + @Schema(description = "文件上传时间") + private Instant uploadTime; + + /** + * 文件路径 + */ + @Schema(description = "文件路径") + private String filePath; + + /** + * 文件名 + */ + @Schema(description = "文件名") + private String fileName; + + /** + * 文件大小 + */ + @Schema(description = "文件大小") + private Long fileSize; + + /** + * 文件类型 + */ + @Schema(description = "文件类型") + private String fileType; + + /** + * MD5值 + */ + @Schema(description = "MD5值") + private String md5; + + /** + * SM3值 + */ + @Schema(description = "SM3值") + private String sm3; + + /** + * 数据类型 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "数据类型") + private Integer dataType; + + /** + * 过期时间 + */ + @Schema(description = "过期时间") + private Instant expireTime; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysRiskResp.java b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysRiskResp.java new file mode 100644 index 0000000..ea8e182 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-api/src/main/java/xtools/app/sys/model/dto/resp/SysRiskResp.java @@ -0,0 +1,67 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysRiskResp

+ *

Description : 系统风控表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysRiskResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private String sysType; + + /** + * 风控类型 + */ + @Schema(description = "风控类型") + private Integer type; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-auth/pom.xml b/xtools-app-sys/xtools-app-sys-auth/pom.xml new file mode 100644 index 0000000..39532a4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-auth + + + + + + + org.xujun + xtools-web + + + + org.xujun + xtools-boot-core + + + + org.xujun + xtools-boot-cache-redis + + + + org.xujun + xtools-boot-mask + + + + org.xujun + xtools-boot-web-filter + + + + + + org.xujun + xtools-app-common-cache + + + + + + org.springframework + spring-web + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + jakarta.servlet + jakarta.servlet-api + provided + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/filter/AuthFilter.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/filter/AuthFilter.java new file mode 100644 index 0000000..46a88ce --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/filter/AuthFilter.java @@ -0,0 +1,235 @@ +package xtools.app.sys.auth.filter; + +import com.alibaba.fastjson2.JSONObject; +import jakarta.annotation.Resource; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.jspecify.annotations.NonNull; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.auth.utils.PremUtils; +import xtools.app.sys.auth.whitelist.AuthWhitelist; +import xtools.base.config.BaseParams; +import xtools.boot.api.constant.BootCommonConstant; +import xtools.boot.api.enums.ResultType; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.core.holder.CommonHolder; +import xtools.boot.core.utils.PathPatternUtils; +import xtools.boot.core.utils.SpringContextUtils; +import xtools.boot.mask.utils.MaskIgnoreUtils; +import xtools.boot.web.filter.base.BaseFilter; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.web.HeaderUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + *

Title : AuthFilter

+ *

Description : AuthFilter

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 21:18 + */ +@Component +public class AuthFilter extends BaseFilter implements Ordered, BaseParams { + + /** + * 微服务标识 + */ + private static final String CLOUD_FLAG = String.valueOf(Boolean.TRUE); + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.AUTH_CLOUD_TOKEN; + + /** + * 权限白名单 + */ + private static final Set AUTH_WHITE_LIST = new HashSet<>(); + + /** + * 登录白名单 + */ + private static final Set LOGIN_WHITE_LIST = new HashSet<>(); + + @Resource + private RedisService redisService; + + @Override + public int getOrder() { + return CP_NUM200 + CP_NUM1; + } + + @Override + protected void initFilterBean() throws ServletException { + super.initFilterBean(); + Collection beanList = SpringContextUtils.getBeanList(AuthWhitelist.class); + if (CollectionUtils.isEmpty(beanList)) { + return; + } + beanList.forEach(item -> { + AUTH_WHITE_LIST.addAll(item.addAuth()); + LOGIN_WHITE_LIST.addAll(item.addLogin()); + }); + } + + @Override + protected void doFilterInternal( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + // 判断是否为微服务请求 + if (Objects.equals(HeaderUtils.getHeader(request, BootCommonConstant.CLOUD), CLOUD_FLAG)) { + // 微服务请求 + cloudAuth(request, response, filterChain); + } else { + // 常规请求 + auth(request, response, filterChain); + } + } + + /** + * 微服务验证权限 + * + * @param request 请求 + * @param response 响应 + * @param filterChain 过滤器链 + */ + private void cloudAuth( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + String token = HeaderUtils.getHeader(request, BootCommonConstant.CLOUD_TOKEN); + if (StringUtils.isBlank(token)) { + HttpServletUtils.respWriter(response, JSONObject.from(new Result<>(ResultType.UNAUTHORIZED, null))); + return; + } + Long total = redisService.hashDelete(CACHE_PARAM.key(), token); + if (Objects.isNull(total) || total < CP_NUM1) { + HttpServletUtils.respWriter(response, JSONObject.from(new Result<>(ResultType.UNAUTHORIZED, null))); + return; + } + // 传递头部信息 + String uid = AuthUtils.getUid(request); + String accessToken = AuthUtils.getAccessToken(request); + if (StringUtils.isNotBlank(uid)) { + CommonHolder.set(BootCommonConstant.UID, uid); + } + if (StringUtils.isNotBlank(accessToken)) { + CommonHolder.set(BootCommonConstant.AUTHORIZATION, accessToken); + // 校验忽略掩码 + checkIgnoreMask(); + } + + filterChain.doFilter(request, response); + } + + /** + * 常规验证权限 + * + * @param request 请求 + * @param response 响应 + * @param filterChain 过滤器链 + */ + private void auth( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + // 获取访问 uri + String uri = HeaderUtils.getUri(request); + + // 忽略权限校验 + if (checkAuthWhiteList(uri)) { + filterChain.doFilter(request, response); + return; + } + + // 验证uid + String uid = AuthUtils.getUid(request); + if (StringUtils.isBlank(uid)) { + HttpServletUtils.respWriter(response, JSONObject.from(new Result<>(ResultType.METHOD_NOT_ALLOWED, null))); + return; + } + + // 校验登录白名单 + if (checkLoginWhiteList(uri)) { + filterChain.doFilter(request, response); + return; + } + + // 校验登录权限 + String accessToken = AuthUtils.getAccessToken(request); + LoginUserDto loginUser = AuthUtils.get(accessToken); + if (Objects.isNull(loginUser)) { + HttpServletUtils.respWriter(response, JSONObject.from(new Result<>(ResultType.UNAUTHORIZED, null))); + return; + } + + + // 校验 uri 访问权限 + String method = request.getMethod(); + if (!PremUtils.checkInterfacePerm(uri, method, loginUser.getRoleIds())) { + HttpServletUtils.respWriter(response, JSONObject.from(new Result<>(ResultType.FORBIDDEN, null))); + return; + } + + CommonHolder.set(BootCommonConstant.UID, uid); + CommonHolder.set(BootCommonConstant.AUTHORIZATION, accessToken); + CommonHolder.set(BootCommonConstant.AUTH, loginUser); + + // 校验忽略掩码 + checkIgnoreMask(); + filterChain.doFilter(request, response); + } + + /** + * 校验忽略掩码 + */ + private void checkIgnoreMask() { + if (AuthUtils.isIgnoreMask()) { + // 忽略脱敏 + MaskIgnoreUtils.ignore(); + } + } + + /** + * 检测权限白名单 + * + * @param uri 访问 uri + * @return 是否是白名单 + */ + private boolean checkAuthWhiteList(String uri) { + return PathPatternUtils.match(AUTH_WHITE_LIST, uri); + } + + /** + * 检测登录白名单 + * + * @param uri 请求 uri + * @return 是否是白名单 + */ + private boolean checkLoginWhiteList(String uri) { + return PathPatternUtils.match(LOGIN_WHITE_LIST, uri); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/holder/AuthHolder.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/holder/AuthHolder.java new file mode 100644 index 0000000..7bb4116 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/holder/AuthHolder.java @@ -0,0 +1,45 @@ +//package xtools.app.sys.auth.holder; +// +//import xtools.app.sys.auth.model.dto.LoginUserDto; +//import xtools.boot.api.exection.UnauthorizedError; +// +/// ** +// *

Title : LoginUserHolder

+// *

Description : LoginUserHolder

+// *

DevelopTools : Idea_x64_v2026.1

+// *

DevelopSystem : macOS Sequoia 15.7.5

+// *

Company : org.xujun

+// * +// * @author : XuJun +// * @version : 1.0.0 +// * @date : 2026/1/31 21:20 +// */ +//public class AuthHolder { +// +// /** +// * 登录用户信息 +// */ +// private static final ScopedValue LOGIN_USER_INFO = ScopedValue.newInstance(); +// +// /** +// * 获取登录用户信息 Holder +// * +// * @return 登录用户信息 +// */ +// public static ScopedValue getScoped() { +// return LOGIN_USER_INFO; +// } +// +// /** +// * 获取登录用户信息 +// * +// * @return 登录用户信息 +// */ +// public static LoginUserDto get() { +// if (!LOGIN_USER_INFO.isBound()) { +// throw new UnauthorizedError(); +// } +// return LOGIN_USER_INFO.get(); +// } +// +//} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/InterfacePermDto.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/InterfacePermDto.java new file mode 100644 index 0000000..2da0449 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/InterfacePermDto.java @@ -0,0 +1,36 @@ +package xtools.app.sys.auth.model.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : InterfacePermDto

+ *

Description : InterfacePermDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 15:58 + */ +@Data +public class InterfacePermDto implements Serializable { + + /** + * 接口地址 + */ + private String uri; + + /** + * 接口类型 + */ + private String type; + + /** + * 角色 ID 集合 + */ + private List roleIds; +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/LoginUserDto.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/LoginUserDto.java new file mode 100644 index 0000000..729e1da --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/LoginUserDto.java @@ -0,0 +1,51 @@ +package xtools.app.sys.auth.model.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : LoginUserDto

+ *

Description : LoginUserDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 20:40 + */ +@Data +public class LoginUserDto implements Serializable { + + /** + * 用户 ID + */ + private Long id; + + /** + * 账号 + */ + private String account; + + /** + * 昵称 + */ + private String nickname; + + /** + * 部门 ID + */ + private Long deptId; + + /** + * 角色 ID 集合 + */ + private List roleIds; + + /** + * 忽略脱敏时间 + */ + private Long ignoreMaskTime; +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/TokenDto.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/TokenDto.java new file mode 100644 index 0000000..2af87d8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/model/dto/TokenDto.java @@ -0,0 +1,39 @@ +package xtools.app.sys.auth.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +/** + *

Title : TokenDto

+ *

Description : TokenDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 14:43 + */ +@Data +public class TokenDto implements Serializable { + + /** + * 数据 Token + */ + @Schema(description = "数据 Token", example = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbi") + private String accessToken; + + /** + * 刷新 Token + */ + @Schema(description = "刷新 Token", example = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbi") + private String refreshToken; + + /** + * 数据 Token过期时间 + */ + @Schema(description = "数据 Token过期时间", example = "1675000000000") + private Long expiryTime; +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/AuthUtils.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/AuthUtils.java new file mode 100644 index 0000000..96b02cd --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/AuthUtils.java @@ -0,0 +1,327 @@ +package xtools.app.sys.auth.utils; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import jakarta.servlet.http.HttpServletRequest; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.model.dto.TokenDto; +import xtools.base.config.BaseParams; +import xtools.boot.api.constant.BootCommonConstant; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.UnauthorizedError; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.boot.core.holder.CommonHolder; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.UuidUtils; +import xtools.core.extend.CheckUtils; +import xtools.web.HeaderUtils; + +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + *

Title : AuthUtils

+ *

Description : AuthUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 20:44 + */ +public class AuthUtils implements BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.AUTH_SYS_USER; + + /** + * accessTokenKey + */ + private static final String ACCESS_TOKEN_KEY = "Authorization"; + + /** + * accessToken + */ + private static final String ACCESS_TOKEN = "accessToken"; + + /** + * refreshToken + */ + private static final String REFRESH_TOKEN = "refreshToken"; + + /** + * user + */ + private static final String USER = "id"; + + /** + * mask + */ + private static final String MASK = "mask"; + + /** + * 缓存 KeyMap + */ + private static final Map CACHE_KEY; + + // 初始化 + static { + String key = CACHE_PARAM.key(); + CACHE_KEY = new ConcurrentHashMap<>(CP_NUM16); + CACHE_KEY.put(ACCESS_TOKEN, key + ACCESS_TOKEN + CP_COLON); + CACHE_KEY.put(REFRESH_TOKEN, key + REFRESH_TOKEN + CP_COLON); + CACHE_KEY.put(USER, key + USER + CP_COLON); + CACHE_KEY.put(MASK, key + MASK + CP_COLON); + } + + /** + * 获取 AccessTokenKey + * + * @return key + */ + public static String getAccessTokenKey() { + return ACCESS_TOKEN_KEY; + } + + /** + * 获取 AccessToken + * + * @param request HttpServletRequest + * @return AccessToken + */ + public static String getAccessToken(HttpServletRequest request) { + return HeaderUtils.getRequestParam(request, getAccessTokenKey()); + } + + /** + * 获取 Uid + * + * @param request HttpServletRequest + * @return Uid + */ + public static String getUid(HttpServletRequest request) { + return HeaderUtils.getRequestParam(request, BootCommonConstant.UID); + } + + /** + * 创建 Token + * + * @param loginUser 登录用户信息 + * @return Token 信息 + */ + public static TokenDto createToken(LoginUserDto loginUser) { + Long userId = loginUser.getId(); + remove(userId); + + String accessToken = UuidUtils.get(); + String refreshToken = UuidUtils.get(); + + Long accessTokenExpiryTime = CACHE_PARAM.expireTime(); + Long refreshTokenExpiryTime = accessTokenExpiryTime + CACHE_PARAM.expireTime(); + Long userExpiryTime = System.currentTimeMillis() + accessTokenExpiryTime * 1000; + + RedisService redis = RedisUtils.get(); + // 保存 accessToken信息 + redis.set(getCacheKey(ACCESS_TOKEN, accessToken), + JSONObject.of("expiryTime", userExpiryTime, "loginUser", loginUser), refreshTokenExpiryTime); + // 保存 refreshToken信息 + redis.set(getCacheKey(REFRESH_TOKEN, refreshToken), accessToken, refreshTokenExpiryTime); + // 保存用户 Token 信息 + redis.set(getCacheKey(USER, userId), + JSONObject.of(ACCESS_TOKEN, accessToken, REFRESH_TOKEN, refreshToken), refreshTokenExpiryTime); + + // 构建 Token 信息 + TokenDto token = new TokenDto(); + token.setAccessToken(accessToken); + token.setRefreshToken(refreshToken); + token.setExpiryTime(userExpiryTime); + return token; + } + + /** + * 获取 LoginUser + * + * @return LoginUser + */ + public static LoginUserDto get() { + Map map = CommonHolder.get(); + if (CollectionUtils.isEmpty(map)) { + throw new UnauthorizedError(); + } + if (map.get(BootCommonConstant.AUTH) instanceof LoginUserDto loginUserDto) { + return loginUserDto; + } + if (map.get(BootCommonConstant.AUTHORIZATION) instanceof String accessToken) { + return get(accessToken); + } + throw new UnauthorizedError(); + } + + /** + * 获取 LoginUser + * + * @param id 用户 ID + * @return LoginUser + */ + public static LoginUserDto get(Long id) { + RedisService redis = RedisUtils.get(); + JSONObject userCache = redis.get(getCacheKey(USER, id), JSONObject.class); + if (CollectionUtils.isEmpty(userCache)) { + return null; + } + String accessToken = userCache.getString(ACCESS_TOKEN); + return get(accessToken); + } + + /** + * 从缓存获取 LoginUser + * + * @param accessToken AccessToken + * @return LoginUser + */ + public static LoginUserDto get(String accessToken) { + if (StringUtils.isBlank(accessToken)) { + return null; + } + return getFromCache(accessToken, true); + } + + /** + * 移除缓存中登录用户信息 + * + * @param idList 用户 ID 集合 + */ + public static void remove(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return; + } + for (Long id : idList) { + remove(id); + } + } + + /** + * 移除缓存中登录用户信息 + * + * @param id 用户 ID + */ + public static void remove(Long id) { + RedisService redis = RedisUtils.get(); + JSONObject userCache = redis.get(getCacheKey(USER, id), JSONObject.class); + if (CollectionUtils.isEmpty(userCache)) { + return; + } + String accessToken = userCache.getString(ACCESS_TOKEN); + String refreshToken = userCache.getString(REFRESH_TOKEN); + redis.del(getCacheKey(ACCESS_TOKEN, accessToken)); + redis.del(getCacheKey(REFRESH_TOKEN, refreshToken)); + redis.del(getCacheKey(USER, id)); + } + + /** + * 刷新 Token + * + * @param refreshToken RefreshToken + * @return Token + */ + public static TokenDto refreshToken(String refreshToken) { + if (StringUtils.isBlank(refreshToken)) { + throw new BizError("refreshToken 不能为空"); + } + RedisService redis = RedisUtils.get(); + String accessToken = redis.get(getCacheKey(REFRESH_TOKEN, refreshToken), String.class); + if (StringUtils.isBlank(accessToken)) { + throw new BizError("token已过期,请重新登录"); + } + LoginUserDto loginUser = getFromCache(accessToken, false); + if (loginUser == null) { + throw new BizError("token已过期,请重新登录"); + } + return createToken(loginUser); + } + + /** + * 获取是否忽略脱敏 + * + * @return 是否忽略脱敏 + */ + public static boolean isIgnoreMask() { + LoginUserDto loginUser = get(); + if (Objects.isNull(loginUser)) { + throw new BizError("请先登录"); + } + RedisService redis = RedisUtils.get(); + Long time = redis.get(getCacheKey(MASK, loginUser.getId()), Long.class); + return CheckUtils.id(time); + } + + /** + * 设置忽略脱敏 + */ + public static void setIgnoreMask() { + LoginUserDto loginUser = get(); + if (Objects.isNull(loginUser)) { + throw new BizError("请先登录"); + } + RedisService redis = RedisUtils.get(); + redis.set(getCacheKey(MASK, loginUser.getId()), Instant.now().toEpochMilli(), CACHE_PARAM.expireTime()); + } + + /** + * 移除忽略脱敏 + */ + public static void removeIgnoreMask() { + LoginUserDto loginUser = get(); + if (Objects.isNull(loginUser)) { + throw new BizError("请先登录"); + } + RedisService redis = RedisUtils.get(); + redis.del(getCacheKey(MASK, loginUser.getId())); + } + + /** + * 从缓存获取 LoginUser + * + * @param accessToken AccessToken + * @param checkTime 是否检验有效期 + * @return LoginUser + */ + private static LoginUserDto getFromCache(String accessToken, boolean checkTime) { + JSONObject data = RedisUtils.get().get(getCacheKey(ACCESS_TOKEN, accessToken), JSONObject.class); + if (CollectionUtils.isEmpty(data)) { + return null; + } + if (checkTime) { + Long expiryTime = data.getLong("expiryTime"); + if (expiryTime < System.currentTimeMillis()) { + return null; + } + } + return JSON.to(LoginUserDto.class, data.getJSONObject("loginUser")); + } + + /** + * 获取缓存 key + * + * @param keyType key 类型 + * @param key Key + * @return 缓存 key + */ + private static String getCacheKey(String keyType, Object key) { + String keyPrefix = CACHE_KEY.get(keyType); + if (StringUtils.isBlank(keyPrefix)) { + throw new BizError("keyType 错误"); + } + return keyPrefix + key; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/PremUtils.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/PremUtils.java new file mode 100644 index 0000000..82be357 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/utils/PremUtils.java @@ -0,0 +1,125 @@ +package xtools.app.sys.auth.utils; + +import com.alibaba.fastjson2.JSON; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.auth.model.dto.InterfacePermDto; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

Title : PremUtils

+ *

Description : PremUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 18:31 + */ +public class PremUtils implements BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.AUTH_SYS_URI; + + /** + * 接口权限类型映射 + */ + private static final Map PERM_TYPE_MAP; + + // 初始化 + static { + PERM_TYPE_MAP = new HashMap<>(CP_NUM7); + PERM_TYPE_MAP.put("1", "GET"); + PERM_TYPE_MAP.put("2", "POST"); + PERM_TYPE_MAP.put("3", "PUT"); + PERM_TYPE_MAP.put("4", "DELETE"); + PERM_TYPE_MAP.put("5", "PATCH"); + PERM_TYPE_MAP.put("6", "HEAD"); + PERM_TYPE_MAP.put("7", "OPTIONS"); + } + + /** + * 获取接口权限类型 + * + * @param type 接口权限类型 + * @return 接口权限类型 + */ + public static String getPermType(String type) { + return PERM_TYPE_MAP.get(type); + } + + /** + * 获取接口权限缓存 key + * + * @return 缓存 key + */ + public static String getCacheKey() { + return CACHE_PARAM.key(); + } + + /** + * 获取模块名称 + * + * @param uri 请求 uri + * @return 模块名称 + */ + public static String getModuleName(String uri) { + String[] split = uri.split(CP_SLASH); + int length = split.length; + if (length <= CP_NUM1) { + return CP_EMPTY; + } else if (length == CP_NUM2) { + return split[CP_NUM1]; + } else { + return split[CP_NUM1] + CP_LINE + split[CP_NUM2]; + } + } + + /** + * 检查接口权限 + * + * @param uri 请求 uri + * @param type 接口权限类型 + * @param roleIds 角色 ID 集合 + * @return 是否有权限 + */ + public static boolean checkInterfacePerm(String uri, String type, List roleIds) { + String moduleName = getModuleName(uri); + if (StringUtils.isBlank(moduleName)) { + return false; + } + String cacheKey = moduleName + CP_COLON + type; + RedisService redis = RedisUtils.get(); + List list = redis.hashGet(getCacheKey(), cacheKey, List.class); + if (CollectionUtils.isEmpty(list)) { + return false; + } + PathMatcher pm = new AntPathMatcher(); + for (Object obj : list) { + InterfacePermDto item = JSON.to(InterfacePermDto.class, obj); + String permUri = item.getUri(); + if (!pm.match(permUri, uri)) { + continue; + } + List permRoleIds = item.getRoleIds(); + if (CollectionUtils.isEmpty(permRoleIds)) { + return false; + } + return roleIds.stream().anyMatch(permRoleIds::contains); + } + return false; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/whitelist/AuthWhitelist.java b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/whitelist/AuthWhitelist.java new file mode 100644 index 0000000..f3ed21f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-auth/src/main/java/xtools/app/sys/auth/whitelist/AuthWhitelist.java @@ -0,0 +1,36 @@ +package xtools.app.sys.auth.whitelist; + +import java.util.Set; + +/** + *

Title : AuthWhitelist

+ *

Description : AuthWhitelist

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/2 11:38 + */ +public interface AuthWhitelist { + + /** + * 添加权限白名单 + * + * @return 权限白名单 + */ + default Set addAuth() { + return Set.of(); + } + + /** + * 添加登录白名单 + * + * @return 登录白名单 + */ + default Set addLogin() { + return Set.of(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/pom.xml b/xtools-app-sys/xtools-app-sys-biz/pom.xml new file mode 100644 index 0000000..ad66818 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/pom.xml @@ -0,0 +1,186 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-biz + + + + + + dev + + true + + + + + org.xujun + xtools-boot-knife4j + + + + + + prod + + + + + + + + + + org.bouncycastle + bcprov-jdk18on + + + + com.github.oshi + oshi-core + + + + org.apache.fesod + fesod-sheet + + + org.xujun + xtools-extend + + + + + org.xujun + xtools-api + + + + org.xujun + xtools-boot-core + + + + org.xujun + xtools-boot-db-mybatis + + + + org.xujun + xtools-boot-db-mybatis-plus + + + + org.xujun + xtools-boot-elasticsearch + + + + org.xujun + xtools-boot-ip + + + + org.xujun + xtools-boot-mask + + + + org.xujun + xtools-boot-web-base + + + + org.xujun + xtools-boot-web-filter + + + + + + org.xujun + xtools-app-common-cache + + + org.xujun + xtools-app-common-jar + + + org.xujun + xtools-app-common-job + + + org.xujun + xtools-app-common-log-bus + + + org.xujun + xtools-app-common-log-filter + + + org.xujun + xtools-app-common-mq + + + org.xujun + xtools-app-common-task + + + + org.xujun + xtools-app-sys-api + + + org.xujun + xtools-app-sys-auth + + + org.xujun + xtools-app-sys-file + + + org.xujun + xtools-app-sys-file-web + + + org.xujun + xtools-app-sys-param + + + org.xujun + xtools-app-sys-risk + + + + + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-processor + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + com.github.whvcse + easy-captcha + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/ApiConfig.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/ApiConfig.java new file mode 100644 index 0000000..e1b2e8b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/ApiConfig.java @@ -0,0 +1,42 @@ +package xtools.app.sys.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + *

Title : ApiConfig

+ *

Description : ApiConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/16 11:01 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "api") +public class ApiConfig { + + /** + * 百度 + */ + private Baidu baidu; + + /** + *

Title : Baidu

+ *

Description : 百度

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026-02-16 11:01:05 + */ + @Data + public static class Baidu { + // 百度地图ak + private String ak; + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysAuthWhitelist.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysAuthWhitelist.java new file mode 100644 index 0000000..9eeb12c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysAuthWhitelist.java @@ -0,0 +1,47 @@ +package xtools.app.sys.config; + +import org.springframework.stereotype.Component; +import xtools.app.sys.auth.whitelist.AuthWhitelist; + +import java.util.Set; + +/** + *

Title : SysAuthWhitelist

+ *

Description : SysAuthWhitelist

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/2 14:13 + */ +@Component +public class SysAuthWhitelist implements AuthWhitelist { + + /** + * 添加权限白名单 + * + * @return 权限白名单 + */ + @Override + public Set addAuth() { + return Set.of( + "/sys/common/get/*/file" + ); + } + + /** + * 添加登录白名单 + * + * @return 登录白名单 + */ + @Override + public Set addLogin() { + return Set.of( + "/sys/common/**", + "/sys/login/**" + ); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysConfig.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysConfig.java new file mode 100644 index 0000000..fa4bc87 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysConfig.java @@ -0,0 +1,62 @@ +package xtools.app.sys.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + *

Title : SysConfig

+ *

Description : SysConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 10:19 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "sys") +public class SysConfig { + + /** + * 用户 + */ + private User user; + + /** + * 日志 + */ + private Log log; + + /** + * 用户 + */ + @Data + public static class User { + + /** + * 密码 + */ + private String passwd = "xtools"; + } + + /** + * 日志 + */ + @Data + public static class Log { + + /** + * 存储类型(elasticsearch|mysql) + */ + private String type = "mysql"; + + /** + * 最大保存天数 + */ + private int maxDays = 2; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysHttpLogWhitelist.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysHttpLogWhitelist.java new file mode 100644 index 0000000..f336a79 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysHttpLogWhitelist.java @@ -0,0 +1,34 @@ +package xtools.app.sys.config; + +import org.springframework.stereotype.Component; +import xtools.app.common.log.whitelist.HttpLogWhitelist; + +import java.util.Set; + +/** + *

Title : SysHttpLogWhitelist

+ *

Description : SysHttpLogWhitelist

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/2 14:50 + */ +@Component +public class SysHttpLogWhitelist implements HttpLogWhitelist { + + /** + * 添加白名单 + * + * @return 白名单 + */ + @Override + public Set ignoreResp() { + return Set.of( + "/sys/common/get/*/file" + ); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysLogMySqlConfig.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysLogMySqlConfig.java new file mode 100644 index 0000000..f935631 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/config/SysLogMySqlConfig.java @@ -0,0 +1,43 @@ +package xtools.app.sys.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import xtools.app.sys.service.SysLogService; +import xtools.app.sys.service.impl.SysLogServiceImpl; + +/** + *

Title : SysLogMySqlConfig

+ *

Description : SysLogMySqlConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 10:29 + */ +@Slf4j +@Configuration +public class SysLogMySqlConfig { + + /** + * 日志类型mysql + */ + private static final String TYPE_MYSQL = "mysql"; + + + /** + * 获取数据库日志服务 + * + * @return 日志服务 + */ + @Bean + @ConditionalOnProperty(prefix = "sys.log", name = "type", havingValue = TYPE_MYSQL) + public SysLogService getDbSysLogService() { + log.info("系统日志存储类型:{}", TYPE_MYSQL); + return new SysLogServiceImpl(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysAddressController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysAddressController.java new file mode 100644 index 0000000..34691e0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysAddressController.java @@ -0,0 +1,45 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotEmpty; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.api.SysAddressApi; +import xtools.app.sys.model.dto.resp.SysAddressResp; +import xtools.app.sys.service.SysAddressService; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysAddressController

+ *

Description : 公用地址表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:40 + */ +@RequiredArgsConstructor +@Tag(name = "公用地址表") +@RestController +@RequestMapping("/sys/address") +public class SysAddressController implements SysAddressApi { + + private final SysAddressService sysAddressService; + + @Override + @Operation(summary = "根据code获取地址信息") + @GetMapping("/get-by-code/{code}") + public Result getByCode( + @Schema(description = "地址编码", example = "1") + @NotEmpty(message = "不能为空") + @PathVariable String code + ) { + return sysAddressService.getByCode(code); + } +} + diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysBaseController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysBaseController.java new file mode 100644 index 0000000..dc8268b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysBaseController.java @@ -0,0 +1,130 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.model.dto.req.IgnoreMaskReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.req.UserInfoPasswdEditReq; +import xtools.app.sys.model.dto.resp.SysBaseUserInfoResp; +import xtools.app.sys.model.dto.resp.SysIpAddrResp; +import xtools.app.sys.model.dto.resp.SysUpdateHistoryResp; +import xtools.app.sys.service.SysBaseService; +import xtools.app.sys.service.SysUpdateHistoryService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.mask.utils.MaskIgnoreUtils; +import xtools.core.StringUtils; + +import java.util.List; + +/** + *

Title : SysBaseController

+ *

Description : SysBaseController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Slf4j +@Tag(name = "系统基本信息") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/base") +public class SysBaseController { + + private final SysUpdateHistoryService sysUpdateHistoryService; + + private final SysBaseService sysBaseService; + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @Operation(summary = "获取用户信息") + @GetMapping("/get-user-info") + public Result getUserInfo() { + // 忽略脱敏 + MaskIgnoreUtils.ignore(); + return sysBaseService.getUserInfo(); + } + + @Operation(summary = "修改用户信息") + @PostMapping("/edit-user-info") + public Result saveUserInfo(@RequestBody @Valid UserInfoEditReq req) { + return sysBaseService.editUserInfo(req); + } + + @Operation(summary = "修改密码") + @PostMapping("/edit-passwd") + public Result editPasswd(HttpServletRequest request, @RequestBody @Valid UserInfoPasswdEditReq req) { + String uid = AuthUtils.getUid(request); + if (StringUtils.isBlank(uid)) { + return Result.badRequest(); + } + req.setUid(uid); + return sysBaseService.editPasswd(req); + } + + @Operation(summary = "是否忽略脱敏") + @GetMapping("/is-ignore-mask") + public Result isIgnoreMask() { + return Result.ok(AuthUtils.isIgnoreMask()); + } + + @Operation(summary = "忽略脱敏") + @PostMapping("/ignore-mask") + public Result ignoreMask(HttpServletRequest request, @RequestBody @Valid IgnoreMaskReq req) { + String uid = AuthUtils.getUid(request); + if (StringUtils.isBlank(uid)) { + return Result.badRequest(); + } + req.setUid(uid); + return sysBaseService.ignoreMask(req); + } + + @Operation(summary = "取消忽略脱敏") + @GetMapping("/unignore-mask") + public Result unIgnoreMask(HttpServletRequest request) { + return sysBaseService.unIgnoreMask(); + } + + @Operation(summary = "退出登录") + @GetMapping("/logout") + public Result logout(HttpServletRequest request) { + LoginUserDto loginUser = AuthUtils.get(); + AuthUtils.remove(loginUser.getId()); + return Result.ok(true); + } + + @Operation(summary = "获取更新历史") + @GetMapping("/get-update-history") + public Result> getUpdateHistory() { + return sysUpdateHistoryService.getAll(0); + } + + @Operation(summary = "查询ip对应的地址") + @GetMapping("/get-ip-address/{ip}") + public Result getIpAddress( + @NotEmpty(message = "不能为空") + @PathVariable String ip + ) { + return sysBaseService.getIpAddress(ip); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysCommonController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysCommonController.java new file mode 100644 index 0000000..d3b47e2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysCommonController.java @@ -0,0 +1,45 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.service.SysCommonService; +import xtools.boot.api.model.dto.Result; +import xtools.core.StringUtils; + +/** + *

Title : SysCommonController

+ *

Description : SysCommonController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Slf4j +@Tag(name = "系统通用") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/common") +public class SysCommonController { + + private final SysCommonService sysCommonService; + + @Operation(summary = "获取SM2公钥") + @RequestMapping("/get-sm2-public-key") + public Result getSm2PublicKey(HttpServletRequest request) { + String uid = AuthUtils.getUid(request); + if (StringUtils.isBlank(uid)) { + return Result.badRequest(); + } + return Result.ok(sysCommonService.getSm2Key(uid).getPublicKey()); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDeptController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDeptController.java new file mode 100644 index 0000000..0a19df0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDeptController.java @@ -0,0 +1,96 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysDeptAddReq; +import xtools.app.sys.model.dto.req.SysDeptPageReq; +import xtools.app.sys.model.dto.req.SysDeptUpdateReq; +import xtools.app.sys.model.dto.resp.SysDeptResp; +import xtools.app.sys.model.dto.resp.SysDeptTreeResp; +import xtools.app.sys.service.SysDeptService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.api.model.dto.resp.TreeResp; + +import java.util.List; + +/** + *

Title : SysDeptController

+ *

Description : 部门管理表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Tag(name = "部门管理表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/dept") +public class SysDeptController { + + private final SysDeptService sysDeptService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysDeptService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysDeptService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysDeptAddReq req) { + return sysDeptService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysDeptUpdateReq req) { + return sysDeptService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysDeptService.delById(req.getIdList()); + } + + @Operation(summary = "获取表格部门树") + @PostMapping("tree-table") + public Result> treeTable(@RequestBody @Valid SysDeptPageReq req) { + return sysDeptService.treeTable(req); + } + + @Operation(summary = "获取部门树") + @GetMapping("trees") + public Result> trees() { + return sysDeptService.trees(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictController.java new file mode 100644 index 0000000..0000b04 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictController.java @@ -0,0 +1,123 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.model.dto.excel.SysDictExcel; +import xtools.app.sys.model.dto.req.SysDictAddReq; +import xtools.app.sys.model.dto.req.SysDictPageReq; +import xtools.app.sys.model.dto.req.SysDictUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictResp; +import xtools.app.sys.service.SysDictService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.CollectionUtils; +import xtools.extend.office.FesodUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.List; + +/** + *

Title : SysDictController

+ *

Description : 数据字典类型表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Tag(name = "数据字典类型表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/dict") +public class SysDictController { + + private final SysDictService sysDictService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysDictService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysDictService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysDictAddReq req) { + return sysDictService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysDictUpdateReq req) { + return sysDictService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysDictService.delById(req.getIdList()); + } + + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid SysDictPageReq req, HttpServletResponse response) { + String sheetName = "数据字典类型表"; + String filename = sheetName + ".xlsx"; + List dataList = sysDictService.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), SysDictExcel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), SysDictExcel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + sysDictService.importExcel(dataList); + return Result.ok(true); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictItemController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictItemController.java new file mode 100644 index 0000000..e5d4935 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysDictItemController.java @@ -0,0 +1,136 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.api.SysDictItemApi; +import xtools.app.sys.model.dto.excel.SysDictItemExcel; +import xtools.app.sys.model.dto.req.SysDictItemAddReq; +import xtools.app.sys.model.dto.req.SysDictItemPageReq; +import xtools.app.sys.model.dto.req.SysDictItemUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.app.sys.service.SysDictItemService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.CollectionUtils; +import xtools.extend.office.FesodUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.List; + +/** + *

Title : SysDictItemController

+ *

Description : 数据字典项表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Tag(name = "数据字典项表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/dict-item") +public class SysDictItemController implements SysDictItemApi { + + private final SysDictItemService sysDictItemService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysDictItemService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysDictItemService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysDictItemAddReq req) { + return sysDictItemService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysDictItemUpdateReq req) { + return sysDictItemService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysDictItemService.delById(req.getIdList()); + } + + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid SysDictItemPageReq req, HttpServletResponse response) { + String sheetName = "数据字典类型"; + String filename = sheetName + ".xlsx"; + List dataList = sysDictItemService.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), SysDictItemExcel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), SysDictItemExcel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + sysDictItemService.importExcel(dataList); + return Result.ok(true); + } + + @Override + @Operation(summary = "获取字典项") + @GetMapping("get-by-code/{dictCode}") + public Result> getByCode( + @Schema(description = "字典编码", example = "1") + @NotEmpty(message = "不能为空") + @PathVariable String dictCode + ) { + return sysDictItemService.getByCode(dictCode); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysFileController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysFileController.java new file mode 100644 index 0000000..86d2809 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysFileController.java @@ -0,0 +1,116 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.api.SysFileApi; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileChangeReq; +import xtools.app.sys.model.dto.req.SysFilePageReq; +import xtools.app.sys.model.dto.req.SysFileUpdateReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.app.sys.service.SysFileService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysFileController

+ *

Description : 系统文件表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@RequiredArgsConstructor +@Tag(name = "系统文件表") +@RestController +@RequestMapping("/sys/file") +public class SysFileController implements SysFileApi { + + private final SysFileService sysFileService; + + @Operation(summary = "分页请求SYS_FILE_PERMISSION") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysFileService.page(pageReq); + } + + @Override + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysFileService.getById(id); + } + + /** + * 根据文件名查询 + * + * @param bucket 桶名称 + * @param fileName 文件名 + * @return 结果 + */ + @Override + @GetMapping("base/get-by-name") + @Operation(summary = "根据路径查询") + public Result getByName( + @Schema(description = "桶名称") + @NotBlank(message = "不能为空") + @RequestParam String bucket, + @Schema(description = "文件路径") + @NotBlank(message = "不能为空") + @RequestParam String fileName + ) { + return sysFileService.getByName(bucket, fileName); + } + + @Override + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysFileAddReq req) { + return sysFileService.add(req); + } + + @Override + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysFileUpdateReq req) { + return sysFileService.update(req); + } + + @Override + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysFileService.delById(req); + } + + @Override + @Operation(summary = "删除数据") + @PostMapping("change-data-type-by-ids") + public Result changeDataTypeByIds(@RequestBody @Valid SysFileChangeReq req) { + return sysFileService.changeDataTypeByIds(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysHomeController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysHomeController.java new file mode 100644 index 0000000..733be41 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysHomeController.java @@ -0,0 +1,58 @@ +package xtools.app.sys.controller; + +import com.alibaba.fastjson2.JSONObject; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.resp.SysHomeDataResp; +import xtools.app.sys.service.SysHomeService; +import xtools.boot.api.model.dto.Result; +import xtools.extend.SysInfoUtils; +import xtools.web.HeaderUtils; + +/** + *

Title : SysHomeController

+ *

Description : SysHomeController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Tag(name = "系统Home信息") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/home") +public class SysHomeController { + + private final SysHomeService sysHomeService; + + /** + * 获取运行时 + * + * @return 运行时 + */ + @Operation(summary = "运行时") + @GetMapping("/runtime") + public Result runtime() { + return Result.ok(SysInfoUtils.get(true)); + } + + /** + * 获取首页数据 + * + * @return 首页数据 + */ + @Operation(summary = "首页数据") + @GetMapping("/get-data") + public Result getData(HttpServletRequest request) { + String ip = HeaderUtils.getIp(request); + return sysHomeService.getData(ip); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysJarController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysJarController.java new file mode 100644 index 0000000..de98678 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysJarController.java @@ -0,0 +1,36 @@ +package xtools.app.sys.controller; + +import com.alibaba.fastjson2.JSONObject; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.common.jar.utils.RunJarUtils; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysJarController

+ *

Description : SysJarController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Tag(name = "系统Jar包") +@RestController +@RequestMapping("/sys/jar") +public class SysJarController { + + @Operation(summary = "获取所有jar包") + @RequestMapping("/get-all") + public Result> getAll(HttpServletRequest request) { + return Result.ok(RunJarUtils.get()); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLogController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLogController.java new file mode 100644 index 0000000..1d0eadd --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLogController.java @@ -0,0 +1,67 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysLogPageReq; +import xtools.app.sys.model.dto.resp.SysLogResp; +import xtools.app.sys.service.SysLogService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysLogController

+ *

Description : 日志记录表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Tag(name = "日志记录表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/log") +public class SysLogController { + + private final SysLogService sysLogService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysLogService.page(pageReq); + } + + @Operation(summary = "根据日志 ID 查询") + @GetMapping("get-by-log-id/{logId}") + public Result getByLogId( + @Schema(description = "日志 ID", example = "xxx") + @NotEmpty(message = "不能为空") + @PathVariable String logId + ) { + return sysLogService.getByLogId(logId); + } + + @Operation(summary = "根据traceId查询") + @GetMapping("get-by-trace-id/{traceId}") + public Result> getByTraceId( + @Schema(description = "traceId", example = "xxx") + @NotEmpty(message = "不能为空") + @PathVariable String traceId + ) { + return sysLogService.getByTraceId(traceId); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLoginController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLoginController.java new file mode 100644 index 0000000..76de5c9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysLoginController.java @@ -0,0 +1,70 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.auth.model.dto.TokenDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.model.dto.req.SysLoginReq; +import xtools.app.sys.service.SysLoginService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.base.RedisService; + +/** + *

Title : SysLoginController

+ *

Description : SysLoginController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Tag(name = "系统登录") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/login") +public class SysLoginController { + + private final SysLoginService sysLoginService; + @Resource + private RedisService redisService; + + @Operation(summary = "获取验证码") + @GetMapping("captcha/*") + public Result captcha(HttpServletRequest request) { + String uid = AuthUtils.getUid(request); + return sysLoginService.captcha(uid); + } + + @Operation(summary = "密码登录") + @PostMapping("passwd") + public Result passwd(HttpServletRequest request, @RequestBody @Valid SysLoginReq req) { + String uid = AuthUtils.getUid(request); + req.setUid(uid); + return sysLoginService.passwd(req); + } + + @Operation(summary = "刷新令牌") + @GetMapping("refresh/{refreshToken}") + public Result refresh( + @Schema(description = "刷新令牌", example = "refreshToken") + @NotNull(message = "不能为空") + @PathVariable String refreshToken + ) { + return Result.ok(AuthUtils.refreshToken(refreshToken)); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMenuController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMenuController.java new file mode 100644 index 0000000..346a746 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMenuController.java @@ -0,0 +1,97 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysMenuAddReq; +import xtools.app.sys.model.dto.req.SysMenuPageReq; +import xtools.app.sys.model.dto.req.SysMenuTreesReq; +import xtools.app.sys.model.dto.req.SysMenuUpdateReq; +import xtools.app.sys.model.dto.resp.SysMenuResp; +import xtools.app.sys.model.dto.resp.SysMenuTreeResp; +import xtools.app.sys.service.SysMenuService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.api.model.dto.resp.TreeResp; + +import java.util.List; + +/** + *

Title : SysMenuController

+ *

Description : 系统菜单表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Tag(name = "系统菜单表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/menu") +public class SysMenuController { + + private final SysMenuService sysMenuService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysMenuService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysMenuService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysMenuAddReq req) { + return sysMenuService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysMenuUpdateReq req) { + return sysMenuService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysMenuService.delById(req.getIdList()); + } + + @Operation(summary = "获取表格菜单树") + @PostMapping("tree-table") + public Result> treeTable(@RequestBody @Valid SysMenuPageReq req) { + return sysMenuService.treeTable(req); + } + + @Operation(summary = "获取菜单树") + @PostMapping("trees") + public Result> trees(@RequestBody @Valid SysMenuTreesReq req) { + return sysMenuService.trees(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMonitorController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMonitorController.java new file mode 100644 index 0000000..e4927f6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysMonitorController.java @@ -0,0 +1,92 @@ +package xtools.app.sys.controller; + +import com.alibaba.fastjson2.JSONObject; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.service.SysMonitorService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.EnumInfoDto; +import xtools.boot.api.model.dto.Result; +import xtools.boot.core.utils.EnumUtils; +import xtools.boot.db.mybatis.enums.MySqlMonitorEnums; +import xtools.boot.elasticsearch.enums.ElasticsearchMonitorEnums; + +import java.util.List; + +/** + *

Title : SysMonitorController

+ *

Description : SysMonitorController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 11:51 + */ +@Tag(name = "系统监控") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/monitor") +public class SysMonitorController { + + private final SysMonitorService sysMonitorService; + + @Operation(summary = "Redis监控") + @GetMapping("/redis") + public Result redis() { + return sysMonitorService.redis(); + } + + @Operation(summary = "获取MySql监控类型") + @GetMapping("/get-mysql-monitor-types") + public Result> getMySqlMonitorTypes() { + return Result.ok(EnumUtils.getEnumInfos(MySqlMonitorEnums.values())); + } + + @Operation(summary = "MySql监控") + @GetMapping("/mysql/{type}") + public Result> mysql( + @Min(value = 0, message = "不能小于0") + @NotNull(message = "不能为空") + @PathVariable Integer type + ) { + MySqlMonitorEnums mySqlMonitorEnums; + try { + mySqlMonitorEnums = MySqlMonitorEnums.valueOf(type); + } catch (Exception e) { + throw new BizError("type值错误"); + } + return sysMonitorService.mysql(mySqlMonitorEnums); + } + + @Operation(summary = "获取Elasticsearch监控类型") + @GetMapping("/get-elasticsearch-monitor-types") + public Result> getElasticsearchMonitorTypes() { + return Result.ok(EnumUtils.getEnumInfos(ElasticsearchMonitorEnums.values())); + } + + @Operation(summary = "Elasticsearch监控") + @GetMapping("/elasticsearch/{type}") + public Result elasticsearch( + @Min(value = 0, message = "不能小于0") + @NotNull(message = "不能为空") + @PathVariable Integer type + ) { + ElasticsearchMonitorEnums elasticsearchMonitorEnums; + try { + elasticsearchMonitorEnums = ElasticsearchMonitorEnums.valueOf(type); + } catch (Exception e) { + throw new BizError("type值错误"); + } + return sysMonitorService.elasticsearch(elasticsearchMonitorEnums); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysNoticeController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysNoticeController.java new file mode 100644 index 0000000..8e1ac3f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysNoticeController.java @@ -0,0 +1,141 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.file.enums.FileBizEnum; +import xtools.app.sys.file.service.SysFileOptService; +import xtools.app.sys.model.dto.req.SysNoticeAddReq; +import xtools.app.sys.model.dto.req.SysNoticePageReq; +import xtools.app.sys.model.dto.req.SysNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysNoticeResp; +import xtools.app.sys.service.SysNoticeService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.io.InputStream; + +/** + *

Title : SysNoticeController

+ *

Description : 系统通知公告表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Slf4j +@RequiredArgsConstructor +@Tag(name = "系统通知公告表") +@RestController +@RequestMapping("/sys/notice") +public class SysNoticeController { + + private final SysNoticeService sysNoticeService; + + private final SysFileOptService sysFileOptService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysNoticeService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysNoticeService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysNoticeAddReq req) { + return sysNoticeService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysNoticeUpdateReq req) { + return sysNoticeService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysNoticeService.delById(req); + } + + @Operation(summary = "上传图片") + @PostMapping("/upload-img") + public Result uploadImg( + @RequestParam("img") MultipartFile img + ) { + if (img.isEmpty()) { + throw new BizError("图片件不能为空"); + } + String filename = img.getOriginalFilename(); + if (StringUtils.isBlank(filename)) { + throw new BizError("图片件名称不能为空"); + } + FileBizEnum bizType = FileBizEnum.SYS_NOTICE; + if (!CheckUtils.suffix(filename, bizType.extArr())) { + throw new BizError("图片格式错误"); + } + try (InputStream inputStream = img.getInputStream()) { + LoginUserDto loginUser = AuthUtils.get(); + Long id = sysFileOptService.upload( + filename, + inputStream, + img.getSize(), + loginUser.getId(), + loginUser.getAccount(), + bizType, + null + ); + return Result.ok(id); + } catch (Exception e) { + log.error("上传失败", e); + throw new BizError("上传失败"); + } + } + + @Operation(summary = "发布") + @PostMapping("publish") + public Result publish(@RequestBody @Valid IdListReq req) { + return sysNoticeService.publish(req); + } + + @Operation(summary = "撤回") + @PostMapping("revoke") + public Result revoke(@RequestBody @Valid IdListReq req) { + return sysNoticeService.revoke(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysParamController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysParamController.java new file mode 100644 index 0000000..688077e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysParamController.java @@ -0,0 +1,126 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.api.SysParamApi; +import xtools.app.sys.model.dto.excel.SysParamExcel; +import xtools.app.sys.model.dto.req.SysParamAddReq; +import xtools.app.sys.model.dto.req.SysParamPageReq; +import xtools.app.sys.model.dto.req.SysParamUpdateReq; +import xtools.app.sys.model.dto.resp.SysParamResp; +import xtools.app.sys.service.SysParamService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.CollectionUtils; +import xtools.extend.office.FesodUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.List; + +/** + *

Title : SysParamController

+ *

Description : 系统参数表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@RequiredArgsConstructor +@Tag(name = "系统参数表") +@RestController +@RequestMapping("/sys/param") +public class SysParamController implements SysParamApi { + + private final SysParamService sysParamService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysParamService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysParamService.getById(id); + } + + @Override + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysParamAddReq req) { + return sysParamService.add(req); + } + + @Override + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysParamUpdateReq req) { + return sysParamService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysParamService.delById(req); + } + + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid SysParamPageReq req, HttpServletResponse response) { + String sheetName = "系统参数表"; + String filename = sheetName + ".xlsx"; + List dataList = sysParamService.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), SysParamExcel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), SysParamExcel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + sysParamService.importExcel(dataList); + return Result.ok(true); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRiskController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRiskController.java new file mode 100644 index 0000000..1df9340 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRiskController.java @@ -0,0 +1,229 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.api.SysRiskApi; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.model.dto.excel.SysRiskExcel; +import xtools.app.sys.model.dto.req.SysRiskAddReq; +import xtools.app.sys.model.dto.req.SysRiskPageReq; +import xtools.app.sys.model.dto.req.SysRiskUpdateReq; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.app.sys.service.SysRiskService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.CollectionUtils; +import xtools.extend.office.FesodUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.List; + +/** + *

Title : SysRiskController

+ *

Description : 系统风控表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@RequiredArgsConstructor +@Tag(name = "系统风控表") +@RestController +@RequestMapping("/sys/risk") +public class SysRiskController implements SysRiskApi { + + private final SysRiskService sysRiskService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysRiskService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysRiskService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysRiskAddReq req) { + return sysRiskService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysRiskUpdateReq req) { + return sysRiskService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysRiskService.delById(req); + } + + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid SysRiskPageReq req, HttpServletResponse response) { + String sheetName = "系统风控表"; + String filename = sheetName + ".xlsx"; + List dataList = sysRiskService.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), SysRiskExcel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), SysRiskExcel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + sysRiskService.importExcel(dataList); + return Result.ok(true); + } + + /** + * 根据风控类型获取数据 + * + * @param type 风控类型 + * @return 数据 + */ + @Override + @GetMapping("type") + @Operation(summary = "根据类型获取数据") + public Result> getByType( + @Schema(description = "风控类型") + @NotNull(message = "不能为空") + @RequestParam SysRiskType type + ) { + return sysRiskService.getByType(type); + } + + /** + * 添加IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + @Override + @PostMapping("add-ip") + @Operation(summary = "添加IP") + public Result addIp( + @Schema(description = "系统类型") + @NotBlank(message = "不能为空") + @RequestParam String sysType, + @Schema(description = "IP") + @NotBlank(message = "不能为空") + @RequestParam String ip + ) { + return sysRiskService.addIp(sysType, ip); + } + + /** + * 移除IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 移除结果 + */ + @Override + @PostMapping("remove-ip") + @Operation(summary = "移除IP") + public Result removeIp( + @Schema(description = "系统类型") + @NotBlank(message = "不能为空") + @RequestParam String sysType, + @Schema(description = "IP") + @NotBlank(message = "不能为空") + @RequestParam String ip + ) { + return sysRiskService.removeIp(sysType, ip); + } + + @Operation(summary = "获取IP风控数据") + @GetMapping("get-ip/{sysType}") + public Result> getIp( + @Schema(description = "系统类型") + @NotBlank(message = "不能为空") + @PathVariable String sysType + ) { + return sysRiskService.getIp(sysType); + } + + @Operation(summary = "保存IP风控数据") + @PostMapping("save-ip/{sysType}") + public Result saveIp( + @Schema(description = "黑名单") + @NotNull(message = "不能为空") + @PathVariable String sysType, + @Schema(description = "IP列表") + @RequestBody List ipList + ) { + return sysRiskService.saveIp(sysType, ipList); + } + + @Operation(summary = "获取Uri风控数据") + @GetMapping("get-uri/{sysType}") + public Result> getUri( + @Schema(description = "系统类型") + @NotBlank(message = "不能为空") + @PathVariable String sysType + ) { + return sysRiskService.getUri(sysType); + } + + @Operation(summary = "保存Uri风控数据") + @PostMapping("save-uri/{sysType}") + public Result saveUri( + @Schema(description = "黑名单") + @NotNull(message = "不能为空") + @PathVariable String sysType, + @Schema(description = "Uri列表") + @RequestBody List uriList + ) { + return sysRiskService.saveUri(sysType, uriList); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleController.java new file mode 100644 index 0000000..38f8c8f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleController.java @@ -0,0 +1,88 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysRoleAddReq; +import xtools.app.sys.model.dto.req.SysRolePageReq; +import xtools.app.sys.model.dto.req.SysRoleUpdateReq; +import xtools.app.sys.model.dto.resp.SysRoleResp; +import xtools.app.sys.service.SysRoleService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysRoleController

+ *

Description : 系统角色表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Tag(name = "系统角色表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/role") +public class SysRoleController { + + private final SysRoleService sysRoleService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysRoleService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysRoleService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysRoleAddReq req) { + return sysRoleService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysRoleUpdateReq req) { + return sysRoleService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysRoleService.delById(req.getIdList()); + } + + @Operation(summary = "获取所有角色数据") + @GetMapping("all") + public Result> all() { + return sysRoleService.all(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleMenuController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleMenuController.java new file mode 100644 index 0000000..00b6fd8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysRoleMenuController.java @@ -0,0 +1,68 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysRoleMenuReq; +import xtools.app.sys.service.SysRoleMenuService; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysRoleMenuController

+ *

Description : 角色菜单关联表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Tag(name = "角色菜单关联表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/role-menu") +public class SysRoleMenuController { + + private final SysRoleMenuService sysRoleMenuService; + + /** + * 获取角色菜单 ID 集合 + * + * @param roleId 角色 ID + * @return 角色菜单 ID 集合 + */ + @Operation(summary = "获取角色菜单 ID 集合") + @GetMapping("/get-role-menu/{roleId}") + public Result> getRoleMenu( + @Schema(description = "角色 ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long roleId + ) { + return sysRoleMenuService.getRoleMenu(roleId); + } + + /** + * 保存角色菜单关联 + * + * @param req 保存参数 + * @return 保存结果 + */ + @Operation(summary = "保存角色菜单关联") + @PostMapping("/save-role-menu") + public Result saveRoleMenu(@RequestBody @Valid SysRoleMenuReq req) { + return sysRoleMenuService.saveRoleMenu(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysTaskController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysTaskController.java new file mode 100644 index 0000000..afea9f3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysTaskController.java @@ -0,0 +1,41 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysTaskPageReq; +import xtools.app.sys.model.dto.resp.SysTaskResp; +import xtools.app.sys.service.SysTaskService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +/** + *

Title : SysTaskController

+ *

Description : 系统任务 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Tag(name = "系统任务") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/task") +public class SysTaskController { + + private final SysTaskService sysTaskService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysTaskService.page(pageReq); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUpdateHistoryController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUpdateHistoryController.java new file mode 100644 index 0000000..0c11cd1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUpdateHistoryController.java @@ -0,0 +1,90 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysUpdateHistoryAddReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryPageReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryUpdateReq; +import xtools.app.sys.model.dto.resp.SysUpdateHistoryResp; +import xtools.app.sys.service.SysUpdateHistoryService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysUpdateHistoryController

+ *

Description : 系统更新历史 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Tag(name = "系统更新历史") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/update-history") +public class SysUpdateHistoryController { + + private final SysUpdateHistoryService sysUpdateHistoryService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysUpdateHistoryService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysUpdateHistoryService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysUpdateHistoryAddReq req) { + return sysUpdateHistoryService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysUpdateHistoryUpdateReq req) { + return sysUpdateHistoryService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysUpdateHistoryService.delById(req.getIdList()); + } + + @Operation(summary = "删除缓存") + @DeleteMapping("delete-cache/{type}") + public Result deleteCache( + @Schema(description = "类型", example = "1") + @NotNull(message = "不能为空") + @PathVariable Integer type + ) { + return sysUpdateHistoryService.deleteCache(type); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserController.java new file mode 100644 index 0000000..f810fc7 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserController.java @@ -0,0 +1,88 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysUserAddReq; +import xtools.app.sys.model.dto.req.SysUserPageReq; +import xtools.app.sys.model.dto.req.SysUserUpdateReq; +import xtools.app.sys.model.dto.resp.SysUserResp; +import xtools.app.sys.service.SysUserService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysUserController

+ *

Description : 系统用户表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Tag(name = "系统用户表") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/user") +public class SysUserController { + + private final SysUserService sysUserService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysUserService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysUserService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysUserAddReq req) { + return sysUserService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysUserUpdateReq req) { + return sysUserService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysUserService.delById(req.getIdList()); + } + + @Operation(summary = "根据 ID 集合查询") + @PostMapping("get-list-by-ids") + public Result> getListByIds(@RequestBody @Valid IdListReq req) { + return sysUserService.getListByIds(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeController.java new file mode 100644 index 0000000..7c2b6b5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeController.java @@ -0,0 +1,57 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysUserNoticePageReq; +import xtools.app.sys.model.dto.req.SysUserNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeResp; +import xtools.app.sys.service.SysUserNoticeService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysUserNoticeController

+ *

Description : 系统用户通知公告表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@RequiredArgsConstructor +@Tag(name = "系统用户通知公告表") +@RestController +@RequestMapping("/sys/user-notice") +public class SysUserNoticeController { + + private final SysUserNoticeService sysUserNoticeService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysUserNoticeService.page(pageReq); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysUserNoticeUpdateReq req) { + return sysUserNoticeService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysUserNoticeService.delById(req); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeInfoController.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeInfoController.java new file mode 100644 index 0000000..12ddd4b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/controller/SysUserNoticeInfoController.java @@ -0,0 +1,70 @@ +package xtools.app.sys.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.model.dto.req.SysUserNoticeInfoPageReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeInfoResp; +import xtools.app.sys.service.SysUserNoticeInfoService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysUserNoticeInfoController

+ *

Description : 系统用户通知公告信息表 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@RequiredArgsConstructor +@Tag(name = "系统用户通知公告信息表") +@RestController +@RequestMapping("/sys/user-notice-info") +public class SysUserNoticeInfoController { + + private final SysUserNoticeInfoService sysUserNoticeInfoService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysUserNoticeInfoService.page(pageReq); + } + + @Operation(summary = "获取内容") + @GetMapping("get-content/{id}") + public Result getContent( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysUserNoticeInfoService.getContent(id); + } + + @Operation(summary = "批量已读") + @PostMapping("read-list") + public Result readList(@RequestBody @Valid IdListReq req) { + return sysUserNoticeInfoService.readList(req); + } + + @Operation(summary = "全部已读") + @GetMapping("read-all") + public Result readAll() { + return sysUserNoticeInfoService.readAll(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysAddressConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysAddressConvert.java new file mode 100644 index 0000000..e266d2d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysAddressConvert.java @@ -0,0 +1,27 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.resp.SysAddressResp; +import xtools.app.sys.model.entity.SysAddress; + +/** + *

Title : SysAddressConvert

+ *

Description : 公用地址表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@Mapper(componentModel = "spring") +public interface SysAddressConvert { + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysAddressResp entityToResp(SysAddress data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysBaseConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysBaseConvert.java new file mode 100644 index 0000000..c2c5cfa --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysBaseConvert.java @@ -0,0 +1,27 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.resp.SysIpAddrResp; +import xtools.extend.dto.IpAddrDto; + +/** + *

Title : SysBaseConvert

+ *

Description : SysBaseConvert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper(componentModel = "spring") +public interface SysBaseConvert { + + /** + * IP地址DTO 转换为响应对象 + * + * @param dto IP地址DTO + * @return 响应对象 + */ + SysIpAddrResp dtoToResp(IpAddrDto dto); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDeptConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDeptConvert.java new file mode 100644 index 0000000..68fe298 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDeptConvert.java @@ -0,0 +1,64 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysDeptAddReq; +import xtools.app.sys.model.dto.req.SysDeptUpdateReq; +import xtools.app.sys.model.dto.resp.SysDeptResp; +import xtools.app.sys.model.dto.resp.SysDeptTreeResp; +import xtools.app.sys.model.entity.SysDept; + +import java.util.List; + +/** + *

Title : SysDeptConvert

+ *

Description : 部门管理表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Mapper(componentModel = "spring") +public interface SysDeptConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysDept addReqToEntity(SysDeptAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysDept updateReqToEntity(SysDeptUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysDeptResp entityToResp(SysDept data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 批量实体转 Tree 响应 + * + * @param list 批量实体 + * @return 响应 + */ + List entityToTreeRespList(List list); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictConvert.java new file mode 100644 index 0000000..7e4ab7b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictConvert.java @@ -0,0 +1,74 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import xtools.app.sys.model.dto.excel.SysDictExcel; +import xtools.app.sys.model.dto.req.SysDictAddReq; +import xtools.app.sys.model.dto.req.SysDictUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictResp; +import xtools.app.sys.model.entity.SysDict; + +import java.util.List; + +/** + *

Title : SysDictConvert

+ *

Description : 数据字典类型表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Mapper(componentModel = "spring") +public interface SysDictConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysDict addReqToEntity(SysDictAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysDict updateReqToEntity(SysDictUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysDictResp entityToResp(SysDict data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + SysDictExcel entityToExcel(SysDict data); + + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + @Mapping(target = "status", ignore = true) + SysDict excelToEntity(SysDictExcel data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictItemConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictItemConvert.java new file mode 100644 index 0000000..42d92a3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysDictItemConvert.java @@ -0,0 +1,74 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import xtools.app.sys.model.dto.excel.SysDictItemExcel; +import xtools.app.sys.model.dto.req.SysDictItemAddReq; +import xtools.app.sys.model.dto.req.SysDictItemUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.app.sys.model.entity.SysDictItem; + +import java.util.List; + +/** + *

Title : SysDictItemConvert

+ *

Description : 数据字典项表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Mapper(componentModel = "spring") +public interface SysDictItemConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysDictItem addReqToEntity(SysDictItemAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysDictItem updateReqToEntity(SysDictItemUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysDictItemResp entityToResp(SysDictItem data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + SysDictItemExcel entityToExcel(SysDictItem data); + + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + @Mapping(target = "status", ignore = true) + SysDictItem excelToEntity(SysDictItemExcel data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysFileConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysFileConvert.java new file mode 100644 index 0000000..c20f94b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysFileConvert.java @@ -0,0 +1,55 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileUpdateReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.app.sys.model.entity.SysFile; + +import java.util.List; + +/** + *

Title : SysFileConvert

+ *

Description : 系统文件表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Mapper(componentModel = "spring") +public interface SysFileConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysFile addReqToEntity(SysFileAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysFile updateReqToEntity(SysFileUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysFileResp entityToResp(SysFile data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLogConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLogConvert.java new file mode 100644 index 0000000..b30168c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLogConvert.java @@ -0,0 +1,37 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.resp.SysLogResp; +import xtools.app.sys.model.entity.SysLog; + +import java.util.List; + +/** + *

Title : SysLogConvert

+ *

Description : 日志记录表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Mapper(componentModel = "spring") +public interface SysLogConvert { + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysLogResp entityToResp(SysLog data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLoginConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLoginConvert.java new file mode 100644 index 0000000..3caf750 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysLoginConvert.java @@ -0,0 +1,27 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.model.entity.SysUser; + +/** + *

Title : SysLoginConvert

+ *

Description : SysLoginConvert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper(componentModel = "spring") +public interface SysLoginConvert { + + /** + * 实体转缓存 Dto + * + * @param entity 实体 + * @return 响应 + */ + LoginUserDto entityToCacheDto(SysUser entity); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysMenuConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysMenuConvert.java new file mode 100644 index 0000000..0b7cf3c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysMenuConvert.java @@ -0,0 +1,64 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysMenuAddReq; +import xtools.app.sys.model.dto.req.SysMenuUpdateReq; +import xtools.app.sys.model.dto.resp.SysMenuResp; +import xtools.app.sys.model.dto.resp.SysMenuTreeResp; +import xtools.app.sys.model.entity.SysMenu; + +import java.util.List; + +/** + *

Title : SysMenuConvert

+ *

Description : 系统菜单表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Mapper(componentModel = "spring") +public interface SysMenuConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysMenu addReqToEntity(SysMenuAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysMenu updateReqToEntity(SysMenuUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysMenuResp entityToResp(SysMenu data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 批量实体转 Tree 响应 + * + * @param list 批量实体 + * @return 响应 + */ + List entityToTreeRespList(List list); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysNoticeConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysNoticeConvert.java new file mode 100644 index 0000000..f606568 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysNoticeConvert.java @@ -0,0 +1,55 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysNoticeAddReq; +import xtools.app.sys.model.dto.req.SysNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysNoticeResp; +import xtools.app.sys.model.entity.SysNotice; + +import java.util.List; + +/** + *

Title : SysNoticeConvert

+ *

Description : 系统通知公告表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Mapper(componentModel = "spring") +public interface SysNoticeConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysNotice addReqToEntity(SysNoticeAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysNotice updateReqToEntity(SysNoticeUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysNoticeResp entityToResp(SysNotice data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysParamConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysParamConvert.java new file mode 100644 index 0000000..e37c0d8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysParamConvert.java @@ -0,0 +1,74 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import xtools.app.sys.model.dto.excel.SysParamExcel; +import xtools.app.sys.model.dto.req.SysParamAddReq; +import xtools.app.sys.model.dto.req.SysParamUpdateReq; +import xtools.app.sys.model.dto.resp.SysParamResp; +import xtools.app.sys.model.entity.SysParam; + +import java.util.List; + +/** + *

Title : SysParamConvert

+ *

Description : 系统参数表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Mapper(componentModel = "spring") +public interface SysParamConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysParam addReqToEntity(SysParamAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysParam updateReqToEntity(SysParamUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysParamResp entityToResp(SysParam data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + SysParamExcel entityToExcel(SysParam data); + + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + @Mapping(target = "dataType", ignore = true) + SysParam excelToEntity(SysParamExcel data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRiskConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRiskConvert.java new file mode 100644 index 0000000..57f72fa --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRiskConvert.java @@ -0,0 +1,72 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.excel.SysRiskExcel; +import xtools.app.sys.model.dto.req.SysRiskAddReq; +import xtools.app.sys.model.dto.req.SysRiskUpdateReq; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.app.sys.model.entity.SysRisk; + +import java.util.List; + +/** + *

Title : SysRiskConvert

+ *

Description : 系统风控表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Mapper(componentModel = "spring") +public interface SysRiskConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysRisk addReqToEntity(SysRiskAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysRisk updateReqToEntity(SysRiskUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysRiskResp entityToResp(SysRisk data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + SysRiskExcel entityToExcel(SysRisk data); + + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + SysRisk excelToEntity(SysRiskExcel data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleConvert.java new file mode 100644 index 0000000..b2521cb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleConvert.java @@ -0,0 +1,55 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysRoleAddReq; +import xtools.app.sys.model.dto.req.SysRoleUpdateReq; +import xtools.app.sys.model.dto.resp.SysRoleResp; +import xtools.app.sys.model.entity.SysRole; + +import java.util.List; + +/** + *

Title : SysRoleConvert

+ *

Description : 系统角色表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper(componentModel = "spring") +public interface SysRoleConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysRole addReqToEntity(SysRoleAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysRole updateReqToEntity(SysRoleUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysRoleResp entityToResp(SysRole data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleMenuConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleMenuConvert.java new file mode 100644 index 0000000..af56516 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysRoleMenuConvert.java @@ -0,0 +1,17 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; + +/** + *

Title : SysRoleMenuConvert

+ *

Description : 角色菜单关联表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Mapper(componentModel = "spring") +public interface SysRoleMenuConvert { + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysTaskConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysTaskConvert.java new file mode 100644 index 0000000..a7b1133 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysTaskConvert.java @@ -0,0 +1,37 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.resp.SysTaskResp; +import xtools.app.sys.model.entity.SysTask; + +import java.util.List; + +/** + *

Title : SysTaskConvert

+ *

Description : 系统任务 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Mapper(componentModel = "spring") +public interface SysTaskConvert { + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysTaskResp entityToResp(SysTask data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUpdateHistoryConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUpdateHistoryConvert.java new file mode 100644 index 0000000..6b8f78d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUpdateHistoryConvert.java @@ -0,0 +1,64 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysUpdateHistoryAddReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryUpdateReq; +import xtools.app.sys.model.dto.resp.SysUpdateHistoryResp; +import xtools.app.sys.model.entity.SysUpdateHistory; +import xtools.app.sys.param.dto.UpdateHistoryDto; + +import java.util.List; + +/** + *

Title : SysUpdateHistoryConvert

+ *

Description : 系统更新历史 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Mapper(componentModel = "spring") +public interface SysUpdateHistoryConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysUpdateHistory addReqToEntity(SysUpdateHistoryAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysUpdateHistory updateReqToEntity(SysUpdateHistoryUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysUpdateHistoryResp entityToResp(SysUpdateHistory data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 批量实体转缓存 + * + * @param dataList 批量实体 + * @return 缓存 + */ + List entityToCacheList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserConvert.java new file mode 100644 index 0000000..d433842 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserConvert.java @@ -0,0 +1,63 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysUserAddReq; +import xtools.app.sys.model.dto.req.SysUserUpdateReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.resp.SysUserResp; +import xtools.app.sys.model.entity.SysUser; + +import java.util.List; + +/** + *

Title : SysUserConvert

+ *

Description : 系统用户表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper(componentModel = "spring") +public interface SysUserConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysUser addReqToEntity(SysUserAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysUser updateReqToEntity(SysUserUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysUserResp entityToResp(SysUser data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 保存请求转实体 + * + * @param req 保存请求 + * @return 实体 + */ + SysUser saveReqToEntity(UserInfoEditReq req); +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeConvert.java new file mode 100644 index 0000000..4ef51f2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeConvert.java @@ -0,0 +1,55 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.model.dto.req.SysUserNoticeAddReq; +import xtools.app.sys.model.dto.req.SysUserNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeResp; +import xtools.app.sys.model.entity.SysUserNotice; + +import java.util.List; + +/** + *

Title : SysUserNoticeConvert

+ *

Description : 系统用户通知公告表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Mapper(componentModel = "spring") +public interface SysUserNoticeConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysUserNotice addReqToEntity(SysUserNoticeAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysUserNotice updateReqToEntity(SysUserNoticeUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysUserNoticeResp entityToResp(SysUserNotice data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeInfoConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeInfoConvert.java new file mode 100644 index 0000000..77fbb70 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserNoticeInfoConvert.java @@ -0,0 +1,17 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; + +/** + *

Title : SysUserNoticeInfoConvert

+ *

Description : 系统用户通知公告信息表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Mapper(componentModel = "spring") +public interface SysUserNoticeInfoConvert { + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserRoleConvert.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserRoleConvert.java new file mode 100644 index 0000000..93fcbb3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/convert/SysUserRoleConvert.java @@ -0,0 +1,17 @@ +package xtools.app.sys.convert; + +import org.mapstruct.Mapper; + +/** + *

Title : SysUserRoleConvert

+ *

Description : 用户角色关联表 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +@Mapper(componentModel = "spring") +public interface SysUserRoleConvert { + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/init/InitSys.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/init/InitSys.java new file mode 100644 index 0000000..75006d6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/init/InitSys.java @@ -0,0 +1,68 @@ +package xtools.app.sys.init; + +import lombok.RequiredArgsConstructor; +import org.jspecify.annotations.NonNull; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import xtools.app.sys.risk.IpRisk; +import xtools.app.sys.risk.UriRisk; +import xtools.app.sys.service.SysParamService; +import xtools.app.sys.service.SysPermService; +import xtools.app.sys.service.SysUpdateHistoryService; +import xtools.base.config.BaseParams; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.core.enums.LogLevel; + + +/** + *

Title : InitSys

+ *

Description : InitSys

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 14:13 + */ +@Component +@Order(BaseParams.CP_NUM200) +@RequiredArgsConstructor +public class InitSys implements ApplicationRunner { + + private final SysPermService sysPermService; + + private final SysParamService sysParamService; + + private final SysUpdateHistoryService sysUpdateHistoryService; + + private final IpRisk ipRisk; + + private final UriRisk uriRisk; + + @Override + public void run(@NonNull ApplicationArguments args) { + ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newMain()).run(() -> { + try { + init(); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.OTHER).title("初始化异常").error(e).save(); + } + }); + } + + /** + * 初始化 + */ + private void init() { + sysParamService.init(); + sysPermService.reloadPermCache(); + sysUpdateHistoryService.init(); + ipRisk.init(); + uriRisk.init(); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysFileJob.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysFileJob.java new file mode 100644 index 0000000..cf3bdaf --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysFileJob.java @@ -0,0 +1,35 @@ +package xtools.app.sys.job; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import xtools.app.common.job.base.BaseJob; +import xtools.app.sys.service.SysFileService; + +/** + *

Title : SysFileJob

+ *

Description : SysFileJob

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/17 21:24 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class SysFileJob extends BaseJob { + + private final SysFileService sysFileService; + + /** + * 运行作业 + */ + @Override + public void runJob() { + sysFileService.doJob(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysLogJob.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysLogJob.java new file mode 100644 index 0000000..86ebeb8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/job/SysLogJob.java @@ -0,0 +1,83 @@ +package xtools.app.sys.job; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import xtools.app.common.job.base.BaseJob; +import xtools.app.common.task.enums.TaskType; +import xtools.app.sys.config.SysConfig; +import xtools.app.sys.service.SysLogService; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.task.TaskBus; +import xtools.boot.task.enums.TaskStatus; +import xtools.core.UuidUtils; +import xtools.core.enums.LogLevel; +import xtools.core.extend.TemplateUtils; +import xtools.core.time.CalendarUtils; + +import java.time.Instant; +import java.util.Calendar; +import java.util.Objects; + +/** + *

Title : SysLogJob

+ *

Description : SysLogJob

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/17 21:24 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class SysLogJob extends BaseJob { + + private final SysConfig sysConfig; + + private final SysLogService sysLogService; + + /** + * 运行作业 + */ + @Override + public void runJob() { + // 任务日志code + String code = UuidUtils.get(); + // 任务类型 + TaskType taskType = TaskType.DEL_SYS_LOG; + // 任务信息 + String info = "开始清理系统日志,请稍候..."; + // 保存任务 + TaskBus.init(code, taskType, TaskStatus.ING).info(info).save(); + // 异常 + Exception ex = null; + try { + // 保存天数 + int day = sysConfig.getLog().getMaxDays(); + // 获取删除对应的时间 + Instant aMonthAgo = CalendarUtils.calc(Calendar.DATE, -day); + // 删除日志 + Long count = sysLogService.delete(null, aMonthAgo); + // 记录任务日志 + info = "执行完成,共清理[{}]天前的[{}]条系统日志"; + info = TemplateUtils.format(info, day, count); + } catch (Exception e) { + ex = e; + info = "执行失败"; + throw e; + } finally { + // 保存任务 + TaskStatus status = Objects.isNull(ex) ? TaskStatus.SUCCESS : TaskStatus.ERROR; + TaskBus.init(code, taskType, status).info(info).save(); + if (Objects.nonNull(ex)) { + // 保存异常日志 + LogBus.init(LogLevel.ERROR, LogBusBaseType.TASK).error(ex).save(); + } + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysAddressMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysAddressMapper.java new file mode 100644 index 0000000..f41d929 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysAddressMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysAddress; + +/** + *

Title : SysAddressMapper

+ *

Description : 公用地址表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@Mapper +public interface SysAddressMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDeptMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDeptMapper.java new file mode 100644 index 0000000..223adbb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDeptMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysDept; + +/** + *

Title : SysDeptMapper

+ *

Description : 部门管理表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Mapper +public interface SysDeptMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictItemMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictItemMapper.java new file mode 100644 index 0000000..f7a2fab --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictItemMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysDictItem; + +/** + *

Title : SysDictItemMapper

+ *

Description : 数据字典项表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Mapper +public interface SysDictItemMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictMapper.java new file mode 100644 index 0000000..270e86d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysDictMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysDict; + +/** + *

Title : SysDictMapper

+ *

Description : 数据字典类型表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Mapper +public interface SysDictMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysFileMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysFileMapper.java new file mode 100644 index 0000000..a14d93d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysFileMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysFile; + +/** + *

Title : SysFileMapper

+ *

Description : 系统文件表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Mapper +public interface SysFileMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysLogMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysLogMapper.java new file mode 100644 index 0000000..8d74009 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysLogMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysLog; + +/** + *

Title : SysLogMapper

+ *

Description : 日志记录表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Mapper +public interface SysLogMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysMenuMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysMenuMapper.java new file mode 100644 index 0000000..7aaaf2b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysMenuMapper.java @@ -0,0 +1,46 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xtools.app.sys.model.entity.SysInterfacePerm; +import xtools.app.sys.model.entity.SysMenu; + +import java.util.List; + +/** + *

Title : SysMenuMapper

+ *

Description : 系统菜单表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Mapper +public interface SysMenuMapper extends BaseMapper { + + /** + * 根据角色 ID 查询菜单列表 + * + * @param roleIds 角色 ID 集合 + * @return 菜单列表 + */ + List getMenuByRoleIds(@Param("roleIds") List roleIds); + + /** + * 根据角色 ID 获取按钮权限列表 + * + * @param roleIds 角色 ID 集合 + * @return 按钮权限列表 + */ + List getBtnPermByRoleIds(@Param("roleIds") List roleIds); + + /** + * 获取接口权限列表 + * + * @return 接口权限列表 + */ + List getSysInterfacePerm(); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysNoticeMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..0a9e29f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysNoticeMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysNotice; + +/** + *

Title : SysNoticeMapper

+ *

Description : 系统通知公告表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Mapper +public interface SysNoticeMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysParamMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysParamMapper.java new file mode 100644 index 0000000..32655bb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysParamMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysParam; + +/** + *

Title : SysParamMapper

+ *

Description : 系统参数表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Mapper +public interface SysParamMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRiskMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRiskMapper.java new file mode 100644 index 0000000..b3d0bed --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRiskMapper.java @@ -0,0 +1,40 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xtools.app.sys.model.entity.SysRisk; + +/** + *

Title : SysRiskMapper

+ *

Description : 系统风控表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Mapper +public interface SysRiskMapper extends BaseMapper { + + /** + * 添加IP + * + * @param type 风控类型 + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + Integer addIp(@Param("type") Integer type, @Param("sysType") String sysType, @Param("ip") String ip); + + /** + * 移除IP + * + * @param type 风控类型 + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + Integer removeIp(@Param("type") Integer type, @Param("sysType") String sysType, @Param("ip") String ip); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMapper.java new file mode 100644 index 0000000..c61e94f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysRole; + +/** + *

Title : SysRoleMapper

+ *

Description : 系统角色表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper +public interface SysRoleMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMenuMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..031f5e4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysRoleMenuMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysRoleMenu; + +/** + *

Title : SysRoleMenuMapper

+ *

Description : 角色菜单关联表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Mapper +public interface SysRoleMenuMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysTaskMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysTaskMapper.java new file mode 100644 index 0000000..b90d1f5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysTaskMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysTask; + +/** + *

Title : SysTaskMapper

+ *

Description : 系统任务 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Mapper +public interface SysTaskMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUpdateHistoryMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUpdateHistoryMapper.java new file mode 100644 index 0000000..f3bc52e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUpdateHistoryMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysUpdateHistory; + +/** + *

Title : SysUpdateHistoryMapper

+ *

Description : 系统更新历史 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Mapper +public interface SysUpdateHistoryMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserMapper.java new file mode 100644 index 0000000..6ce7a08 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysUser; + +/** + *

Title : SysUserMapper

+ *

Description : 系统用户表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Mapper +public interface SysUserMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeInfoMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeInfoMapper.java new file mode 100644 index 0000000..a7dfebb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeInfoMapper.java @@ -0,0 +1,38 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xtools.app.sys.model.dto.req.SysUserNoticeInfoPageReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeInfoResp; +import xtools.app.sys.model.entity.SysUserNoticeInfo; + +/** + *

Title : SysUserNoticeInfoMapper

+ *

Description : 系统用户通知公告信息表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Mapper +public interface SysUserNoticeInfoMapper extends BaseMapper { + + /** + * 获取用户通知列表 + * + * @param page 分页条件 + * @param userId 用户 ID + * @param query 查询条件 + * @return 用户通知列表 + */ + Page getUserNoticeList( + IPage page, + @Param("userId") Long userId, + @Param("query") SysUserNoticeInfoPageReq query + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeMapper.java new file mode 100644 index 0000000..99dfd66 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserNoticeMapper.java @@ -0,0 +1,36 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xtools.app.sys.model.dto.req.SysUserNoticePageReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeResp; +import xtools.app.sys.model.entity.SysUserNotice; + +/** + *

Title : SysUserNoticeMapper

+ *

Description : 系统用户通知公告表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Mapper +public interface SysUserNoticeMapper extends BaseMapper { + + /** + * 获取分页列表 + * + * @param page 分页参数 + * @param query 查询参数 + * @return 分页列表 + */ + Page getPage( + IPage page, + @Param("query") SysUserNoticePageReq query + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserRoleMapper.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..d640f1b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mapper/SysUserRoleMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.model.entity.SysUserRole; + +/** + *

Title : SysUserRoleMapper

+ *

Description : 用户角色关联表 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +@Mapper +public interface SysUserRoleMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/Sm2KeyDto.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/Sm2KeyDto.java new file mode 100644 index 0000000..97ed2c1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/Sm2KeyDto.java @@ -0,0 +1,34 @@ +package xtools.app.sys.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : Sm2Key

+ *

Description : Sm2Key

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/10 16:39 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Sm2KeyDto implements Serializable { + + /** + * 公钥 + */ + private String publicKey; + + /** + * 私钥 + */ + private String privateKey; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictExcel.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictExcel.java new file mode 100644 index 0000000..0dd3741 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictExcel.java @@ -0,0 +1,47 @@ +package xtools.app.sys.model.dto.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; + +import java.io.Serializable; + +/** + *

Title : SysDictExcel

+ *

Description : 数据字典类型表Excel对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-20 10:21:54 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictExcel implements Serializable { + + /** + * 字典编码 + */ + @ExcelProperty("字典编码") + private String dictCode; + + /** + * 字典名称 + */ + @ExcelProperty("字典名称") + private String dictName; + + /** + * 状态 + */ + @ExcelProperty("状态") + private String status; + + /** + * 备注 + */ + @ExcelProperty("备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictItemExcel.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictItemExcel.java new file mode 100644 index 0000000..1cabbbc --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysDictItemExcel.java @@ -0,0 +1,68 @@ +package xtools.app.sys.model.dto.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; + +import java.io.Serializable; + +/** + *

Title : SysDictItemExcel

+ *

Description : SysDictItemExcel

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/19 16:53 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictItemExcel implements Serializable { + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @ExcelProperty("关联字典编码") + private String dictCode; + + /** + * 字典项值 + */ + @ExcelProperty("字典项值") + private String value; + + /** + * 字典项标签 + */ + @ExcelProperty("字典项标签") + private String label; + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @ExcelProperty("标签类型") + private String tagType; + + /** + * 状态 + */ + @ExcelProperty("状态") + private String status; + + /** + * 排序 + */ + @ExcelProperty("排序") + private Integer sort; + + /** + * 备注 + */ + @ExcelProperty("备注") + private String memo; + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysParamExcel.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysParamExcel.java new file mode 100644 index 0000000..24ccf82 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysParamExcel.java @@ -0,0 +1,48 @@ +package xtools.app.sys.model.dto.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; + +import java.io.Serializable; + +/** + *

Title : SysParamExcel

+ *

Description : 系统参数表Excel对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysParamExcel implements Serializable { + + /** + * 系统参数key + */ + @ExcelProperty("系统参数key") + private String paramKey; + + /** + * 系统参数值 + */ + @ExcelProperty("系统参数值") + private String data; + + /** + * 参数值类型 + */ + @ExcelProperty("参数值类型") + private String dataType; + + /** + * 备注 + */ + @ExcelProperty("备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysRiskExcel.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysRiskExcel.java new file mode 100644 index 0000000..b2103b0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/excel/SysRiskExcel.java @@ -0,0 +1,66 @@ +package xtools.app.sys.model.dto.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; + +import java.io.Serializable; + +/** + *

Title : SysRiskExcel

+ *

Description : 系统风控表Excel对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRiskExcel implements Serializable { + + /** + * 主键 ID + */ + @ExcelProperty("主键 ID") + private Long id; + + /** + * 系统类型 + */ + @ExcelProperty("系统类型") + private String sysType; + + /** + * 风控类型 + */ + @ExcelProperty("风控类型") + private Integer type; + + /** + * 系统参数值 + */ + @ExcelProperty("系统参数值") + private String data; + + /** + * 创建人ID + */ + @ExcelProperty("创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @ExcelProperty("更新人ID") + private Long updateBy; + + /** + * 备注 + */ + @ExcelProperty("备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/IgnoreMaskReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/IgnoreMaskReq.java new file mode 100644 index 0000000..dc90f41 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/IgnoreMaskReq.java @@ -0,0 +1,48 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : IgnoreMaskReq

+ *

Description : IgnoreMaskReq

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 18:44 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IgnoreMaskReq implements Serializable { + + /** + * Uid + */ + @Schema(description = "uid", example = "abc") + private String uid; + + /** + * 公钥 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "公钥", example = "abc") + private String publicKey; + + /** + * 密码 + */ + @Size(min = 6, message = "长度不能小于6") + @NotEmpty(message = "不能为空") + @Schema(description = "密码", example = "123456") + private String passwd; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptAddReq.java new file mode 100644 index 0000000..b3b10eb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptAddReq.java @@ -0,0 +1,77 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDeptAddReq

+ *

Description : 部门管理表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDeptAddReq implements Serializable { + + /** + * 部门编号 + */ + @Schema(description = "部门编号", example = "DEPT001") + private String deptCode; + + /** + * 部门名称 + */ + @Schema(description = "部门名称", example = "研发部") + private String deptName; + + /** + * 父节点 ID + */ + @Schema(description = "父节点 ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "部门描述信息") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptPageReq.java new file mode 100644 index 0000000..a3d4326 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptPageReq.java @@ -0,0 +1,96 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysDeptPageReq

+ *

Description : 部门管理表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDeptPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 部门编号 + */ + @Schema(description = "部门编号", example = "DEPT001") + private String deptCode; + + /** + * 部门名称 + */ + @Schema(description = "部门名称", example = "研发部") + private String deptName; + + /** + * 父节点 ID + */ + @Schema(description = "父节点 ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "部门描述信息") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptUpdateReq.java new file mode 100644 index 0000000..8d0461b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDeptUpdateReq.java @@ -0,0 +1,83 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDeptUpdateReq

+ *

Description : 部门管理表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDeptUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 部门编号 + */ + @Schema(description = "部门编号", example = "DEPT001") + private String deptCode; + + /** + * 部门名称 + */ + @Schema(description = "部门名称", example = "研发部") + private String deptName; + + /** + * 父节点 ID + */ + @Schema(description = "父节点 ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "部门描述信息") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictAddReq.java new file mode 100644 index 0000000..455e792 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictAddReq.java @@ -0,0 +1,59 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDictAddReq

+ *

Description : 数据字典类型表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictAddReq implements Serializable { + + /** + * 字典编码 + */ + @Schema(description = "字典编码", example = "USER_STATUS") + private String dictCode; + + /** + * 字典名称 + */ + @Schema(description = "字典名称", example = "用户状态") + private String dictName; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户状态字典") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemAddReq.java new file mode 100644 index 0000000..3024f96 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemAddReq.java @@ -0,0 +1,77 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDictItemAddReq

+ *

Description : 数据字典项表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictItemAddReq implements Serializable { + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @Schema(description = "关联字典编码,与sys_dict表中的dict_code对应", example = "USER_STATUS") + private String dictCode; + + /** + * 字典项值 + */ + @Schema(description = "字典项值", example = "1") + private String value; + + /** + * 字典项标签 + */ + @Schema(description = "字典项标签", example = "启用") + private String label; + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @Schema(description = "标签类型,用于前端样式展示(如success,warning等)", example = "success") + private String tagType; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID", example = "1") + private Long createBy; + + /** + * 修改人ID + */ + @Schema(description = "修改人ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "启用状态") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemPageReq.java new file mode 100644 index 0000000..0102442 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemPageReq.java @@ -0,0 +1,96 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysDictItemPageReq

+ *

Description : 数据字典项表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictItemPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @Schema(description = "关联字典编码,与sys_dict表中的dict_code对应", example = "USER_STATUS") + private String dictCode; + + /** + * 字典项值 + */ + @Schema(description = "字典项值", example = "1") + private String value; + + /** + * 字典项标签 + */ + @Schema(description = "字典项标签", example = "启用") + private String label; + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @Schema(description = "标签类型,用于前端样式展示(如success,warning等)", example = "success") + private String tagType; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID", example = "1") + private Long createBy; + + /** + * 修改人ID + */ + @Schema(description = "修改人ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "启用状态") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemUpdateReq.java new file mode 100644 index 0000000..4354839 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictItemUpdateReq.java @@ -0,0 +1,83 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDictItemUpdateReq

+ *

Description : 数据字典项表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictItemUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @Schema(description = "关联字典编码,与sys_dict表中的dict_code对应", example = "USER_STATUS") + private String dictCode; + + /** + * 字典项值 + */ + @Schema(description = "字典项值", example = "1") + private String value; + + /** + * 字典项标签 + */ + @Schema(description = "字典项标签", example = "启用") + private String label; + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @Schema(description = "标签类型,用于前端样式展示(如success,warning等)", example = "success") + private String tagType; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID", example = "1") + private Long createBy; + + /** + * 修改人ID + */ + @Schema(description = "修改人ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "启用状态") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictPageReq.java new file mode 100644 index 0000000..fa29b0c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictPageReq.java @@ -0,0 +1,78 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysDictPageReq

+ *

Description : 数据字典类型表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 字典编码 + */ + @Schema(description = "字典编码", example = "USER_STATUS") + private String dictCode; + + /** + * 字典名称 + */ + @Schema(description = "字典名称", example = "用户状态") + private String dictName; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户状态字典") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictUpdateReq.java new file mode 100644 index 0000000..b28a945 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysDictUpdateReq.java @@ -0,0 +1,65 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysDictUpdateReq

+ *

Description : 数据字典类型表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysDictUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 字典编码 + */ + @Schema(description = "字典编码", example = "USER_STATUS") + private String dictCode; + + /** + * 字典名称 + */ + @Schema(description = "字典名称", example = "用户状态") + private String dictName; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户状态字典") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysFilePageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysFilePageReq.java new file mode 100644 index 0000000..1a4ce34 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysFilePageReq.java @@ -0,0 +1,144 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysFilePageReq

+ *

Description : 系统文件表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysFilePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 用户id + */ + @Schema(description = "用户id") + private Long userId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + private String userName; + + /** + * 业务id + */ + @Schema(description = "业务id") + private Long bizId; + + /** + * 业务类型 + */ + @Schema(description = "业务类型") + private String bizType; + + /** + * 权限 + */ + @Schema(description = "权限") + private Integer permission; + + /** + * 桶名称 + */ + @Schema(description = "桶名称") + private String bucket; + + /** + * 桶类型 + */ + @Schema(description = "桶类型") + private String storageType; + + /** + * 文件上传时间 + */ + @Schema(description = "文件上传时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] uploadTimeRange; + + /** + * 文件路径 + */ + @Schema(description = "文件路径") + private String filePath; + + /** + * 文件名 + */ + @Schema(description = "文件名") + private String fileName; + + /** + * 文件大小 + */ + @Schema(description = "文件大小") + private Long fileSize; + + /** + * 文件类型 + */ + @Schema(description = "文件类型") + private String fileType; + + /** + * MD5值 + */ + @Schema(description = "MD5值") + private String md5; + + /** + * SM3值 + */ + @Schema(description = "SM3值") + private String sm3; + + /** + * 数据类型 + */ + @Schema(description = "数据类型") + private Integer dataType; + + /** + * 过期时间 + */ + @Schema(description = "过期时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] expireTimeRange; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLogPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLogPageReq.java new file mode 100644 index 0000000..26dd1a9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLogPageReq.java @@ -0,0 +1,90 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysLogPageReq

+ *

Description : 日志记录表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysLogPageReq implements Serializable { + + /** + * 日志时间 + */ + @Schema(description = "日志时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] logTimeRange; + + /** + * 日志追踪ID + */ + @Schema(description = "日志追踪ID") + private String traceId; + + /** + * 日志类型 + */ + @Schema(description = "日志类型") + private String logType; + + /** + * 日志级别 + */ + @Schema(description = "日志级别") + private Integer logLevel; + + /** + * 日志标题 + */ + @Schema(description = "日志标题") + private String title; + + /** + * 请求IP + */ + @Schema(description = "请求IP") + private String ip; + + /** + * 请求URI + */ + @Schema(description = "请求URI") + private String uri; + + /** + * 日志线程类型 + */ + @Schema(description = "日志线程类型") + private String threadType; + + /** + * 服务名称 + */ + @Schema(description = "服务名称") + private String appName; + + /** + * 本机IP + */ + @Schema(description = "本机IP") + private String localIp; + + /** + * 运行端口 + */ + @Schema(description = "运行端口") + private String port; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLoginReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLoginReq.java new file mode 100644 index 0000000..e8042a1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysLoginReq.java @@ -0,0 +1,59 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysLoginReq

+ *

Description : SysLoginReq

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 14:04 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysLoginReq implements Serializable { + + /** + * 账号 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "账号", example = "admin") + private String account; + + /** + * 密码 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "密码", example = "123456") + private String passwd; + + /** + * 公钥 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "公钥", example = "abc") + private String publicKey; + + /** + * 验证码 + */ + @Schema(description = "验证码", example = "1234") + private String captcha; + + /** + * Uid + */ + @Schema(description = "uid", example = "abc") + private String uid; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuAddReq.java new file mode 100644 index 0000000..cd0dc2e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuAddReq.java @@ -0,0 +1,137 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysMenuAddReq

+ *

Description : 系统菜单表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysMenuAddReq implements Serializable { + + /** + * 父菜单ID + */ + @Schema(description = "父菜单ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 应用id + */ + @Schema(description = "应用id", example = "1") + private Long appId; + + /** + * 菜单名称 + */ + @Schema(description = "菜单名称", example = "系统管理") + private String menuName; + + /** + * 菜单图标 + */ + @Schema(description = "菜单图标", example = "el-icon-setting") + private String menuIcon; + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型", example = "M") + private String menuType; + + /** + * 显示状态 + */ + @Schema(description = "显示状态", example = "1") + private Integer menuVisible; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 路由名称Vue Router 中用于命名路由 + */ + @Schema(description = "路由名称Vue Router 中用于命名路由", example = "System") + private String routeName; + + /** + * 路由路径Vue Router 中定义的 URL 路径 + */ + @Schema(description = "路由路径Vue Router 中定义的 URL 路径", example = "/system") + private String routePath; + + /** + * 组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue + */ + @Schema(description = "组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue", example = "system/index") + private String component; + + /** + * 按钮权限标识 + */ + @Schema(description = "按钮权限标识", example = "system:add") + private String btnPerm; + + /** + * 接口权限类型 + */ + @Schema(description = "接口权限类型", example = "GET") + private String interfacePermType; + + /** + * 接口权限uri + */ + @Schema(description = "接口权限uri", example = "/api/system/**") + private String interfacePermUri; + + /** + * 目录只有一个子路由是否始终显示 + */ + @Schema(description = "目录只有一个子路由是否始终显示", example = "1") + private Integer alwaysShow; + + /** + * 菜单是否开启页面缓存 + */ + @Schema(description = "菜单是否开启页面缓存", example = "1") + private Integer menuCache; + + /** + * 跳转路径 + */ + @Schema(description = "跳转路径", example = "/system/user") + private String menuRedirect; + + /** + * 路由参数 + */ + @Schema(description = "路由参数", example = "{id: 1}") + private String menuParams; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理菜单") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuPageReq.java new file mode 100644 index 0000000..fcc38b3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuPageReq.java @@ -0,0 +1,156 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysMenuPageReq

+ *

Description : 系统菜单表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysMenuPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 父菜单ID + */ + @Schema(description = "父菜单ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 应用id + */ + @Schema(description = "应用id", example = "1") + private Long appId; + + /** + * 菜单名称 + */ + @Schema(description = "菜单名称", example = "系统管理") + private String menuName; + + /** + * 菜单图标 + */ + @Schema(description = "菜单图标", example = "el-icon-setting") + private String menuIcon; + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型", example = "M") + private String menuType; + + /** + * 显示状态 + */ + @Schema(description = "显示状态", example = "1") + private Integer menuVisible; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 路由名称Vue Router 中用于命名路由 + */ + @Schema(description = "路由名称Vue Router 中用于命名路由", example = "System") + private String routeName; + + /** + * 路由路径Vue Router 中定义的 URL 路径 + */ + @Schema(description = "路由路径Vue Router 中定义的 URL 路径", example = "/system") + private String routePath; + + /** + * 组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue + */ + @Schema(description = "组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue", example = "system/index") + private String component; + + /** + * 按钮权限标识 + */ + @Schema(description = "按钮权限标识", example = "system:add") + private String btnPerm; + + /** + * 接口权限类型 + */ + @Schema(description = "接口权限类型", example = "GET") + private String interfacePermType; + + /** + * 接口权限uri + */ + @Schema(description = "接口权限uri", example = "/api/system/**") + private String interfacePermUri; + + /** + * 目录只有一个子路由是否始终显示 + */ + @Schema(description = "目录只有一个子路由是否始终显示", example = "1") + private Integer alwaysShow; + + /** + * 菜单是否开启页面缓存 + */ + @Schema(description = "菜单是否开启页面缓存", example = "1") + private Integer menuCache; + + /** + * 跳转路径 + */ + @Schema(description = "跳转路径", example = "/system/user") + private String menuRedirect; + + /** + * 路由参数 + */ + @Schema(description = "路由参数", example = "{id: 1}") + private String menuParams; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理菜单") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuTreesReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuTreesReq.java new file mode 100644 index 0000000..40ec548 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuTreesReq.java @@ -0,0 +1,36 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : SysMenuAddReq

+ *

Description : 系统菜单表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysMenuTreesReq implements Serializable { + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型", example = "[\"M\", \"C\", \"F\"]") + private List menuType; + + /** + * 标签添加菜单类型 + */ + @Schema(description = "标签添加菜单类型", example = "true") + private Boolean labelAddMenuType; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuUpdateReq.java new file mode 100644 index 0000000..ccf1c83 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysMenuUpdateReq.java @@ -0,0 +1,143 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysMenuUpdateReq

+ *

Description : 系统菜单表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysMenuUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 父菜单ID + */ + @Schema(description = "父菜单ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 应用id + */ + @Schema(description = "应用id", example = "1") + private Long appId; + + /** + * 菜单名称 + */ + @Schema(description = "菜单名称", example = "系统管理") + private String menuName; + + /** + * 菜单图标 + */ + @Schema(description = "菜单图标", example = "el-icon-setting") + private String menuIcon; + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型", example = "M") + private String menuType; + + /** + * 显示状态 + */ + @Schema(description = "显示状态", example = "1") + private Integer menuVisible; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 路由名称Vue Router 中用于命名路由 + */ + @Schema(description = "路由名称Vue Router 中用于命名路由", example = "System") + private String routeName; + + /** + * 路由路径Vue Router 中定义的 URL 路径 + */ + @Schema(description = "路由路径Vue Router 中定义的 URL 路径", example = "/system") + private String routePath; + + /** + * 组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue + */ + @Schema(description = "组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue", example = "system/index") + private String component; + + /** + * 按钮权限标识 + */ + @Schema(description = "按钮权限标识", example = "system:add") + private String btnPerm; + + /** + * 接口权限类型 + */ + @Schema(description = "接口权限类型", example = "GET") + private String interfacePermType; + + /** + * 接口权限uri + */ + @Schema(description = "接口权限uri", example = "/api/system/**") + private String interfacePermUri; + + /** + * 目录只有一个子路由是否始终显示 + */ + @Schema(description = "目录只有一个子路由是否始终显示", example = "1") + private Integer alwaysShow; + + /** + * 菜单是否开启页面缓存 + */ + @Schema(description = "菜单是否开启页面缓存", example = "1") + private Integer menuCache; + + /** + * 跳转路径 + */ + @Schema(description = "跳转路径", example = "/system/user") + private String menuRedirect; + + /** + * 路由参数 + */ + @Schema(description = "路由参数", example = "{id: 1}") + private String menuParams; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理菜单") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeAddReq.java new file mode 100644 index 0000000..d979c7d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeAddReq.java @@ -0,0 +1,101 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.boot.api.anntation.IgnoreXss; + +import java.io.Serializable; +import java.time.Instant; +import java.util.List; + +/** + *

Title : SysNoticeAddReq

+ *

Description : 系统通知公告表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysNoticeAddReq implements Serializable { + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知内容-markdown格式 + */ + @IgnoreXss + @Schema(description = "通知内容-markdown格式") + private String contentMd; + + /** + * 通知内容-html格式 + */ + @IgnoreXss + @Schema(description = "通知内容-html格式") + private String contentHtml; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 目标类型 + */ + @Schema(description = "目标类型") + private Integer targetType; + + /** + * 发布状态 + */ + @Schema(description = "发布状态") + private Integer publishStatus; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + private Instant publishTime; + + /** + * 撤回时间 + */ + @Schema(description = "撤回时间") + private Instant revokeTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 目标用户集合 + */ + @Schema(description = "目标用户集合") + private List targetUserIds; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticePageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticePageReq.java new file mode 100644 index 0000000..2bde611 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticePageReq.java @@ -0,0 +1,126 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysNoticePageReq

+ *

Description : 系统通知公告表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysNoticePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知内容-markdown格式 + */ + @Schema(description = "通知内容-markdown格式") + private String contentMd; + + /** + * 通知内容-html格式 + */ + @Schema(description = "通知内容-html格式") + private String contentHtml; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 目标类型 + */ + @Schema(description = "目标类型") + private Integer targetType; + + /** + * 发布人ID + */ + @Schema(description = "发布人ID") + private Long publisherId; + + /** + * 发布状态 + */ + @Schema(description = "发布状态") + private Integer publishStatus; + + /** + * 发布时间 + */ + @Schema(description = "发布时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] publishTimeRange; + + /** + * 撤回时间 + */ + @Schema(description = "撤回时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] revokeTimeRange; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + private Long updateBy; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeUpdateReq.java new file mode 100644 index 0000000..3469e6c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysNoticeUpdateReq.java @@ -0,0 +1,107 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.boot.api.anntation.IgnoreXss; + +import java.io.Serializable; +import java.time.Instant; +import java.util.List; + +/** + *

Title : SysNoticeUpdateReq

+ *

Description : 系统通知公告表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysNoticeUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知内容-markdown格式 + */ + @IgnoreXss + @Schema(description = "通知内容-markdown格式") + private String contentMd; + + /** + * 通知内容-html格式 + */ + @IgnoreXss + @Schema(description = "通知内容-html格式") + private String contentHtml; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 目标类型 + */ + @Schema(description = "目标类型") + private Integer targetType; + + /** + * 发布状态 + */ + @Schema(description = "发布状态") + private Integer publishStatus; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + private Instant publishTime; + + /** + * 撤回时间 + */ + @Schema(description = "撤回时间") + private Instant revokeTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 目标用户集合 + */ + @Schema(description = "目标用户集合") + private List targetUserIds; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysParamPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysParamPageReq.java new file mode 100644 index 0000000..e0b7061 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysParamPageReq.java @@ -0,0 +1,78 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysParamPageReq

+ *

Description : 系统参数表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysParamPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统参数key + */ + @Schema(description = "系统参数key") + private String paramKey; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 参数值类型 + */ + @Schema(description = "参数值类型") + private Integer dataType; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskAddReq.java new file mode 100644 index 0000000..087c5da --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskAddReq.java @@ -0,0 +1,48 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysRiskAddReq

+ *

Description : 系统风控表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRiskAddReq implements Serializable { + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private String sysType; + + /** + * 风控类型 + */ + @Schema(description = "风控类型") + private Integer type; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskPageReq.java new file mode 100644 index 0000000..89e05ec --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskPageReq.java @@ -0,0 +1,78 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysRiskPageReq

+ *

Description : 系统风控表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRiskPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private String sysType; + + /** + * 风控类型 + */ + @Schema(description = "风控类型") + private Integer type; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskUpdateReq.java new file mode 100644 index 0000000..43be91d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRiskUpdateReq.java @@ -0,0 +1,54 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysRiskUpdateReq

+ *

Description : 系统风控表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRiskUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private String sysType; + + /** + * 风控类型 + */ + @Schema(description = "风控类型") + private Integer type; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleAddReq.java new file mode 100644 index 0000000..85f3eef --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleAddReq.java @@ -0,0 +1,72 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysRoleAddReq

+ *

Description : 系统角色表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRoleAddReq implements Serializable { + + /** + * 角色名称 + */ + @Schema(description = "角色名称", example = "管理员") + private String name; + + /** + * 角色编码 + */ + @Schema(description = "角色编码", example = "ADMIN") + private String code; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 角色状态 + */ + @Schema(description = "角色状态", example = "1") + private Integer status; + + /** + * 数据权限 + */ + @Schema(description = "数据权限", example = "1") + private Integer dataScope; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 更新人 ID + */ + @Schema(description = "更新人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员角色") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleMenuReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleMenuReq.java new file mode 100644 index 0000000..4a28e98 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleMenuReq.java @@ -0,0 +1,40 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : SysRoleMenuReq

+ *

Description : 角色菜单关联表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRoleMenuReq implements Serializable { + + /** + * 角色 ID + */ + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @Schema(description = "角色 ID", example = "1") + private Long roleId; + + /** + * 菜单 ID 集合 + */ + @Schema(description = "菜单 ID 集合", example = "1,2,3") + private List menuIds; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRolePageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRolePageReq.java new file mode 100644 index 0000000..0b76331 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRolePageReq.java @@ -0,0 +1,90 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysRolePageReq

+ *

Description : 系统角色表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRolePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 角色名称 + */ + @Schema(description = "角色名称", example = "管理员") + private String name; + + /** + * 角色编码 + */ + @Schema(description = "角色编码", example = "ADMIN") + private String code; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 角色状态 + */ + @Schema(description = "角色状态", example = "1") + private Integer status; + + /** + * 数据权限 + */ + @Schema(description = "数据权限", example = "1") + private Integer dataScope; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 更新人 ID + */ + @Schema(description = "更新人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员角色") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleUpdateReq.java new file mode 100644 index 0000000..3836ea5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysRoleUpdateReq.java @@ -0,0 +1,77 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysRoleUpdateReq

+ *

Description : 系统角色表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysRoleUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 角色名称 + */ + @Schema(description = "角色名称", example = "管理员") + private String name; + + /** + * 角色编码 + */ + @Schema(description = "角色编码", example = "ADMIN") + private String code; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + /** + * 角色状态 + */ + @Schema(description = "角色状态", example = "1") + private Integer status; + + /** + * 数据权限 + */ + @Schema(description = "数据权限", example = "1") + private Integer dataScope; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 更新人 ID + */ + @Schema(description = "更新人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员角色") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysTaskPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysTaskPageReq.java new file mode 100644 index 0000000..83178a8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysTaskPageReq.java @@ -0,0 +1,90 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysTaskPageReq

+ *

Description : 系统任务分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysTaskPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 日志追踪 ID + */ + @Schema(description = "日志追踪 ID") + private String traceId; + + /** + * code + */ + @Schema(description = "code") + private String code; + + /** + * 任务类型 + */ + @Schema(description = "任务类型") + private String type; + + /** + * 状态 + */ + @Schema(description = "状态") + private Integer status; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 开始时间 + */ + @Schema(description = "开始时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] startTimeRange; + + /** + * 结束时间 + */ + @Schema(description = "结束时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] endTimeRange; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryAddReq.java new file mode 100644 index 0000000..ca7a6c6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryAddReq.java @@ -0,0 +1,53 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysUpdateHistoryAddReq

+ *

Description : 系统更新历史添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUpdateHistoryAddReq implements Serializable { + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private Integer type; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + private String version; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryPageReq.java new file mode 100644 index 0000000..f06bb9f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryPageReq.java @@ -0,0 +1,72 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUpdateHistoryPageReq

+ *

Description : 系统更新历史分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUpdateHistoryPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private Integer type; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + private String version; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryUpdateReq.java new file mode 100644 index 0000000..6bdb108 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUpdateHistoryUpdateReq.java @@ -0,0 +1,59 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysUpdateHistoryUpdateReq

+ *

Description : 系统更新历史更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUpdateHistoryUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private Integer type; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + private String version; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserAddReq.java new file mode 100644 index 0000000..93c071c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserAddReq.java @@ -0,0 +1,95 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysUserAddReq

+ *

Description : 系统用户表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserAddReq implements Serializable { + + /** + * 部门ID + */ + @Schema(description = "部门ID", example = "1") + private Long deptId; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "admin") + private String account; + + /** + * 昵称 + */ + @Schema(description = "昵称", example = "管理员") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像", example = "https://example.com/avatar.jpg") + private String avatar; + + /** + * 手机号 + */ + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + /** + * 用户邮箱 + */ + @Schema(description = "用户邮箱", example = "admin@example.com") + private String email; + + /** + * 性别 + */ + @Schema(description = "性别", example = "1") + private Integer sex; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员账户") + private String memo; + + /** + * 角色ID集合 + */ + @Schema(description = "角色ID集合", example = "[1, 2]") + private Long[] roleIds; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeAddReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeAddReq.java new file mode 100644 index 0000000..4bf5836 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeAddReq.java @@ -0,0 +1,61 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserNoticeAddReq

+ *

Description : 系统用户通知公告表添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserNoticeAddReq implements Serializable { + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + private Long noticeId; + + /** + * 用户ID + */ + @Schema(description = "用户ID") + private Long userId; + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 阅读时间 + */ + @Schema(description = "阅读时间") + private Instant readTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeInfoPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeInfoPageReq.java new file mode 100644 index 0000000..bd13fb5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeInfoPageReq.java @@ -0,0 +1,61 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserNoticeInfoPageReq

+ *

Description : 系统用户通知公告信息表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserNoticeInfoPageReq implements Serializable { + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 发布人ID + */ + @Schema(description = "发布人ID") + private Long publisherId; + + /** + * 发布时间 + */ + @Schema(description = "发布时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] publishTimeRange; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticePageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticePageReq.java new file mode 100644 index 0000000..c0bf11d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticePageReq.java @@ -0,0 +1,90 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserNoticePageReq

+ *

Description : 系统用户通知公告表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserNoticePageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + private Long noticeId; + + /** + * 用户ID + */ + @Schema(description = "用户ID") + private Long userId; + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 阅读时间 + */ + @Schema(description = "阅读时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] readTimeRange; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; + + /** + * 标题 + */ + @Schema(description = "标题") + private String title; + + /** + * 昵称 + */ + @Schema(description = "昵称") + private String nickname; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeUpdateReq.java new file mode 100644 index 0000000..09ad987 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserNoticeUpdateReq.java @@ -0,0 +1,67 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserNoticeUpdateReq

+ *

Description : 系统用户通知公告表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserNoticeUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + private Long noticeId; + + /** + * 用户ID + */ + @Schema(description = "用户ID") + private Long userId; + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 阅读时间 + */ + @Schema(description = "阅读时间") + private Instant readTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserPageReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserPageReq.java new file mode 100644 index 0000000..f6a0ec4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserPageReq.java @@ -0,0 +1,114 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserPageReq

+ *

Description : 系统用户表分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 部门ID + */ + @Schema(description = "部门ID", example = "1") + private Long deptId; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "admin") + private String account; + + /** + * 昵称 + */ + @Schema(description = "昵称", example = "管理员") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像", example = "https://example.com/avatar.jpg") + private String avatar; + + /** + * 手机号 + */ + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + /** + * 用户邮箱 + */ + @Schema(description = "用户邮箱", example = "admin@example.com") + private String email; + + /** + * 性别 + */ + @Schema(description = "性别", example = "1") + private Integer sex; + + /** + * 密码 + */ + @Schema(description = "密码", example = "123456") + private String passwd; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员账户") + private String memo; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserUpdateReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserUpdateReq.java new file mode 100644 index 0000000..154f323 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/SysUserUpdateReq.java @@ -0,0 +1,101 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysUserUpdateReq

+ *

Description : 系统用户表更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 部门ID + */ + @Schema(description = "部门ID", example = "1") + private Long deptId; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "admin") + private String account; + + /** + * 昵称 + */ + @Schema(description = "昵称", example = "管理员") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像", example = "https://example.com/avatar.jpg") + private String avatar; + + /** + * 手机号 + */ + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + /** + * 用户邮箱 + */ + @Schema(description = "用户邮箱", example = "admin@example.com") + private String email; + + /** + * 性别 + */ + @Schema(description = "性别", example = "1") + private Integer sex; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员账户") + private String memo; + + /** + * 角色ID集合 + */ + @Schema(description = "角色ID集合", example = "[1, 2]") + private Long[] roleIds; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoEditReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoEditReq.java new file mode 100644 index 0000000..e829cc6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoEditReq.java @@ -0,0 +1,68 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : UserInfoEditReq

+ *

Description : UserInfoEditReq

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserInfoEditReq implements Serializable { + + /** + * ID + */ + @Schema(description = "ID", example = "1") + private Long id; + + /** + * 昵称 + */ + @Size(min = 2, message = "长度不能小于2") + @NotEmpty(message = "不能为空") + @Schema(description = "昵称", example = "管理员") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像", example = "base64格式") + private String avatar; + + /** + * 手机号 + */ + @Size(max = 11, min = 11, message = "长度为11") + @NotEmpty(message = "不能为空") + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + /** + * 用户邮箱 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "用户邮箱", example = "admin@example.com") + private String email; + + /** + * 性别 + */ + @NotNull(message = "不能为空") + @Schema(description = "性别", example = "1") + private Integer sex; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoPasswdEditReq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoPasswdEditReq.java new file mode 100644 index 0000000..48af65c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/req/UserInfoPasswdEditReq.java @@ -0,0 +1,55 @@ +package xtools.app.sys.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : UserInfoPasswdEditReq

+ *

Description : UserInfoPasswdEditReq

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserInfoPasswdEditReq implements Serializable { + + /** + * Uid + */ + @Schema(description = "uid", example = "abc") + private String uid; + + /** + * 公钥 + */ + @NotEmpty(message = "不能为空") + @Schema(description = "公钥", example = "abc") + private String publicKey; + + /** + * 原密码 + */ + @Size(min = 6, message = "长度不能小于6") + @NotEmpty(message = "不能为空") + @Schema(description = "密码", example = "123456") + private String oldPasswd; + + /** + * 密码 + */ + @Size(min = 6, message = "长度不能小于6") + @NotEmpty(message = "不能为空") + @Schema(description = "密码", example = "123456") + private String passwd; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysBaseUserInfoResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysBaseUserInfoResp.java new file mode 100644 index 0000000..6d7b127 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysBaseUserInfoResp.java @@ -0,0 +1,50 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : SysBaseUserInfoResp

+ *

Description : SysBaseUserInfoResp

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/30 10:09 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysBaseUserInfoResp implements Serializable { + + /** + * 用户信息 + */ + @Schema(description = "用户信息") + private SysUserResp sysUser; + + /** + * 菜单树 + */ + @Schema(description = "菜单树") + private List menuTree; + + /** + * 路由列表 + */ + @Schema(description = "路由列表") + private List routeList; + + /** + * 按钮权限 + */ + @Schema(description = "按钮权限") + private List btnPerms; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptResp.java new file mode 100644 index 0000000..326c84f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptResp.java @@ -0,0 +1,94 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDeptResp

+ *

Description : 部门管理表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysDeptResp extends BaseEntity { + + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + + /** + * 部门编号 + */ + @Schema(description = "部门编号", example = "DEPT001") + private String deptCode; + + + /** + * 部门名称 + */ + @Schema(description = "部门名称", example = "研发部") + private String deptName; + + + /** + * 父节点 ID + */ + @Schema(description = "父节点 ID", example = "1") + private Long parentId; + + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + + /** + * 备注 + */ + @Schema(description = "备注", example = "部门描述信息") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptTreeResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptTreeResp.java new file mode 100644 index 0000000..3e459a6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDeptTreeResp.java @@ -0,0 +1,33 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

Title : SysDeptTreeResp

+ *

Description : SysDeptTreeResp

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/28 15:39 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysDeptTreeResp extends SysDeptResp { + + /** + * 子部门 + */ + @Schema(description = "子部门", example = "[{\"id\": 2, \"deptName\": \"前端组\"}, {\"id\": 3, \"deptName\": \"后端组\"}]") + private List children; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDictResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDictResp.java new file mode 100644 index 0000000..26f957f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysDictResp.java @@ -0,0 +1,73 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDictResp

+ *

Description : 数据字典类型表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysDictResp extends BaseEntity { + + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + + /** + * 字典编码 + */ + @Schema(description = "字典编码", example = "USER_STATUS") + private String dictCode; + + + /** + * 字典名称 + */ + @Schema(description = "字典名称", example = "用户状态") + private String dictName; + + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + + /** + * 备注 + */ + @Schema(description = "备注", example = "用户状态字典") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysHomeDataResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysHomeDataResp.java new file mode 100644 index 0000000..071cfe1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysHomeDataResp.java @@ -0,0 +1,45 @@ +package xtools.app.sys.model.dto.resp; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import xtools.core.dto.SysBaseInfoDto; + +import java.io.Serializable; + +/** + *

Title : SysHomeDataResp

+ *

Description : SysHomeDataResp

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 19:53 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysHomeDataResp implements Serializable { + + /** + * jvm系统信息 + */ + private SysBaseInfoDto jvm; + + /** + * ip + */ + private String ip; + + /** + * 地址 + */ + private String address; + + /** + * 天气信息 + */ + private String weather; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysIpAddrResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysIpAddrResp.java new file mode 100644 index 0000000..5e78d1a --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysIpAddrResp.java @@ -0,0 +1,49 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysIpAddrResp

+ *

Description : SysIpAddrResp

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/25 11:17 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysIpAddrResp implements Serializable { + + /** + * 国家 + */ + @Schema(description = "国家", example = "中国") + private String country; + + /** + * 省份 + */ + @Schema(description = "省份", example = "广东省") + private String province; + + /** + * 城市 + */ + @Schema(description = "城市", example = "深圳市") + private String city; + + /** + * 网络提供商 + */ + @Schema(description = "网络提供商", example = "阿里云") + private String isp; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysLogResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysLogResp.java new file mode 100644 index 0000000..f929d64 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysLogResp.java @@ -0,0 +1,138 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysLogResp

+ *

Description : 日志记录表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysLogResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 日志ID + */ + @Schema(description = "日志ID") + private String logId; + + /** + * 日志追踪ID + */ + @Schema(description = "日志追踪ID") + private String traceId; + + /** + * 日志父ID + */ + @Schema(description = "日志父ID") + private String parentId; + + /** + * 日志线程类型 + */ + @Schema(description = "日志线程类型") + private String threadType; + + /** + * 日志时间 + */ + @Schema(description = "日志时间") + private Long logTime; + + /** + * 日志获取索引 + */ + @Schema(description = "日志获取索引") + private Integer logIndex; + + /** + * 日志级别 + */ + @Schema(description = "日志级别") + private Integer logLevel; + + /** + * 服务名称 + */ + @Schema(description = "服务名称") + private String appName; + + /** + * 本机IP + */ + @Schema(description = "本机IP") + private String localIp; + + /** + * 运行端口 + */ + @Schema(description = "运行端口") + private String port; + + /** + * 日志标题 + */ + @Schema(description = "日志标题") + private String title; + + /** + * 日志类型 + */ + @Schema(description = "日志类型") + private String logType; + + /** + * 请求IP + */ + @Schema(description = "请求IP") + private String ip; + + /** + * 请求URI + */ + @Schema(description = "请求URI") + private String uri; + + /** + * 日志内容 + */ + @Schema(description = "日志内容") + private String logBody; + + /** + * 堆栈信息 + */ + @Schema(description = "堆栈信息") + private String stackTrace; + + /** + * 日志错误信息 + */ + @Schema(description = "日志错误信息") + private String logError; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuResp.java new file mode 100644 index 0000000..6c95c9f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuResp.java @@ -0,0 +1,144 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysMenuResp

+ *

Description : 系统菜单表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysMenuResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 父菜单ID + */ + @Schema(description = "父菜单ID", example = "1") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径", example = "0,1") + private String treePath; + + /** + * 应用id + */ + @Schema(description = "应用id", example = "1") + private Long appId; + + /** + * 菜单名称 + */ + @Schema(description = "菜单名称", example = "系统管理") + private String menuName; + + /** + * 菜单图标 + */ + @Schema(description = "菜单图标", example = "el-icon-setting") + private String menuIcon; + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型", example = "M") + private String menuType; + + /** + * 显示状态 + */ + @Schema(description = "显示状态", example = "1") + private Integer menuVisible; + + /** + * 排序 + */ + @Schema(description = "排序", example = "1") + private Integer sort; + + /** + * 路由名称Vue Router 中用于命名路由 + */ + @Schema(description = "路由名称Vue Router 中用于命名路由", example = "System") + private String routeName; + + /** + * 路由路径Vue Router 中定义的 URL 路径 + */ + @Schema(description = "路由路径Vue Router 中定义的 URL 路径", example = "/system") + private String routePath; + + /** + * 组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue + */ + @Schema(description = "组件路径组件页面完整路径,相对于 src/view/,缺省后缀 .vue", example = "system/index") + private String component; + + /** + * 按钮权限标识 + */ + @Schema(description = "按钮权限标识", example = "system:add") + private String btnPerm; + + /** + * 接口权限类型 + */ + @Schema(description = "接口权限类型", example = "GET") + private String interfacePermType; + + /** + * 接口权限uri + */ + @Schema(description = "接口权限uri", example = "/api/system/**") + private String interfacePermUri; + + /** + * 目录只有一个子路由是否始终显示 + */ + @Schema(description = "目录只有一个子路由是否始终显示", example = "1") + private Integer alwaysShow; + + /** + * 菜单是否开启页面缓存 + */ + @Schema(description = "菜单是否开启页面缓存", example = "1") + private Integer menuCache; + + /** + * 跳转路径 + */ + @Schema(description = "跳转路径", example = "/system/user") + private String menuRedirect; + + /** + * 路由参数 + */ + @Schema(description = "路由参数", example = "{id: 1}") + private String menuParams; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理菜单") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuTreeResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuTreeResp.java new file mode 100644 index 0000000..9d468ef --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysMenuTreeResp.java @@ -0,0 +1,33 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + *

Title : SysMenuTreeResp

+ *

Description : SysMenuTreeResp

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/28 22:28 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysMenuTreeResp extends SysMenuResp { + + /** + * 子菜单 + */ + @Schema(description = "子菜单", example = "[{\"id\": 2, \"menuName\": \"用户管理\"}, {\"id\": 3, \"menuName\": \"角色管理\"}]") + private List children; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysNoticeResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysNoticeResp.java new file mode 100644 index 0000000..9476bae --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysNoticeResp.java @@ -0,0 +1,128 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; +import java.util.List; + +/** + *

Title : SysNoticeResp

+ *

Description : 系统通知公告表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysNoticeResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知内容-markdown格式 + */ + @Schema(description = "通知内容-markdown格式") + private String contentMd; + + /** + * 通知内容-html格式 + */ + @Schema(description = "通知内容-html格式") + private String contentHtml; + + /** + * 通知类型 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 目标类型 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "目标类型") + private Integer targetType; + + /** + * 发布人 + */ + @Schema(description = "发布人") + private String publisher; + + /** + * 发布状态 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "发布状态") + private Integer publishStatus; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + private Instant publishTime; + + /** + * 撤回时间 + */ + @Schema(description = "撤回时间") + private Instant revokeTime; + + /** + * 创建人ID + */ + @Schema(description = "创建人") + private String createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人") + private String updateBy; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 目标用户集合 + */ + @Schema(description = "目标用户集合") + private List targetUserIds; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysParamResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysParamResp.java new file mode 100644 index 0000000..d1b87bd --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysParamResp.java @@ -0,0 +1,69 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysParamResp

+ *

Description : 系统参数表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysParamResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统参数key + */ + @Schema(description = "系统参数key") + private String paramKey; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + private String data; + + /** + * 参数值类型 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "参数值类型") + private Integer dataType; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysRoleResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysRoleResp.java new file mode 100644 index 0000000..b876720 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysRoleResp.java @@ -0,0 +1,89 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysRoleResp

+ *

Description : 系统角色表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysRoleResp extends BaseEntity { + + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + + /** + * 角色名称 + */ + @Schema(description = "角色名称", example = "管理员") + private String name; + + + /** + * 角色编码 + */ + @Schema(description = "角色编码", example = "ADMIN") + private String code; + + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序", example = "1") + private Integer sort; + + + /** + * 角色状态 + */ + @Schema(description = "角色状态", example = "1") + private Integer status; + + + /** + * 数据权限 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "数据权限", example = "1") + private Integer dataScope; + + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + + /** + * 更新人 ID + */ + @Schema(description = "更新人 ID", example = "1") + private Long updateBy; + + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员角色") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysTaskResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysTaskResp.java new file mode 100644 index 0000000..d53a963 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysTaskResp.java @@ -0,0 +1,80 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysTaskResp

+ *

Description : 系统任务响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysTaskResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 日志追踪 ID + */ + @Schema(description = "日志追踪 ID") + private String traceId; + + /** + * code + */ + @Schema(description = "code") + private String code; + + /** + * 任务类型 + */ + @Schema(description = "任务类型") + private String type; + + /** + * 状态 + */ + @Schema(description = "状态") + private Integer status; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 开始时间 + */ + @Schema(description = "开始时间") + private Instant startTime; + + /** + * 结束时间 + */ + @Schema(description = "结束时间") + private Instant endTime; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUpdateHistoryResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUpdateHistoryResp.java new file mode 100644 index 0000000..f5f2cb9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUpdateHistoryResp.java @@ -0,0 +1,60 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysUpdateHistoryResp

+ *

Description : 系统更新历史响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysUpdateHistoryResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + private Integer type; + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + private String version; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeInfoResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeInfoResp.java new file mode 100644 index 0000000..8123463 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeInfoResp.java @@ -0,0 +1,70 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysUserNoticeInfoResp

+ *

Description : 系统用户通知公告信息表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysUserNoticeInfoResp implements Serializable { + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + private Long id; + + /** + * 读取状态 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + private String title; + + /** + * 通知类型 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "通知类型") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + private String level; + + /** + * 发布人ID + */ + @Schema(description = "发布人") + private String publisher; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + private Instant publishTime; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeResp.java new file mode 100644 index 0000000..2114ad0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserNoticeResp.java @@ -0,0 +1,82 @@ +package xtools.app.sys.model.dto.resp; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysUserNoticeResp

+ *

Description : 系统用户通知公告表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysUserNoticeResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + private Long noticeId; + + /** + * 用户ID + */ + @Schema(description = "用户ID") + private Long userId; + + /** + * 读取状态 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(description = "读取状态") + private Integer noticeRead; + + /** + * 阅读时间 + */ + @Schema(description = "阅读时间") + private Instant readTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + private String memo; + + /** + * 标题 + */ + @Schema(description = "标题") + private String title; + + /** + * 昵称 + */ + @Schema(description = "昵称") + private String nickname; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserResp.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserResp.java new file mode 100644 index 0000000..29c2fdd --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/dto/resp/SysUserResp.java @@ -0,0 +1,123 @@ +package xtools.app.sys.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; +import xtools.boot.mask.anntation.Mask; +import xtools.boot.mask.enums.MaskType; + +import java.util.List; + +/** + *

Title : SysUserResp

+ *

Description : 系统用户表响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysUserResp extends BaseEntity { + + + /** + * 主键 ID + */ + @Schema(description = "主键 ID", example = "1") + private Long id; + + /** + * 部门 ID + */ + @Schema(description = "部门 ID", example = "1") + private Long deptId; + + /** + * 用户名 + */ + @Schema(description = "用户名", example = "admin") + @Mask(value = MaskType.CUSTOM, prefixNoMaskLen = 1, suffixNoMaskLen = 1) + private String account; + + /** + * 昵称 + */ + @Schema(description = "昵称", example = "管理员") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像", example = "https://example.com/avatar.jpg") + private String avatar; + + /** + * 手机号 + */ + @Schema(description = "手机号", example = "13800138000") + @Mask(value = MaskType.MOBILE_PHONE, always = true) + private String mobile; + + /** + * 用户邮箱 + */ + @Schema(description = "用户邮箱", example = "admin@example.com") + @Mask(MaskType.EMAIL) + private String email; + + /** + * 性别 + */ + @Schema(description = "性别", example = "1") + private Integer sex; + + /** + * 密码 + */ + @Schema(description = "密码", example = "******") + @Mask(MaskType.PASSWORD) + private String passwd; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID", example = "1") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID", example = "1") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注", example = "系统管理员账户") + private String memo; + + /** + * 部门名称 + */ + @Schema(description = "部门名称", example = "研发部") + private String deptName; + + /** + * 角色 ID 列表 + */ + @Schema(description = "角色ID列表", example = "[1, 2]") + private List roleIds; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysAddress.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysAddress.java new file mode 100644 index 0000000..0455027 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysAddress.java @@ -0,0 +1,86 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysAddress

+ *

Description : 公用地址表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_address") +public class SysAddress extends BaseEntity { + + /** + * 公用地址-ID + */ + @Schema(description = "公用地址-ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 公用地址-父ID + */ + @Schema(description = "公用地址-父ID") + @TableField(value = "parent_id") + private Long parentId; + + /** + * 公用地址-唯一编码 + */ + @Schema(description = "公用地址-唯一编码") + @TableField(value = "code") + private String code; + + /** + * 公用地址-类型 + */ + @Schema(description = "公用地址-类型") + @TableField(value = "type") + private Integer type; + + /** + * 公用地址-名称 + */ + @Schema(description = "公用地址-名称") + @TableField(value = "title") + private String title; + + /** + * 公用地址-经度 + */ + @Schema(description = "公用地址-经度") + @TableField(value = "lng") + private String lng; + + /** + * 公用地址-纬度 + */ + @Schema(description = "公用地址-纬度") + @TableField(value = "lat") + private String lat; + + /** + * 公用地址-备注 + */ + @Schema(description = "公用地址-备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDept.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDept.java new file mode 100644 index 0000000..c37588d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDept.java @@ -0,0 +1,99 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDept

+ *

Description : 部门管理表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_dept") +public class SysDept extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 部门编号 + */ + @Schema(description = "部门编号") + @TableField(value = "dept_code") + private String deptCode; + + /** + * 部门名称 + */ + @Schema(description = "部门名称") + @TableField(value = "dept_name") + private String deptName; + + /** + * 父节点 ID + */ + @Schema(description = "父节点 ID") + @TableField(value = "parent_id") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径") + @TableField(value = "tree_path") + private String treePath; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序") + @TableField(value = "sort") + private Integer sort; + + /** + * 状态 + */ + @Schema(description = "状态") + @TableField(value = "status") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDict.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDict.java new file mode 100644 index 0000000..c923d7f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDict.java @@ -0,0 +1,78 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDict

+ *

Description : 数据字典类型表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_dict") +public class SysDict extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 字典编码 + */ + @Schema(description = "字典编码") + @TableField(value = "dict_code") + private String dictCode; + + /** + * 字典名称 + */ + @Schema(description = "字典名称") + @TableField(value = "dict_name") + private String dictName; + + /** + * 状态 + */ + @Schema(description = "状态") + @TableField(value = "status") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDictItem.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDictItem.java new file mode 100644 index 0000000..3d9bb45 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysDictItem.java @@ -0,0 +1,99 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysDictItem

+ *

Description : 数据字典项表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_dict_item") +public class SysDictItem extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 关联字典编码,与sys_dict表中的dict_code对应 + */ + @Schema(description = "关联字典编码,与sys_dict表中的dict_code对应") + @TableField(value = "dict_code") + private String dictCode; + + /** + * 字典项值 + */ + @Schema(description = "字典项值") + @TableField(value = "value") + private String value; + + /** + * 字典项标签 + */ + @Schema(description = "字典项标签") + @TableField(value = "label") + private String label; + + /** + * 标签类型,用于前端样式展示(如success,warning等) + */ + @Schema(description = "标签类型,用于前端样式展示(如success,warning等)") + @TableField(value = "tag_type") + private String tagType; + + /** + * 状态 + */ + @Schema(description = "状态") + @TableField(value = "status") + private Integer status; + + /** + * 排序 + */ + @Schema(description = "排序") + @TableField(value = "sort") + private Integer sort; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 修改人ID + */ + @Schema(description = "修改人ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysFile.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysFile.java new file mode 100644 index 0000000..abd97c7 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysFile.java @@ -0,0 +1,158 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysFile

+ *

Description : 系统文件表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_file") +public class SysFile extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户id + */ + @Schema(description = "用户id") + @TableField(value = "user_id") + private Long userId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + @TableField(value = "user_name") + private String userName; + + /** + * 业务id + */ + @Schema(description = "业务id") + @TableField(value = "biz_id") + private Long bizId; + + /** + * 业务类型 + */ + @Schema(description = "业务类型") + @TableField(value = "biz_type") + private String bizType; + + /** + * 权限 + */ + @Schema(description = "权限") + @TableField(value = "permission") + private Integer permission; + + /** + * 桶名称 + */ + @Schema(description = "桶名称") + @TableField(value = "bucket") + private String bucket; + + /** + * 桶类型 + */ + @Schema(description = "桶类型") + @TableField(value = "storage_type") + private String storageType; + + /** + * 文件上传时间 + */ + @Schema(description = "文件上传时间") + @TableField(value = "upload_time") + private Instant uploadTime; + + /** + * 文件路径 + */ + @Schema(description = "文件路径") + @TableField(value = "file_path") + private String filePath; + + /** + * 文件名 + */ + @Schema(description = "文件名") + @TableField(value = "file_name") + private String fileName; + + /** + * 文件大小 + */ + @Schema(description = "文件大小") + @TableField(value = "file_size") + private Long fileSize; + + /** + * 文件类型 + */ + @Schema(description = "文件类型") + @TableField(value = "file_type") + private String fileType; + + /** + * MD5值 + */ + @Schema(description = "MD5值") + @TableField(value = "md5") + private String md5; + + /** + * SM3值 + */ + @Schema(description = "SM3值") + @TableField(value = "sm3") + private String sm3; + + /** + * 数据类型 + */ + @Schema(description = "数据类型") + @TableField(value = "data_type") + private Integer dataType; + + /** + * 过期时间 + */ + @Schema(description = "过期时间") + @TableField(value = "expire_time") + private Instant expireTime; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysInterfacePerm.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysInterfacePerm.java new file mode 100644 index 0000000..4a8859e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysInterfacePerm.java @@ -0,0 +1,34 @@ +package xtools.app.sys.model.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysInterfacePerm

+ *

Description : SysInterfacePerm

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 14:08 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysInterfacePerm implements Serializable { + + @Schema(description = "接口地址", example = "/api/v1/sys/user/info") + private String uri; + + @Schema(description = "接口类型", example = "GET") + private String type; + + @Schema(description = "角色 ID 集合") + private String roleIds; +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysLog.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysLog.java new file mode 100644 index 0000000..0731b10 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysLog.java @@ -0,0 +1,162 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysLog

+ *

Description : 日志记录表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_log") +public class SysLog extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 日志ID + */ + @Schema(description = "日志ID") + @TableField(value = "log_id") + private String logId; + + /** + * 日志追踪ID + */ + @Schema(description = "日志追踪ID") + @TableField(value = "trace_id") + private String traceId; + + /** + * 日志父ID + */ + @Schema(description = "日志父ID") + @TableField(value = "parent_id") + private String parentId; + + /** + * 日志线程类型 + */ + @Schema(description = "日志线程类型") + @TableField(value = "thread_type") + private String threadType; + + /** + * 日志时间 + */ + @Schema(description = "日志时间") + @TableField(value = "log_time") + private Long logTime; + + /** + * 日志获取索引 + */ + @Schema(description = "日志获取索引") + @TableField(value = "log_index") + private Integer logIndex; + + /** + * 服务名称 + */ + @Schema(description = "服务名称") + @TableField(value = "app_name") + private String appName; + + /** + * 本机IP + */ + @Schema(description = "本机IP") + @TableField(value = "local_ip") + private String localIp; + + /** + * 运行端口 + */ + @Schema(description = "运行端口") + @TableField(value = "port") + private String port; + + /** + * 日志标题 + */ + @Schema(description = "日志标题") + @TableField(value = "title") + private String title; + + /** + * 日志级别 + */ + @Schema(description = "日志级别") + @TableField(value = "log_level") + private Integer logLevel; + + /** + * 日志类型 + */ + @Schema(description = "日志类型") + @TableField(value = "log_type") + private String logType; + + /** + * 请求IP + */ + @Schema(description = "请求IP") + @TableField(value = "ip") + private String ip; + + /** + * 请求URI + */ + @Schema(description = "请求URI") + @TableField(value = "uri") + private String uri; + + /** + * 日志内容 + */ + @Schema(description = "日志内容") + @TableField(value = "log_body") + private String logBody; + + /** + * 堆栈信息 + */ + @Schema(description = "堆栈信息") + @TableField(value = "stack_trace") + private String stackTrace; + + /** + * 日志错误信息 + */ + @Schema(description = "日志错误信息") + @TableField(value = "log_error") + private String logError; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysMenu.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysMenu.java new file mode 100644 index 0000000..54a2b99 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysMenu.java @@ -0,0 +1,169 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysMenu

+ *

Description : 系统菜单表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-02 16:23:11 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_menu") +public class SysMenu extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 父菜单ID + */ + @Schema(description = "父菜单ID") + @TableField(value = "parent_id") + private Long parentId; + + /** + * 父节点 ID 路径 + */ + @Schema(description = "父节点 ID 路径") + @TableField(value = "tree_path") + private String treePath; + + /** + * 应用id + */ + @Schema(description = "应用id") + @TableField(value = "app_id") + private Long appId; + + /** + * 菜单名称 + */ + @Schema(description = "菜单名称") + @TableField(value = "menu_name") + private String menuName; + + /** + * 菜单图标 + */ + @Schema(description = "菜单图标") + @TableField(value = "menu_icon") + private String menuIcon; + + /** + * 菜单类型 + */ + @Schema(description = "菜单类型") + @TableField(value = "menu_type") + private String menuType; + + /** + * 显示状态 + */ + @Schema(description = "显示状态") + @TableField(value = "menu_visible") + private Integer menuVisible; + + /** + * 排序 + */ + @Schema(description = "排序") + @TableField(value = "sort") + private Integer sort; + + /** + * 路由名称Vue Router 中用于命名路由 + */ + @Schema(description = "路由名称Vue Router 中用于命名路由") + @TableField(value = "route_name") + private String routeName; + + /** + * 路由路径Vue Router 中定义的 URL 路径 + */ + @Schema(description = "路由路径Vue Router 中定义的 URL 路径") + @TableField(value = "route_path") + private String routePath; + + /** + * 组件路径组件页面完整路径,相对于 src/views/,缺省后缀 .vue + */ + @Schema(description = "组件路径组件页面完整路径,相对于 src/views/,缺省后缀 .vue") + @TableField(value = "component") + private String component; + + /** + * 按钮权限标识 + */ + @Schema(description = "按钮权限标识") + @TableField(value = "btn_perm") + private String btnPerm; + + /** + * 接口权限类型 + */ + @Schema(description = "接口权限类型") + @TableField(value = "interface_perm_type") + private String interfacePermType; + + /** + * 接口权限uri + */ + @Schema(description = "接口权限uri") + @TableField(value = "interface_perm_uri") + private String interfacePermUri; + + /** + * 目录只有一个子路由是否始终显示 + */ + @Schema(description = "目录只有一个子路由是否始终显示") + @TableField(value = "always_show") + private Integer alwaysShow; + + /** + * 菜单是否开启页面缓存 + */ + @Schema(description = "菜单是否开启页面缓存") + @TableField(value = "menu_cache") + private Integer menuCache; + + /** + * 跳转路径 + */ + @Schema(description = "跳转路径") + @TableField(value = "menu_redirect") + private String menuRedirect; + + /** + * 路由参数 + */ + @Schema(description = "路由参数") + @TableField(value = "menu_params") + private String menuParams; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysNotice.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysNotice.java new file mode 100644 index 0000000..ff8c369 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysNotice.java @@ -0,0 +1,137 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysNotice

+ *

Description : 系统通知公告表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_notice") +public class SysNotice extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + @TableField(value = "title") + private String title; + + /** + * 通知内容-markdown格式 + */ + @Schema(description = "通知内容-markdown格式") + @TableField(value = "content_md") + private String contentMd; + + /** + * 通知内容-html格式 + */ + @Schema(description = "通知内容-html格式") + @TableField(value = "content_html") + private String contentHtml; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + @TableField(value = "type") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + @TableField(value = "level") + private String level; + + /** + * 目标类型 + */ + @Schema(description = "目标类型") + @TableField(value = "target_type") + private Integer targetType; + + /** + * 发布人ID + */ + @Schema(description = "发布人ID") + @TableField(value = "publisher_id") + private Long publisherId; + + /** + * 发布状态 + */ + @Schema(description = "发布状态") + @TableField(value = "publish_status") + private Integer publishStatus; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + @TableField(value = "publish_time") + private Instant publishTime; + + /** + * 撤回时间 + */ + @Schema(description = "撤回时间") + @TableField(value = "revoke_time") + private Instant revokeTime; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + @TableField(value = "is_deleted") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysParam.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysParam.java new file mode 100644 index 0000000..1bcff71 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysParam.java @@ -0,0 +1,79 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysParam

+ *

Description : 系统参数表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_param") +public class SysParam extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 系统参数key + */ + @Schema(description = "系统参数key") + @TableField(value = "param_key") + private String paramKey; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + @TableField(value = "data") + private String data; + + /** + * 参数值类型 + */ + @Schema(description = "参数值类型") + @TableField(value = "data_type") + private Integer dataType; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRisk.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRisk.java new file mode 100644 index 0000000..dd243c9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRisk.java @@ -0,0 +1,79 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysRisk

+ *

Description : 系统风控表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_risk") +public class SysRisk extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + @TableField(value = "sys_type") + private String sysType; + + /** + * 风控类型 + */ + @Schema(description = "风控类型") + @TableField(value = "type") + private Integer type; + + /** + * 系统参数值 + */ + @Schema(description = "系统参数值") + @TableField(value = "data") + private String data; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 更新人ID + */ + @Schema(description = "更新人ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRole.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRole.java new file mode 100644 index 0000000..2cdfa94 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRole.java @@ -0,0 +1,92 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysRole

+ *

Description : 系统角色表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_role") +public class SysRole extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 角色名称 + */ + @Schema(description = "角色名称") + @TableField(value = "name") + private String name; + + /** + * 角色编码 + */ + @Schema(description = "角色编码") + @TableField(value = "code") + private String code; + + /** + * 显示顺序 + */ + @Schema(description = "显示顺序") + @TableField(value = "sort") + private Integer sort; + + /** + * 角色状态 + */ + @Schema(description = "角色状态") + @TableField(value = "status") + private Integer status; + + /** + * 数据权限 + */ + @Schema(description = "数据权限") + @TableField(value = "data_scope") + private Integer dataScope; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 更新人 ID + */ + @Schema(description = "更新人 ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRoleMenu.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRoleMenu.java new file mode 100644 index 0000000..482c162 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysRoleMenu.java @@ -0,0 +1,57 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysRoleMenu

+ *

Description : 角色菜单关联表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_role_menu") +public class SysRoleMenu extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 角色 ID + */ + @Schema(description = "角色 ID") + @TableField(value = "role_id") + private Long roleId; + + /** + * 菜单 ID + */ + @Schema(description = "菜单 ID") + @TableField(value = "menu_id") + private Long menuId; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysTask.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysTask.java new file mode 100644 index 0000000..4612b85 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysTask.java @@ -0,0 +1,94 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysTask

+ *

Description : 系统任务实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_task") +public class SysTask extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 日志追踪 ID + */ + @Schema(description = "日志追踪 ID") + @TableField(value = "trace_id") + private String traceId; + + /** + * code + */ + @Schema(description = "code") + @TableField(value = "code") + private String code; + + /** + * 任务类型 + */ + @Schema(description = "任务类型") + @TableField(value = "type") + private String type; + + /** + * 状态 + */ + @Schema(description = "状态") + @TableField(value = "status") + private Integer status; + + /** + * 信息 + */ + @Schema(description = "信息") + @TableField(value = "info") + private String info; + + /** + * 开始时间 + */ + @Schema(description = "开始时间") + @TableField(value = "start_time") + private Instant startTime; + + /** + * 结束时间 + */ + @Schema(description = "结束时间") + @TableField(value = "end_time") + private Instant endTime; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUpdateHistory.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUpdateHistory.java new file mode 100644 index 0000000..231d20b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUpdateHistory.java @@ -0,0 +1,71 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysUpdateHistory

+ *

Description : 系统更新历史实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_update_history") +public class SysUpdateHistory extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 系统类型 + */ + @Schema(description = "系统类型") + @TableField(value = "type") + private Integer type; + + /** + * 信息 + */ + @Schema(description = "信息") + @TableField(value = "info") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + @TableField(value = "show_time") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + @TableField(value = "version") + private String version; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUser.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUser.java new file mode 100644 index 0000000..1c22fef --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUser.java @@ -0,0 +1,120 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysUser

+ *

Description : 系统用户表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_user") +public class SysUser extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 部门ID + */ + @Schema(description = "部门ID") + @TableField(value = "dept_id") + private Long deptId; + + /** + * 用户名 + */ + @Schema(description = "用户名") + @TableField(value = "account") + private String account; + + /** + * 昵称 + */ + @Schema(description = "昵称") + @TableField(value = "nickname") + private String nickname; + + /** + * 用户头像 + */ + @Schema(description = "用户头像") + @TableField(value = "avatar") + private String avatar; + + /** + * 手机号 + */ + @Schema(description = "手机号") + @TableField(value = "mobile") + private String mobile; + + /** + * 用户邮箱 + */ + @Schema(description = "用户邮箱") + @TableField(value = "email") + private String email; + + /** + * 性别 + */ + @Schema(description = "性别") + @TableField(value = "sex") + private Integer sex; + + /** + * 密码 + */ + @Schema(description = "密码") + @TableField(value = "passwd") + private String passwd; + + /** + * 状态 + */ + @Schema(description = "状态") + @TableField(value = "status") + private Integer status; + + /** + * 创建人 ID + */ + @Schema(description = "创建人 ID") + @TableField(value = "create_by") + private Long createBy; + + /** + * 修改人 ID + */ + @Schema(description = "修改人 ID") + @TableField(value = "update_by") + private Long updateBy; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNotice.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNotice.java new file mode 100644 index 0000000..c4abf76 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNotice.java @@ -0,0 +1,81 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysUserNotice

+ *

Description : 系统用户通知公告表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_user_notice") +public class SysUserNotice extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + @TableField(value = "notice_id") + private Long noticeId; + + /** + * 用户ID + */ + @Schema(description = "用户ID") + @TableField(value = "user_id") + private Long userId; + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + @TableField(value = "notice_read") + private Integer noticeRead; + + /** + * 阅读时间 + */ + @Schema(description = "阅读时间") + @TableField(value = "read_time") + private Instant readTime; + + /** + * 是否删除 + */ + @Schema(description = "是否删除") + @TableField(value = "is_deleted") + private Integer isDeleted; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNoticeInfo.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNoticeInfo.java new file mode 100644 index 0000000..e3fbe0b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserNoticeInfo.java @@ -0,0 +1,88 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +import java.time.Instant; + +/** + *

Title : SysUserNoticeInfo

+ *

Description : 系统用户通知公告信息表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_user_notice_info") +public class SysUserNoticeInfo extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 通知公告 ID + */ + @Schema(description = "通知公告 ID") + @TableField(value = "notice_id") + private Long noticeId; + + /** + * 读取状态 + */ + @Schema(description = "读取状态") + @TableField(value = "notice_read") + private Integer noticeRead; + + /** + * 通知标题 + */ + @Schema(description = "通知标题") + @TableField(value = "title") + private String title; + + /** + * 通知类型 + */ + @Schema(description = "通知类型") + @TableField(value = "type") + private Integer type; + + /** + * 通知等级 + */ + @Schema(description = "通知等级") + @TableField(value = "level") + private String level; + + /** + * 发布人ID + */ + @Schema(description = "发布人ID") + @TableField(value = "publisher_id") + private Long publisherId; + + /** + * 发布时间 + */ + @Schema(description = "发布时间") + @TableField(value = "publish_time") + private Instant publishTime; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserRole.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserRole.java new file mode 100644 index 0000000..fcb50a8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/model/entity/SysUserRole.java @@ -0,0 +1,57 @@ +package xtools.app.sys.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysUserRole

+ *

Description : 用户角色关联表实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_user_role") +public class SysUserRole extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户 ID + */ + @Schema(description = "用户 ID") + @TableField(value = "user_id") + private Long userId; + + /** + * 角色 ID + */ + @Schema(description = "角色 ID") + @TableField(value = "role_id") + private Long roleId; + + /** + * 备注 + */ + @Schema(description = "备注") + @TableField(value = "memo") + private String memo; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysLogMq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysLogMq.java new file mode 100644 index 0000000..5689521 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysLogMq.java @@ -0,0 +1,67 @@ +package xtools.app.sys.mq; + +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; +import xtools.app.common.log.bus.service.LogBusService; +import xtools.app.common.mq.enums.RabbitMqEnums; +import xtools.boot.log.model.dto.LogBody; +import xtools.boot.mq.base.enums.MqEnums; +import xtools.boot.mq.base.handle.BaseMessageHandle; +import xtools.boot.mq.rabbit.params.RabbitMqParams; + +/** + *

Title : SysLogMq

+ *

Description : SysLogMq

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/11 17:05 + */ +@Component +public class SysLogMq extends BaseMessageHandle { + + @Resource + private LogBusService logBusService; + + /** + * 构造方法 + */ + public SysLogMq() { + super(LogBody.class); + } + + /** + * 获取参数 + * + * @return 参数 + */ + @Override + public Object params() { + RabbitMqParams params = new RabbitMqParams(); + params.setConcurrency("5-10"); + return params; + } + + /** + * 获取队列 + * + * @return 队列 + */ + @Override + public MqEnums queue() { + return RabbitMqEnums.SYS_LOG; + } + + /** + * 处理消息 + * + * @param message 消息内容 + */ + @Override + public void handleMessage(LogBody message) { + logBusService.saveLog(message); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysTaskMq.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysTaskMq.java new file mode 100644 index 0000000..79aba3f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/mq/SysTaskMq.java @@ -0,0 +1,67 @@ +package xtools.app.sys.mq; + +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; +import xtools.app.common.mq.enums.RabbitMqEnums; +import xtools.app.sys.service.SysTaskService; +import xtools.boot.mq.base.enums.MqEnums; +import xtools.boot.mq.base.handle.BaseMessageHandle; +import xtools.boot.mq.rabbit.params.RabbitMqParams; +import xtools.boot.task.model.dto.TaskInfo; + +/** + *

Title : SysLogMq

+ *

Description : SysLogMq

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/11 17:05 + */ +@Component +public class SysTaskMq extends BaseMessageHandle { + + @Resource + private SysTaskService sysTaskService; + + /** + * 构造方法 + */ + public SysTaskMq() { + super(TaskInfo.class); + } + + /** + * 获取参数 + * + * @return 参数 + */ + @Override + public Object params() { + RabbitMqParams params = new RabbitMqParams(); + params.setConcurrency("5-10"); + return params; + } + + /** + * 获取队列 + * + * @return 队列 + */ + @Override + public MqEnums queue() { + return RabbitMqEnums.SYS_TASK; + } + + /** + * 处理消息 + * + * @param message 消息内容 + */ + @Override + public void handleMessage(TaskInfo message) { + sysTaskService.save(message); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysAddressService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysAddressService.java new file mode 100644 index 0000000..b3c1513 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysAddressService.java @@ -0,0 +1,16 @@ +package xtools.app.sys.service; + +import xtools.app.sys.api.SysAddressApi; + +/** + *

Title : SysAddressService

+ *

Description : 公用地址表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +public interface SysAddressService extends SysAddressApi { + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysBaseService.java new file mode 100644 index 0000000..b4f9bc8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysBaseService.java @@ -0,0 +1,69 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.IgnoreMaskReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.req.UserInfoPasswdEditReq; +import xtools.app.sys.model.dto.resp.SysBaseUserInfoResp; +import xtools.app.sys.model.dto.resp.SysIpAddrResp; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysBaseService

+ *

Description : SysBaseService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:24 + */ +public interface SysBaseService { + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + Result getUserInfo(); + + /** + * 保存用户信息 + * + * @param req 请求参数 + * @return 保存结果 + */ + Result editUserInfo(UserInfoEditReq req); + + /** + * 修改密码 + * + * @param req 请求参数 + * @return 修改结果 + */ + Result editPasswd(UserInfoPasswdEditReq req); + + /** + * 忽略掩码 + * + * @param req 请求参数 + * @return 忽略结果 + */ + Result ignoreMask(IgnoreMaskReq req); + + /** + * 取消忽略掩码 + * + * @return 取消结果 + */ + Result unIgnoreMask(); + + /** + * 获取IP地址信息 + * + * @param ip IP地址 + * @return IP地址信息 + */ + Result getIpAddress(String ip); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysCommonService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysCommonService.java new file mode 100644 index 0000000..655da3c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysCommonService.java @@ -0,0 +1,25 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.Sm2KeyDto; + +/** + *

Title : SysCommonService

+ *

Description : SysCommonService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/10 16:34 + */ +public interface SysCommonService { + + /** + * 获取SM2密钥对 + * + * @param uid 用户ID + * @return SM2密钥对 + */ + Sm2KeyDto getSm2Key(String uid); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDeptService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDeptService.java new file mode 100644 index 0000000..102d66d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDeptService.java @@ -0,0 +1,81 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysDeptAddReq; +import xtools.app.sys.model.dto.req.SysDeptPageReq; +import xtools.app.sys.model.dto.req.SysDeptUpdateReq; +import xtools.app.sys.model.dto.resp.SysDeptResp; +import xtools.app.sys.model.dto.resp.SysDeptTreeResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.resp.TreeResp; + +import java.util.List; + +/** + *

Title : SysDeptService

+ *

Description : 部门管理表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +public interface SysDeptService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysDeptAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysDeptUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 获取表格部门树 + * + * @param req 请求参数 + * @return 表格部门树 + */ + Result> treeTable(SysDeptPageReq req); + + /** + * 获取树 + * + * @return 树 + */ + Result> trees(); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictItemService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictItemService.java new file mode 100644 index 0000000..d60b0f2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictItemService.java @@ -0,0 +1,89 @@ +package xtools.app.sys.service; + +import xtools.app.sys.api.SysDictItemApi; +import xtools.app.sys.model.dto.excel.SysDictItemExcel; +import xtools.app.sys.model.dto.req.SysDictItemAddReq; +import xtools.app.sys.model.dto.req.SysDictItemPageReq; +import xtools.app.sys.model.dto.req.SysDictItemUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysDictItemService

+ *

Description : 数据字典项表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +public interface SysDictItemService extends SysDictItemApi { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysDictItemAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysDictItemUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List exportExcel(SysDictItemPageReq req); + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List dataList); + + /** + * 判断字典项是否存在 + * + * @param codeList 字典项编码 + * @return 存在结果 + */ + boolean existsByCodeList(List codeList); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictService.java new file mode 100644 index 0000000..d729bcf --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysDictService.java @@ -0,0 +1,79 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.excel.SysDictExcel; +import xtools.app.sys.model.dto.req.SysDictAddReq; +import xtools.app.sys.model.dto.req.SysDictPageReq; +import xtools.app.sys.model.dto.req.SysDictUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysDictService

+ *

Description : 数据字典类型表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +public interface SysDictService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysDictAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysDictUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List exportExcel(SysDictPageReq req); + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List dataList); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysFileService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysFileService.java new file mode 100644 index 0000000..0c4a6f3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysFileService.java @@ -0,0 +1,34 @@ +package xtools.app.sys.service; + +import xtools.app.sys.api.SysFileApi; +import xtools.app.sys.model.dto.req.SysFilePageReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +/** + *

Title : SysFileService

+ *

Description : 系统文件表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +public interface SysFileService extends SysFileApi { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 定时任务 + */ + void doJob(); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysHomeService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysHomeService.java new file mode 100644 index 0000000..549f937 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysHomeService.java @@ -0,0 +1,26 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.resp.SysHomeDataResp; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysHomeService

+ *

Description : SysHomeService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 19:49 + */ +public interface SysHomeService { + + /** + * 获取数据 + * + * @param ip IP + * @return 数据 + */ + Result getData(String ip); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLogService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLogService.java new file mode 100644 index 0000000..be81f3a --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLogService.java @@ -0,0 +1,64 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysLogPageReq; +import xtools.app.sys.model.dto.resp.SysLogResp; +import xtools.app.sys.model.entity.SysLog; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.time.Instant; +import java.util.List; + +/** + *

Title : SysLogService

+ *

Description : 日志记录表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +public interface SysLogService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据日志 ID 查询 + * + * @param logId 日志 ID + * @return 结果 + */ + Result getByLogId(String logId); + + /** + * 根据traceId查询 + * + * @param traceId traceId + * @return 日志列表 + */ + Result> getByTraceId(String traceId); + + /** + * 保存 + * + * @param sysLog 日志 + * @return 是否保存成功 + */ + boolean save(SysLog sysLog); + + /** + * 删除 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 删除数量 + */ + long delete(Instant startTime, Instant endTime); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLoginService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLoginService.java new file mode 100644 index 0000000..f969402 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysLoginService.java @@ -0,0 +1,36 @@ +package xtools.app.sys.service; + +import xtools.app.sys.auth.model.dto.TokenDto; +import xtools.app.sys.model.dto.req.SysLoginReq; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysLoginService

+ *

Description : SysLoginService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 14:02 + */ +public interface SysLoginService { + + /** + * 获取图片验证码 + * + * @param uid 用户id + * @return 图片验证码 + */ + Result captcha(String uid); + + /** + * 密码登录 + * + * @param req 登录参数 + * @return 登录结果 + */ + Result passwd(SysLoginReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMenuService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMenuService.java new file mode 100644 index 0000000..f209562 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMenuService.java @@ -0,0 +1,116 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysMenuAddReq; +import xtools.app.sys.model.dto.req.SysMenuPageReq; +import xtools.app.sys.model.dto.req.SysMenuTreesReq; +import xtools.app.sys.model.dto.req.SysMenuUpdateReq; +import xtools.app.sys.model.dto.resp.SysMenuResp; +import xtools.app.sys.model.dto.resp.SysMenuTreeResp; +import xtools.app.sys.model.entity.SysMenu; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.resp.TreeResp; + +import java.util.List; + +/** + *

Title : SysMenuService

+ *

Description : 系统菜单表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +public interface SysMenuService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysMenuAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysMenuUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 获取表格菜单树 + * + * @param req 请求参数 + * @return 菜单树 + */ + Result> treeTable(SysMenuPageReq req); + + /** + * 获取菜单树 + * + * @param req 请求参数 + * @return 菜单树 + */ + Result> trees(SysMenuTreesReq req); + + /** + * 构建菜单树 + * + * @param list 菜单数据 + * @return 菜单树 + */ + List buildTree(List list); + + /** + * 获取路由列表 + * + * @param list 菜单数据 + * @return 路由列表 + */ + List getRouteList(List list); + + /** + * 根据角色 ID 获取菜单列表 + * + * @param roleIds 角色 ID 集合 + * @return 菜单列表 + */ + List getMenuByRoleIds(List roleIds); + + /** + * 获取按钮权限 + * + * @param roleIds 角色 ID 集合 + * @return 按钮权限 + */ + List getBtnPermByRoleIds(List roleIds); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMonitorService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMonitorService.java new file mode 100644 index 0000000..37035c2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysMonitorService.java @@ -0,0 +1,45 @@ +package xtools.app.sys.service; + +import com.alibaba.fastjson2.JSONObject; +import xtools.boot.api.model.dto.Result; +import xtools.boot.db.mybatis.enums.MySqlMonitorEnums; +import xtools.boot.elasticsearch.enums.ElasticsearchMonitorEnums; + +import java.util.List; + +/** + *

Title : SysMonitorService

+ *

Description : SysMonitorService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 11:50 + */ +public interface SysMonitorService { + + /** + * 获取redis监控数据 + * + * @return redis监控数据 + */ + Result redis(); + + /** + * 获取mysql监控数据 + * + * @param type 监控类型 + * @return mysql监控数据 + */ + Result> mysql(MySqlMonitorEnums type); + + /** + * 获取elasticsearch监控数据 + * + * @param type 监控类型 + * @return elasticsearch监控数据 + */ + Result elasticsearch(ElasticsearchMonitorEnums type); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysNoticeService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysNoticeService.java new file mode 100644 index 0000000..6b6f332 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysNoticeService.java @@ -0,0 +1,79 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysNoticeAddReq; +import xtools.app.sys.model.dto.req.SysNoticePageReq; +import xtools.app.sys.model.dto.req.SysNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysNoticeResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysNoticeService

+ *

Description : 系统通知公告表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +public interface SysNoticeService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysNoticeAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysNoticeUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(IdListReq req); + + /** + * 发布 + * + * @param req ID 集合 + * @return 发布结果 + */ + Result publish(IdListReq req); + + /** + * 撤回 + * + * @param req ID 集合 + * @return 撤回结果 + */ + Result revoke(IdListReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysParamService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysParamService.java new file mode 100644 index 0000000..fb394a4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysParamService.java @@ -0,0 +1,69 @@ +package xtools.app.sys.service; + +import xtools.app.sys.api.SysParamApi; +import xtools.app.sys.model.dto.excel.SysParamExcel; +import xtools.app.sys.model.dto.req.SysParamPageReq; +import xtools.app.sys.model.dto.resp.SysParamResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysParamService

+ *

Description : 系统参数表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +public interface SysParamService extends SysParamApi { + + /** + * 初始化系统参数缓存 + */ + void init(); + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(IdListReq req); + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List exportExcel(SysParamPageReq req); + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List dataList); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysPermService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysPermService.java new file mode 100644 index 0000000..4ecd906 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysPermService.java @@ -0,0 +1,20 @@ +package xtools.app.sys.service; + +/** + *

Title : SysPermService

+ *

Description : SysPermService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 20:45 + */ +public interface SysPermService { + + /** + * 重新加载权限缓存 + */ + void reloadPermCache(); +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRiskService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRiskService.java new file mode 100644 index 0000000..9f3c301 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRiskService.java @@ -0,0 +1,116 @@ +package xtools.app.sys.service; + +import xtools.app.sys.api.SysRiskApi; +import xtools.app.sys.model.dto.excel.SysRiskExcel; +import xtools.app.sys.model.dto.req.SysRiskAddReq; +import xtools.app.sys.model.dto.req.SysRiskPageReq; +import xtools.app.sys.model.dto.req.SysRiskUpdateReq; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysRiskService

+ *

Description : 系统风控表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +public interface SysRiskService extends SysRiskApi { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysRiskAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysRiskUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(IdListReq req); + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List exportExcel(SysRiskPageReq req); + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List dataList); + + /** + * 获取风控IP数据 + * + * @param sysType 系统类型 + * @return 风控IP数据 + */ + Result> getIp(String sysType); + + /** + * 保存Ip + * + * @param sysType 系统类型 + * @param ipList IP列表 + * @return 保存结果 + */ + Result saveIp(String sysType, List ipList); + + /** + * 获取风控URI数据 + * + * @param sysType 系统类型 + * @return 风控URI数据 + */ + Result> getUri(String sysType); + + /** + * 保存URI + * + * @param sysType 系统类型 + * @param uriList IP列表 + * @return 保存结果 + */ + Result saveUri(String sysType, List uriList); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleMenuService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleMenuService.java new file mode 100644 index 0000000..cb6c243 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleMenuService.java @@ -0,0 +1,35 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysRoleMenuReq; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysRoleMenuService

+ *

Description : 角色菜单关联表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +public interface SysRoleMenuService { + + /** + * 获取角色菜单 ID 集合 + * + * @param roleId 角色 ID + * @return 角色菜单 ID 集合 + */ + Result> getRoleMenu(Long roleId); + + /** + * 保存角色菜单关联 + * + * @param req 保存参数 + * @return 保存结果 + */ + Result saveRoleMenu(SysRoleMenuReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleService.java new file mode 100644 index 0000000..abaa271 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysRoleService.java @@ -0,0 +1,71 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysRoleAddReq; +import xtools.app.sys.model.dto.req.SysRolePageReq; +import xtools.app.sys.model.dto.req.SysRoleUpdateReq; +import xtools.app.sys.model.dto.resp.SysRoleResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysRoleService

+ *

Description : 系统角色表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +public interface SysRoleService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysRoleAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysRoleUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 获取所有角色数据 + * + * @return 所有角色数据 + */ + Result> all(); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysTaskService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysTaskService.java new file mode 100644 index 0000000..6cad7f2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysTaskService.java @@ -0,0 +1,36 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysTaskPageReq; +import xtools.app.sys.model.dto.resp.SysTaskResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.task.model.dto.TaskInfo; + +/** + *

Title : SysTaskService

+ *

Description : 系统任务 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +public interface SysTaskService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 保存任务 + * + * @param taskInfo 任务信息 + */ + void save(TaskInfo taskInfo); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUpdateHistoryService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUpdateHistoryService.java new file mode 100644 index 0000000..dfac8bb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUpdateHistoryService.java @@ -0,0 +1,85 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysUpdateHistoryAddReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryPageReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryUpdateReq; +import xtools.app.sys.model.dto.resp.SysUpdateHistoryResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysUpdateHistoryService

+ *

Description : 系统更新历史 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +public interface SysUpdateHistoryService { + + /** + * 初始化缓存 + */ + void init(); + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysUpdateHistoryAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysUpdateHistoryUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 获取所有历史 + * + * @param type 类型 + * @return 所有历史 + */ + Result> getAll(Integer type); + + /** + * 删除缓存 + * + * @param type 类型 + * @return 删除结果 + */ + Result deleteCache(Integer type); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeInfoService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeInfoService.java new file mode 100644 index 0000000..96a38be --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeInfoService.java @@ -0,0 +1,52 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysUserNoticeInfoPageReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeInfoResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysUserNoticeInfoService

+ *

Description : 系统用户通知公告信息表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +public interface SysUserNoticeInfoService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 获取内容 + * + * @param noticeId 通知ID + * @return 内容 + */ + Result getContent(Long noticeId); + + /** + * 批量已读 + * + * @param req 请求参数 + * @return 是否成功 + */ + Result readList(IdListReq req); + + /** + * 全部已读 + * + * @return 是否成功 + */ + Result readAll(); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeService.java new file mode 100644 index 0000000..b1f4f48 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserNoticeService.java @@ -0,0 +1,65 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysUserNoticePageReq; +import xtools.app.sys.model.dto.req.SysUserNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysUserNoticeService

+ *

Description : 系统用户通知公告表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +public interface SysUserNoticeService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysUserNoticeUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + Result delById(IdListReq req); + + /** + * 根据通知 ID 获取用户 ID + * + * @param noticeId 通知 ID + * @return 用户 ID 集合 + */ + List getUserIdByNoticeId(Long noticeId); + + /** + * 保存 + * + * @param noticeId 通知 ID + * @param uids 用户 ID 集合 + * @param isAll 是否全员推送 + */ + void saveByNoticeId(Long noticeId, final List uids, boolean isAll); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserRoleService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserRoleService.java new file mode 100644 index 0000000..f4748b9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserRoleService.java @@ -0,0 +1,15 @@ +package xtools.app.sys.service; + +/** + *

Title : SysUserRoleService

+ *

Description : 用户角色关联表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +public interface SysUserRoleService { + + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserService.java new file mode 100644 index 0000000..82215e3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/SysUserService.java @@ -0,0 +1,90 @@ +package xtools.app.sys.service; + +import xtools.app.sys.model.dto.req.SysUserAddReq; +import xtools.app.sys.model.dto.req.SysUserPageReq; +import xtools.app.sys.model.dto.req.SysUserUpdateReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.resp.SysUserResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; + +import java.util.List; + +/** + *

Title : SysUserService

+ *

Description : 系统用户表 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +public interface SysUserService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysUserAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysUserUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 根据 ID 集合查询 + * + * @param req ID 集合请求 + * @return 查询结果 + */ + Result> getListByIds(IdListReq req); + + /** + * 获取用户信息 + * + * @param userId 用户 ID + * @return 用户信息 + */ + SysUserResp getUserInfo(Long userId); + + /** + * 保存用户信息 + * + * @param req 用户信息 + * @return 保存结果 + */ + boolean saveSysUser(UserInfoEditReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysAddressBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysAddressBaseService.java new file mode 100644 index 0000000..2d3e6d1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysAddressBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysAddressMapper; +import xtools.app.sys.model.entity.SysAddress; + +/** + *

Title : SysAddressBaseService

+ *

Description : 公用地址表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@Component +public class SysAddressBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDeptBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDeptBaseService.java new file mode 100644 index 0000000..da1d01f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDeptBaseService.java @@ -0,0 +1,67 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysDeptMapper; +import xtools.app.sys.model.entity.SysDept; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysDeptBaseService

+ *

Description : 部门管理表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Component +public class SysDeptBaseService extends ServiceImpl { + + /** + * 获取父级 + * + * @param pid ID + * @return 父级 + */ + public SysDept getParent(Long pid) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询条件 + query.eq(SysDept::getId, pid); + return this.getOne(query); + } + + /** + * 获取部门名称 + * + * @param id ID + * @return 部门名称 + */ + public String getDeptNameById(Long id) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDept::getDeptName); + query.eq(SysDept::getId, id); + SysDept one = this.getOne(query); + if (Objects.isNull(one)) { + return null; + } + return one.getDeptName(); + } + + /** + * 获取所有子级 ID + * + * @param id ID + * @return 所有子级 ID + */ + public List getChildrenId(Long id) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDept::getId); + query.likeLeft(SysDept::getTreePath, id); + return this.list(query).stream().map(SysDept::getId).toList(); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictBaseService.java new file mode 100644 index 0000000..6567591 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictBaseService.java @@ -0,0 +1,34 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysDictMapper; +import xtools.app.sys.model.entity.SysDict; +import xtools.base.config.BaseParams; + +/** + *

Title : SysDictBaseService

+ *

Description : 数据字典类型表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Component +public class SysDictBaseService extends ServiceImpl implements BaseParams { + + /** + * 根据字典编码查询字典 + * + * @param dictCode 字典编码 + * @return 字典 + */ + public SysDict getByCode(String dictCode) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysDict::getDictCode, dictCode); + query.eq(SysDict::getStatus, CP_NUM1); + return this.getOne(query); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictItemBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictItemBaseService.java new file mode 100644 index 0000000..629b342 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysDictItemBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysDictItemMapper; +import xtools.app.sys.model.entity.SysDictItem; + +/** + *

Title : SysDictItemBaseService

+ *

Description : 数据字典项表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Component +public class SysDictItemBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysFileBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysFileBaseService.java new file mode 100644 index 0000000..efae2e8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysFileBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysFileMapper; +import xtools.app.sys.model.entity.SysFile; + +/** + *

Title : SysFileBaseService

+ *

Description : 系统文件表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Component +public class SysFileBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysLogBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysLogBaseService.java new file mode 100644 index 0000000..4581ab1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysLogBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysLogMapper; +import xtools.app.sys.model.entity.SysLog; + +/** + *

Title : SysLogBaseService

+ *

Description : 日志记录表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Component +public class SysLogBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysMenuBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysMenuBaseService.java new file mode 100644 index 0000000..c795d75 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysMenuBaseService.java @@ -0,0 +1,56 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysMenuMapper; +import xtools.app.sys.model.dto.resp.SysMenuTreeResp; +import xtools.app.sys.model.entity.SysMenu; + +import java.util.ArrayList; +import java.util.List; + +/** + *

Title : SysMenuBaseService

+ *

Description : 系统菜单表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Component +public class SysMenuBaseService extends ServiceImpl { + + /** + * 获取父级 + * + * @param pid ID + * @return 父级 + */ + public SysMenu getParent(Long pid) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询条件 + query.eq(SysMenu::getId, pid); + return this.getOne(query); + } + + /** + * 获取子级 + * + * @param id ID + * @param list 数据 + * @return 子级 + */ + public List getChildren(Long id, List list) { + List children = new ArrayList<>(); + list.stream().filter(item -> item.getParentId().equals(id)).forEach(item -> { + List child = getChildren(item.getId(), list); + item.setChildren(child); + children.add(item); + }); + return children; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysNoticeBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysNoticeBaseService.java new file mode 100644 index 0000000..d5c9fc9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysNoticeBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysNoticeMapper; +import xtools.app.sys.model.entity.SysNotice; + +/** + *

Title : SysNoticeBaseService

+ *

Description : 系统通知公告表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Component +public class SysNoticeBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysParamBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysParamBaseService.java new file mode 100644 index 0000000..592afd2 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysParamBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysParamMapper; +import xtools.app.sys.model.entity.SysParam; + +/** + *

Title : SysParamBaseService

+ *

Description : 系统参数表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Component +public class SysParamBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRiskBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRiskBaseService.java new file mode 100644 index 0000000..09fd4f9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRiskBaseService.java @@ -0,0 +1,20 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; + +import xtools.app.sys.mapper.SysRiskMapper; +import xtools.app.sys.model.entity.SysRisk; + +/** + *

Title : SysRiskBaseService

+ *

Description : 系统风控表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Component +public class SysRiskBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleBaseService.java new file mode 100644 index 0000000..d55d963 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysRoleMapper; +import xtools.app.sys.model.entity.SysRole; + +/** + *

Title : SysRoleBaseService

+ *

Description : 系统角色表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Component +public class SysRoleBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleMenuBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleMenuBaseService.java new file mode 100644 index 0000000..695715b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysRoleMenuBaseService.java @@ -0,0 +1,61 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysRoleMenuMapper; +import xtools.app.sys.model.entity.SysRoleMenu; + +import java.util.List; + +/** + *

Title : SysRoleMenuBaseService

+ *

Description : 角色菜单关联表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Component +public class SysRoleMenuBaseService extends ServiceImpl { + + /** + * 获取角色菜单 ID 集合 + * + * @param roleId 角色 ID + * @return 角色菜单 ID 集合 + */ + public List getRoleMenu(Long roleId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysRoleMenu::getMenuId); + query.eq(SysRoleMenu::getRoleId, roleId); + List list = this.list(query); + return list.stream().map(SysRoleMenu::getMenuId).toList(); + } + + /** + * 根据角色 ID 删除角色菜单关联 + * + * @param roleId 角色 ID + * @return 删除结果 + */ + public boolean delByRoleId(Long roleId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysRoleMenu::getRoleId, roleId); + return this.remove(query); + } + + /** + * 根据菜单 ID 集合删除角色菜单关联 + * + * @param menuIds 菜单 ID 集合 + * @return 删除结果 + */ + public boolean delByMenuId(List menuIds) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysRoleMenu::getMenuId, menuIds); + return this.remove(query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysTaskBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysTaskBaseService.java new file mode 100644 index 0000000..5c7b37d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysTaskBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysTaskMapper; +import xtools.app.sys.model.entity.SysTask; + +/** + *

Title : SysTaskBaseService

+ *

Description : 系统任务 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Component +public class SysTaskBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUpdateHistoryBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUpdateHistoryBaseService.java new file mode 100644 index 0000000..7e64816 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUpdateHistoryBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysUpdateHistoryMapper; +import xtools.app.sys.model.entity.SysUpdateHistory; + +/** + *

Title : SysUpdateHistoryBaseService

+ *

Description : 系统更新历史 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Component +public class SysUpdateHistoryBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserBaseService.java new file mode 100644 index 0000000..ebe0424 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserBaseService.java @@ -0,0 +1,42 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysUserMapper; +import xtools.app.sys.model.entity.SysUser; + +/** + *

Title : SysUserBaseService

+ *

Description : 系统用户表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Component +public class SysUserBaseService extends ServiceImpl { + + /** + * 获取用户信息 + * + * @param userId 用户 ID + * @return 用户信息 + */ + public SysUser getSysUser(Long userId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select( + SysUser::getId, + SysUser::getAccount, + SysUser::getNickname, + SysUser::getAvatar, + SysUser::getMobile, + SysUser::getEmail, + SysUser::getSex + ); + query.eq(SysUser::getId, userId); + return this.getOne(query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeBaseService.java new file mode 100644 index 0000000..82aa1c1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysUserNoticeMapper; +import xtools.app.sys.model.entity.SysUserNotice; + +/** + *

Title : SysUserNoticeBaseService

+ *

Description : 系统用户通知公告表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Component +public class SysUserNoticeBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeInfoBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeInfoBaseService.java new file mode 100644 index 0000000..ce1ec66 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserNoticeInfoBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysUserNoticeInfoMapper; +import xtools.app.sys.model.entity.SysUserNoticeInfo; + +/** + *

Title : SysUserNoticeInfoBaseService

+ *

Description : 系统用户通知公告信息表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Component +public class SysUserNoticeInfoBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserRoleBaseService.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserRoleBaseService.java new file mode 100644 index 0000000..53b7c12 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/base/SysUserRoleBaseService.java @@ -0,0 +1,84 @@ +package xtools.app.sys.service.base; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.mapper.SysUserRoleMapper; +import xtools.app.sys.model.entity.SysUserRole; +import xtools.core.ArrUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + *

Title : SysUserRoleBaseService

+ *

Description : 用户角色关联表 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +@Component +public class SysUserRoleBaseService extends ServiceImpl { + + /** + * 获取用户角色 ID 集合 + * + * @param userId 用户 ID + * @return 用户角色 ID 集合 + */ + public List getUserRole(Long userId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUserRole::getRoleId); + query.eq(SysUserRole::getUserId, userId); + List list = this.list(query); + return list.stream().map(SysUserRole::getRoleId).toList(); + } + + /** + * 删除用户角色关联 + * + * @param userId 用户 ID + * @return 删除结果 + */ + public boolean delByUserId(Long userId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysUserRole::getUserId, userId); + return this.remove(query); + } + + /** + * 根据角色 ID 集合删除角色关联 + * + * @param roleIds 角色 ID 集合 + * @return 删除结果 + */ + public boolean delByRoleId(List roleIds) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysUserRole::getRoleId, roleIds); + return this.remove(query); + } + + /** + * 包装用户角色关联 + * + * @param userId 用户 ID + * @param roleIds 角色 ID 集合 + * @return 用户角色关联集合 + */ + public List packageUserRoleList(Long userId, Long[] roleIds) { + List list = new ArrayList<>(); + if (ArrUtils.isEmpty(roleIds)) { + return list; + } + for (Long roleId : roleIds) { + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(userId); + sysUserRole.setRoleId(roleId); + list.add(sysUserRole); + } + return list; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/LogBusServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/LogBusServiceImpl.java new file mode 100644 index 0000000..dd9e545 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/LogBusServiceImpl.java @@ -0,0 +1,93 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.common.log.bus.service.LogBusService; +import xtools.app.sys.model.entity.SysLog; +import xtools.app.sys.service.SysLogService; +import xtools.boot.api.model.dto.log.LogTrack; +import xtools.boot.log.model.dto.LogBody; +import xtools.boot.log.model.dto.RunInfo; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.extend.JsonUtils; + +import java.util.Objects; + +/** + *

Title : LogBusServiceImpl

+ *

Description : LogBusServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/7 19:48 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class LogBusServiceImpl implements LogBusService { + + private final SysLogService sysLogService; + + /** + * 保存日志 + * + * @param logBody 日志 + */ + @Override + public void saveLog(LogBody logBody) { + LogTrack logTrack = logBody.getLogTrack(); + RunInfo runInfo = logBody.getRunInfo(); + + JSONObject logData = logBody.getLogData(); + if (CollectionUtils.isEmpty(logData)) { + logData = new JSONObject(); + } + JSONArray stackTrace = logBody.getStackTrace(); + + // 处理数据 + String title = logBody.getTitle(); + String logType = logBody.getType(); + title = StringUtils.isBlank(title) ? logType : title; + // 获取请求ip + String ip = logData.getString("ip"); + // 获取请求uri + String uri = logData.getString("uri"); + + SysLog sysLog = new SysLog(); + sysLog.setLogId(logTrack.id()); + sysLog.setTraceId(logTrack.traceId()); + sysLog.setParentId(logTrack.parentId()); + sysLog.setThreadType(logTrack.type().name()); + sysLog.setLogTime(logTrack.time()); + sysLog.setLogIndex(logTrack.index()); + + sysLog.setAppName(runInfo.getAppName()); + sysLog.setLocalIp(runInfo.getLocalIp()); + sysLog.setPort(String.valueOf(runInfo.getPort())); + + sysLog.setTitle(title); + sysLog.setLogLevel(logBody.getLevel().code()); + sysLog.setLogType(logType); + sysLog.setIp(ip); + sysLog.setUri(uri); + sysLog.setLogBody(logData.toJSONString()); + sysLog.setStackTrace(Objects.nonNull(stackTrace) ? stackTrace.toJSONString() : null); + sysLog.setLogError(logBody.getErr()); + + // 保存日志 + try { + sysLogService.save(sysLog); + } catch (Exception e) { + log.error("保存日志异常,logBody:{}", JsonUtils.toStrPretty(logBody), e); + } + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysAddressServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysAddressServiceImpl.java new file mode 100644 index 0000000..ed6a423 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysAddressServiceImpl.java @@ -0,0 +1,85 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.MapUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.convert.SysAddressConvert; +import xtools.app.sys.model.dto.resp.SysAddressResp; +import xtools.app.sys.model.entity.SysAddress; +import xtools.app.sys.service.SysAddressService; +import xtools.app.sys.service.base.SysAddressBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.base.RedisService; +import xtools.core.StringUtils; + +import java.util.Objects; + +/** + *

Title : SysAddressServiceImpl

+ *

Description : 公用地址表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysAddressServiceImpl implements SysAddressService, BaseParams { + + /** + * 缓存参数 + */ + private static final AppCache CACHE_PARAM = AppCache.SYS_CACHE_ADDR; + private final SysAddressBaseService sysAddressBaseService; + private final SysAddressConvert sysAddressConvert; + @Resource + private RedisService redisService; + + /** + * 根据code获取地址信息 + * + * @param code Code + * @return 地址信息 + */ + @Override + public Result getByCode(String code) { + if (StringUtils.isBlank(code)) { + return null; + } + String cacheKey = CACHE_PARAM.key() + code; + JSONObject addrJson = redisService.get(cacheKey, JSONObject.class); + if (MapUtils.isNotEmpty(addrJson)) { + return Result.ok(JSON.to(SysAddressResp.class, addrJson)); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select( + SysAddress::getId, + SysAddress::getParentId, + SysAddress::getTitle, + SysAddress::getType, + SysAddress::getLat, + SysAddress::getLng, + SysAddress::getMemo + ); + query.eq(SysAddress::getCode, code); + SysAddress address = sysAddressBaseService.getOne(query); + SysAddressResp resp = sysAddressConvert.entityToResp(address); + if (Objects.isNull(resp)) { + redisService.set(cacheKey, new JSONObject(), CACHE_PARAM.expireTime()); + } else { + redisService.set(cacheKey, resp); + } + return Result.ok(resp); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysBaseServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysBaseServiceImpl.java new file mode 100644 index 0000000..569d2f6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysBaseServiceImpl.java @@ -0,0 +1,177 @@ +package xtools.app.sys.service.impl; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysBaseConvert; +import xtools.app.sys.model.dto.Sm2KeyDto; +import xtools.app.sys.model.dto.req.IgnoreMaskReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.req.UserInfoPasswdEditReq; +import xtools.app.sys.model.dto.resp.SysBaseUserInfoResp; +import xtools.app.sys.model.dto.resp.SysIpAddrResp; +import xtools.app.sys.model.entity.SysMenu; +import xtools.app.sys.model.entity.SysUser; +import xtools.app.sys.service.SysBaseService; +import xtools.app.sys.service.SysCommonService; +import xtools.app.sys.service.SysMenuService; +import xtools.app.sys.service.SysUserService; +import xtools.app.sys.service.base.SysUserBaseService; +import xtools.app.sys.utils.PasswdUtils; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.ip.utils.IpUtils; +import xtools.core.CollectionUtils; +import xtools.extend.dto.IpAddrDto; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysBaseServiceImpl

+ *

Description : SysBaseServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/29 22:25 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysBaseServiceImpl implements SysBaseService, BaseParams { + + private final SysCommonService sysCommonService; + + private final SysMenuService sysMenuService; + + private final SysUserService sysUserService; + + private final SysUserBaseService sysUserBaseService; + + private final SysBaseConvert sysBaseConvert; + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @Override + public Result getUserInfo() { + // 用户信息响应 + SysBaseUserInfoResp resp = new SysBaseUserInfoResp(); + + // 获取登录用户信息 + LoginUserDto loginUser = AuthUtils.get(); + + // 设置用户信息 + resp.setSysUser(sysUserService.getUserInfo(loginUser.getId())); + + // 获取用户角色信息 + List roleIds = loginUser.getRoleIds(); + if (CollectionUtils.isNotEmpty(roleIds)) { + // 获取用户菜单列表 + List sysMenus = sysMenuService.getMenuByRoleIds(roleIds); + resp.setMenuTree(sysMenuService.buildTree(sysMenus)); + resp.setRouteList(sysMenuService.getRouteList(sysMenus)); + resp.setBtnPerms(sysMenuService.getBtnPermByRoleIds(roleIds)); + } + return Result.ok(resp); + } + + /** + * 修改用户信息 + * + * @param req 请求参数 + * @return 保存结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result editUserInfo(UserInfoEditReq req) { + LoginUserDto loginUser = AuthUtils.get(); + req.setId(loginUser.getId()); + return Result.ok(sysUserService.saveSysUser(req)); + } + + /** + * 修改密码 + * + * @param req 请求参数 + * @return 修改结果 + */ + @Override + public Result editPasswd(UserInfoPasswdEditReq req) { + // 解密密码 + Sm2KeyDto sm2Key = sysCommonService.getSm2Key(req.getUid()); + String oldPasswd = PasswdUtils.decrypt(sm2Key, req.getPublicKey(), req.getOldPasswd()); + String passwd = PasswdUtils.decrypt(sm2Key, req.getPublicKey(), req.getPasswd()); + // 获取用户id + Long userId = AuthUtils.get().getId(); + SysUser sysUser = sysUserBaseService.getById(userId); + if (Objects.isNull(sysUser)) { + throw new BizError("用户不存在"); + } + if (!PasswdUtils.check(oldPasswd, sysUser.getPasswd())) { + throw new BizError("原密码错误"); + } + // 修改密码 + SysUser update = new SysUser(); + update.setId(userId); + update.setPasswd(PasswdUtils.encrypt(passwd)); + return Result.ok(sysUserBaseService.updateById(update)); + } + + /** + * 忽略掩码 + * + * @param req 请求参数 + * @return 忽略结果 + */ + @Override + public Result ignoreMask(IgnoreMaskReq req) { + // 解密密码 + Sm2KeyDto sm2Key = sysCommonService.getSm2Key(req.getUid()); + String passwd = PasswdUtils.decrypt(sm2Key, req.getPublicKey(), req.getPasswd()); + // 获取用户id + Long userId = AuthUtils.get().getId(); + SysUser sysUser = sysUserBaseService.getById(userId); + if (Objects.isNull(sysUser)) { + throw new BizError("用户不存在"); + } + if (!PasswdUtils.check(passwd, sysUser.getPasswd())) { + throw new BizError("密码错误"); + } + AuthUtils.setIgnoreMask(); + return Result.ok(true); + } + + /** + * 取消忽略掩码 + * + * @return 取消结果 + */ + @Override + public Result unIgnoreMask() { + AuthUtils.removeIgnoreMask(); + return Result.ok(true); + } + + /** + * 获取IP地址信息 + * + * @param ip IP地址 + * @return IP地址信息 + */ + @Override + public Result getIpAddress(String ip) { + IpAddrDto dto = IpUtils.search(ip); + return Result.ok(sysBaseConvert.dtoToResp(dto)); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysCommonServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysCommonServiceImpl.java new file mode 100644 index 0000000..2c6e290 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysCommonServiceImpl.java @@ -0,0 +1,54 @@ +package xtools.app.sys.service.impl; + +import jakarta.annotation.Resource; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.model.dto.Sm2KeyDto; +import xtools.app.sys.service.SysCommonService; +import xtools.boot.cache.redis.base.RedisService; +import xtools.extend.encrypt.Sm2Utils; + +import java.util.Objects; + +/** + *

Title : SysCommonServiceImpl

+ *

Description : SysCommonServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/10 16:34 + */ +@Primary +@Service +public class SysCommonServiceImpl implements SysCommonService { + + @Resource + private RedisService redisService; + + /** + * 获取SM2密钥对 + * + * @param uid 用户ID + * @return SM2密钥对 + */ + @Override + public Sm2KeyDto getSm2Key(String uid) { + AppCache cacheParam = AppCache.UID_SM2; + Sm2KeyDto key = redisService.get(cacheParam.key(uid), Sm2KeyDto.class); + if (Objects.nonNull(key)) { + return key; + } + AsymmetricCipherKeyPair keyPair = Sm2Utils.getKey(); + key = new Sm2KeyDto(); + key.setPublicKey(Sm2Utils.getPublicKey(keyPair)); + key.setPrivateKey(Sm2Utils.getPrivateKey(keyPair)); + redisService.set(cacheParam.key(uid), key, cacheParam.expireTime()); + return key; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDeptServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..f346ecb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,359 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysDeptConvert; +import xtools.app.sys.model.dto.req.SysDeptAddReq; +import xtools.app.sys.model.dto.req.SysDeptPageReq; +import xtools.app.sys.model.dto.req.SysDeptUpdateReq; +import xtools.app.sys.model.dto.resp.SysDeptResp; +import xtools.app.sys.model.dto.resp.SysDeptTreeResp; +import xtools.app.sys.model.entity.SysDept; +import xtools.app.sys.service.SysDeptService; +import xtools.app.sys.service.base.SysDeptBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.resp.TreeResp; +import xtools.boot.core.utils.TreeUtils; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.boot.web.base.config.JacksonConfig; +import xtools.core.ArrUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +/** + *

Title : SysDeptServiceImpl

+ *

Description : 部门管理表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 14:59:40 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysDeptServiceImpl implements SysDeptService, BaseParams { + + private final SysDeptBaseService sysDeptBaseService; + + private final SysDeptConvert sysDeptConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysDeptConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysDept data = sysDeptBaseService.getById(id); + return Result.ok(sysDeptConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysDeptAddReq req) { + SysDept entity = sysDeptConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + Long parentId = req.getParentId(); + if (CheckUtils.id(parentId)) { + List treeIdList = new ArrayList<>(); + while (true) { + SysDept parent = sysDeptBaseService.getParent(parentId); + if (Objects.isNull(parent)) { + break; + } + treeIdList.add(parent.getId()); + parentId = parent.getParentId(); + } + StringJoiner treePath = new StringJoiner(CP_COMMA); + for (Long id : treeIdList.reversed()) { + treePath.add(id.toString()); + } + entity.setTreePath(treePath.toString()); + } + return Result.ok(sysDeptBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysDeptUpdateReq req) { + SysDept entity = sysDeptConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysDeptBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + if (CollectionUtils.isEmpty(idList)) { + throw new BizError("删除失败"); + } + for (Long id : idList) { + if (existsByPid(id)) { + throw new BizWarning("该部门下有子部门,请先删除子部门"); + } + } + boolean removed = sysDeptBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 判断根据 Pid 部门是否存在 + * + * @param pid 部门 ID + * @return 存在结果 + */ + private boolean existsByPid(Long pid) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询条件 + query.eq(SysDept::getParentId, pid); + return sysDeptBaseService.exists(query); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysDeptPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysDept::getId, + SysDept::getDeptCode, + SysDept::getDeptName, + SysDept::getStatus, + SysDept::getMemo, + SysDept::getGmtCreate, + SysDept::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByAsc(SysDept::getSort); + query.orderByAsc(SysDept::getGmtCreate); + return sysDeptBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysDeptPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysDept::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getDeptCode()), SysDept::getDeptCode, req.getDeptCode()); + query.like(StringUtils.isNotBlank(req.getDeptName()), SysDept::getDeptName, req.getDeptName()); + query.eq(Objects.nonNull(req.getParentId()), SysDept::getParentId, req.getParentId()); + query.like(StringUtils.isNotBlank(req.getTreePath()), SysDept::getTreePath, req.getTreePath()); + query.eq(Objects.nonNull(req.getSort()), SysDept::getSort, req.getSort()); + query.eq(Objects.nonNull(req.getStatus()), SysDept::getStatus, req.getStatus()); + query.eq(Objects.nonNull(req.getCreateBy()), SysDept::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysDept::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysDept::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysDept::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysDept::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(SysDept entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysDept::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getDeptCode()), SysDept::getDeptCode, entity.getDeptCode()); + return sysDeptBaseService.exists(query); + } + + /** + * 获取表格部门树 + * + * @param req 请求参数 + * @return 表格部门树 + */ + @Override + public Result> treeTable(SysDeptPageReq req) { + Set noParentIdSet = getNoInParentId(req); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + if (!Objects.equals(JacksonConfig.NON_NULL.writeValueAsString(req), CP_EMPTY_JSON)) { + query.or(q -> setQueryWrapper(q, req)); + } + if (CollectionUtils.isNotEmpty(noParentIdSet)) { + query.or(q -> q.in(SysDept::getId, noParentIdSet)); + } + // 排序 + query.orderByAsc(SysDept::getSort); + query.orderByAsc(SysDept::getGmtCreate); + return Result.ok(buildTree(sysDeptBaseService.list(query))); + } + + /** + * 获取没有列表的父部门的 ID 集合 + * + * @param req 请求参数 + * @return ID 集合 + */ + private Set getNoInParentId(SysDeptPageReq req) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDept::getId, SysDept::getTreePath); + setQueryWrapper(query, req); + List list = sysDeptBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + return null; + } + Set idSet = list.stream().map(SysDept::getId).collect(Collectors.toSet()); + Set noParentIdSet = new HashSet<>(); + for (SysDept entity : list) { + String treePath = entity.getTreePath(); + if (StringUtils.isBlank(treePath)) { + continue; + } + List treeIds = ArrUtils.toLongList(treePath); + treeIds.forEach(item -> { + if (!idSet.contains(item)) { + noParentIdSet.add(item); + } + }); + } + return noParentIdSet; + } + + + /** + * 构建树 + * + * @param list 数据 + * @return 树 + */ + private List buildTree(List list) { + if (CollectionUtils.isEmpty(list)) { + return new ArrayList<>(); + } + List dataList = sysDeptConvert.entityToTreeRespList(list); + return getChild(0L, dataList); + } + + /** + * 获取子级 + * + * @param id ID + * @param list 数据 + * @return 子级 + */ + private List getChild(Long id, List list) { + List childList = new ArrayList<>(); + list.stream().filter(item -> item.getParentId().equals(id)).forEach(item -> { + List child = getChild(item.getId(), list); + item.setChildren(child); + childList.add(item); + }); + return childList; + } + + /** + * 获取树 + * + * @return 树 + */ + @Override + public Result> trees() { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询字段 + query.select(SysDept::getId, SysDept::getParentId, SysDept::getDeptName); + // 添加查询条件 + query.eq(SysDept::getStatus, CP_NUM1); + // 排序 + query.orderByAsc(SysDept::getSort); + query.orderByAsc(SysDept::getGmtCreate); + // 查询 + List queryList = sysDeptBaseService.list(query); + if (CollectionUtils.isEmpty(queryList)) { + return Result.ok(new ArrayList<>()); + } + List list = queryList.stream().map(item -> { + TreeResp treeResp = new TreeResp(); + treeResp.setParentId(item.getParentId()); + treeResp.setValue(item.getId()); + treeResp.setLabel(item.getDeptName()); + return treeResp; + }).collect(Collectors.toList()); + return Result.ok(TreeUtils.getChild(0L, list)); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictItemServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictItemServiceImpl.java new file mode 100644 index 0000000..ab01595 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictItemServiceImpl.java @@ -0,0 +1,298 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysDictItemConvert; +import xtools.app.sys.model.dto.excel.SysDictItemExcel; +import xtools.app.sys.model.dto.req.SysDictItemAddReq; +import xtools.app.sys.model.dto.req.SysDictItemPageReq; +import xtools.app.sys.model.dto.req.SysDictItemUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.app.sys.model.entity.SysDict; +import xtools.app.sys.model.entity.SysDictItem; +import xtools.app.sys.service.SysDictItemService; +import xtools.app.sys.service.base.SysDictBaseService; +import xtools.app.sys.service.base.SysDictItemBaseService; +import xtools.boot.api.enums.StatusEnum; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysDictItemServiceImpl

+ *

Description : 数据字典项表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 11:29:51 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysDictItemServiceImpl implements SysDictItemService { + + private final SysDictBaseService sysDictBaseService; + + private final SysDictItemBaseService sysDictItemBaseService; + + private final SysDictItemConvert sysDictItemConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysDictItemConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysDictItem data = sysDictItemBaseService.getById(id); + return Result.ok(sysDictItemConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysDictItemAddReq req) { + SysDictItem entity = sysDictItemConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysDictItemBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysDictItemUpdateReq req) { + SysDictItem entity = sysDictItemConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysDictItemBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + boolean removed = sysDictItemBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List exportExcel(SysDictItemPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysDictItem::getDictCode, + SysDictItem::getValue, + SysDictItem::getLabel, + SysDictItem::getTagType, + SysDictItem::getStatus, + SysDictItem::getSort, + SysDictItem::getMemo + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByAsc(SysDictItem::getDictCode); + query.orderByAsc(SysDictItem::getSort); + query.orderByDesc(SysDictItem::getGmtCreate); + List dataList = sysDictItemBaseService.list(query); + return dataList.stream().map(item -> { + StatusEnum status = StatusEnum.valueOf(item.getStatus()); + SysDictItemExcel excel = sysDictItemConvert.entityToExcel(item); + excel.setStatus(status.desc()); + return excel; + }).toList(); + } + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List dataList) { + for (SysDictItemExcel excel : dataList) { + StatusEnum status = StatusEnum.valueOfDesc(excel.getStatus()); + + SysDictItem item = sysDictItemConvert.excelToEntity(excel); + item.setStatus(status.code()); + + SysDictItem dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + sysDictItemBaseService.save(item); + } else { + // 修改 + item.setId(dbItem.getId()); + sysDictItemBaseService.updateById(item); + } + } + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysDictItemPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysDictItem::getId, + SysDictItem::getValue, + SysDictItem::getLabel, + SysDictItem::getTagType, + SysDictItem::getStatus, + SysDictItem::getSort, + SysDictItem::getMemo, + SysDictItem::getGmtCreate, + SysDictItem::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByAsc(SysDictItem::getSort); + query.orderByDesc(SysDictItem::getGmtCreate); + return sysDictItemBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysDictItemPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysDictItem::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getDictCode()), SysDictItem::getDictCode, req.getDictCode()); + query.like(StringUtils.isNotBlank(req.getValue()), SysDictItem::getValue, req.getValue()); + query.like(StringUtils.isNotBlank(req.getLabel()), SysDictItem::getLabel, req.getLabel()); + query.eq(Objects.nonNull(req.getTagType()), SysDictItem::getTagType, req.getTagType()); + query.eq(Objects.nonNull(req.getStatus()), SysDictItem::getStatus, req.getStatus()); + query.eq(Objects.nonNull(req.getSort()), SysDictItem::getSort, req.getSort()); + query.eq(Objects.nonNull(req.getCreateBy()), SysDictItem::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysDictItem::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysDictItem::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysDictItem::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysDictItem::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 存在的实体 + */ + private SysDictItem existsEntity(SysDictItem entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDictItem::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysDictItem::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getDictCode()), SysDictItem::getDictCode, entity.getDictCode()); + query.eq(Objects.nonNull(entity.getValue()), SysDictItem::getValue, entity.getValue()); + return sysDictItemBaseService.getOne(query); + } + + /** + * 判断字典项是否存在 + * + * @param codeList 字典项编码 + * @return 存在结果 + */ + @Override + public boolean existsByCodeList(List codeList) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysDictItem::getDictCode, codeList); + return sysDictItemBaseService.exists(query); + } + + /** + * 根据字典编码查询字典项 + * + * @param dictCode 字典编码 + * @return 字典项 + */ + @Override + public Result> getByCode(String dictCode) { + // 判断字典是否启用 + SysDict sysDict = sysDictBaseService.getByCode(dictCode); + if (Objects.isNull(sysDict)) { + return Result.ok(new ArrayList<>()); + } + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDictItem::getLabel, SysDictItem::getValue, SysDictItem::getTagType); + query.eq(SysDictItem::getDictCode, dictCode); + query.eq(SysDictItem::getStatus, 1); + query.orderByAsc(SysDictItem::getSort); + query.orderByDesc(SysDictItem::getGmtCreate); + return Result.ok(sysDictItemConvert.entityToRespList(sysDictItemBaseService.list(query))); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictServiceImpl.java new file mode 100644 index 0000000..18f9c8d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysDictServiceImpl.java @@ -0,0 +1,266 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysDictConvert; +import xtools.app.sys.model.dto.excel.SysDictExcel; +import xtools.app.sys.model.dto.req.SysDictAddReq; +import xtools.app.sys.model.dto.req.SysDictPageReq; +import xtools.app.sys.model.dto.req.SysDictUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictResp; +import xtools.app.sys.model.entity.SysDict; +import xtools.app.sys.service.SysDictItemService; +import xtools.app.sys.service.SysDictService; +import xtools.app.sys.service.base.SysDictBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.StatusEnum; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysDictServiceImpl

+ *

Description : 数据字典类型表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 10:34:37 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysDictServiceImpl implements SysDictService, BaseParams { + + private final SysDictItemService sysDictItemService; + + private final SysDictBaseService sysDictBaseService; + + private final SysDictConvert sysDictConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysDictConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysDict data = sysDictBaseService.getById(id); + return Result.ok(sysDictConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysDictAddReq req) { + SysDict entity = sysDictConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysDictBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysDictUpdateReq req) { + SysDict entity = sysDictConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysDictBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + if (CollectionUtils.isEmpty(idList)) { + throw new BizError("删除失败"); + } + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDict::getDictCode); + query.in(SysDict::getId, idList); + List dictList = sysDictBaseService.list(query); + if (CollectionUtils.isEmpty(dictList)) { + throw new BizError("删除失败"); + } + List dictCodeList = dictList.stream().map(SysDict::getDictCode).toList(); + if (sysDictItemService.existsByCodeList(dictCodeList)) { + throw new BizWarning("该字典下存在字典数据,无法删除"); + } + boolean removed = sysDictBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List exportExcel(SysDictPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysDict::getDictCode + , SysDict::getDictName + , SysDict::getStatus + , SysDict::getMemo + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysDict::getGmtCreate); + List dataList = sysDictBaseService.list(query); + return dataList.stream().map(item -> { + StatusEnum status = StatusEnum.valueOf(item.getStatus()); + SysDictExcel excel = sysDictConvert.entityToExcel(item); + excel.setStatus(status.desc()); + return excel; + }).toList(); + } + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List dataList) { + for (SysDictExcel excel : dataList) { + StatusEnum status = StatusEnum.valueOfDesc(excel.getStatus()); + + SysDict item = sysDictConvert.excelToEntity(excel); + item.setStatus(status.code()); + + SysDict dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + sysDictBaseService.save(item); + } else { + // 修改 + item.setId(dbItem.getId()); + sysDictBaseService.updateById(item); + } + } + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysDictPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysDict::getId, + SysDict::getDictCode, + SysDict::getDictName, + SysDict::getStatus, + SysDict::getMemo, + SysDict::getGmtCreate, + SysDict::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysDict::getGmtCreate); + return sysDictBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysDictPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysDict::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getDictCode()), SysDict::getDictCode, req.getDictCode()); + query.like(StringUtils.isNotBlank(req.getDictName()), SysDict::getDictName, req.getDictName()); + query.eq(Objects.nonNull(req.getStatus()), SysDict::getStatus, req.getStatus()); + query.eq(Objects.nonNull(req.getCreateBy()), SysDict::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysDict::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysDict::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysDict::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysDict::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysDict existsEntity(SysDict entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysDict::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysDict::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getDictCode()), SysDict::getDictCode, entity.getDictCode()); + return sysDictBaseService.getOne(query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysFileServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysFileServiceImpl.java new file mode 100644 index 0000000..8c8e6aa --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysFileServiceImpl.java @@ -0,0 +1,375 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.common.task.enums.TaskType; +import xtools.app.sys.convert.SysFileConvert; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileChangeReq; +import xtools.app.sys.model.dto.req.SysFilePageReq; +import xtools.app.sys.model.dto.req.SysFileUpdateReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.app.sys.model.entity.SysFile; +import xtools.app.sys.service.SysFileService; +import xtools.app.sys.service.base.SysFileBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.FileDataType; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.storage.base.config.StorageConfig; +import xtools.boot.storage.base.service.StorageService; +import xtools.boot.task.TaskBus; +import xtools.boot.task.enums.TaskStatus; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.UuidUtils; +import xtools.core.enums.LogLevel; +import xtools.core.extend.TemplateUtils; + +import java.time.Instant; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + *

Title : SysFileServiceImpl

+ *

Description : 系统文件表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysFileServiceImpl implements SysFileService, BaseParams { + + private final SysFileBaseService sysFileBaseService; + + private final SysFileConvert sysFileConvert; + + @Resource + private StorageService storageService; + + @Resource + private StorageConfig storageConfig; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysFileConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysFile data = sysFileBaseService.getById(id); + return Result.ok(sysFileConvert.entityToResp(data)); + } + + /** + * 根据文件名查询 + * + * @param bucket 桶名称 + * @param fileName 文件名 + * @return 结果 + */ + @Override + public Result getByName(String bucket, String fileName) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysFile::getBucket, bucket); + query.eq(SysFile::getFileName, fileName); + SysFile data = sysFileBaseService.getOne(query); + return Result.ok(sysFileConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysFileAddReq req) { + SysFile entity = sysFileConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + boolean save = sysFileBaseService.save(entity); + if (!save) { + throw new BizError("数据添加失败"); + } + return Result.ok(entity.getId()); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysFileUpdateReq req) { + SysFile entity = sysFileConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysFileBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + boolean removed = changeDataType(req.getIdList(), FileDataType.DELETE); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 改变数据类型 + * + * @param req 请求参数 + * @return 是否成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result changeDataTypeByIds(SysFileChangeReq req) { + return Result.ok(changeDataType(req.getIdList(), req.getDataType())); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysFilePageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysFile::getId + , SysFile::getUserId + , SysFile::getUserName + , SysFile::getBizId + , SysFile::getBizType + , SysFile::getPermission + , SysFile::getBucket + , SysFile::getStorageType + , SysFile::getUploadTime + , SysFile::getFilePath + , SysFile::getFileName + , SysFile::getFileSize + , SysFile::getFileType + , SysFile::getMd5 + , SysFile::getSm3 + , SysFile::getDataType + , SysFile::getExpireTime + , SysFile::getMemo + , SysFile::getGmtCreate + , SysFile::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysFile::getGmtCreate); + return sysFileBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysFilePageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysFile::getId, req.getId()); + query.eq(Objects.nonNull(req.getUserId()), SysFile::getUserId, req.getUserId()); + query.like(StringUtils.isNotBlank(req.getUserName()), SysFile::getUserName, req.getUserName()); + query.eq(Objects.nonNull(req.getBizId()), SysFile::getBizId, req.getBizId()); + query.eq(Objects.nonNull(req.getPermission()), SysFile::getPermission, req.getPermission()); + query.like(StringUtils.isNotBlank(req.getBizType()), SysFile::getBizType, req.getBizType()); + query.like(StringUtils.isNotBlank(req.getBucket()), SysFile::getBucket, req.getBucket()); + query.like(StringUtils.isNotBlank(req.getStorageType()), SysFile::getStorageType, req.getStorageType()); + QueryUtils.addTimeRange(query, req.getUploadTimeRange(), SysFile::getUploadTime); + query.like(StringUtils.isNotBlank(req.getFilePath()), SysFile::getFilePath, req.getFilePath()); + query.like(StringUtils.isNotBlank(req.getFileName()), SysFile::getFileName, req.getFileName()); + query.eq(Objects.nonNull(req.getFileSize()), SysFile::getFileSize, req.getFileSize()); + query.like(StringUtils.isNotBlank(req.getFileType()), SysFile::getFileType, req.getFileType()); + query.like(StringUtils.isNotBlank(req.getMd5()), SysFile::getMd5, req.getMd5()); + query.like(StringUtils.isNotBlank(req.getSm3()), SysFile::getSm3, req.getSm3()); + query.eq(Objects.nonNull(req.getDataType()), SysFile::getDataType, req.getDataType()); + QueryUtils.addTimeRange(query, req.getExpireTimeRange(), SysFile::getExpireTime); + query.like(StringUtils.isNotBlank(req.getMemo()), SysFile::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysFile::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysFile::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysFile existsEntity(SysFile entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysFile::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysFile::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getBucket()), SysFile::getBucket, entity.getBucket()); + query.eq(StringUtils.isNotBlank(entity.getStorageType()), SysFile::getStorageType, entity.getStorageType()); + query.eq(StringUtils.isNotBlank(entity.getFilePath()), SysFile::getFilePath, entity.getFilePath()); + return sysFileBaseService.getOne(query); + } + + /** + * 批量修改数据类型 + * + * @param idList ID 集合 + * @param dataType 数据类型 + * @return 修改结果 + */ + private boolean changeDataType(List idList, FileDataType dataType) { + // 更新数据 + SysFile updateEntity = new SysFile(); + updateEntity.setDataType(dataType.code()); + // 创建更新条件 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(SysFile::getId, idList); + updateWrapper.set(SysFile::getDataType, dataType.code()); + if (!FileDataType.TEMP.equals(dataType)) { + updateWrapper.set(SysFile::getExpireTime, null); + } + return sysFileBaseService.update(updateWrapper); + } + + + /** + * 定时任务 + */ + @Override + public void doJob() { + // 任务日志code + String code = UuidUtils.get(); + // 任务类型 + TaskType taskType = TaskType.DEL_SYS_FILE; + + // 任务信息 + String info = "开始整理系统文件信息,请稍候..."; + // 保存任务 + TaskBus.init(code, taskType, TaskStatus.ING).info(info).save(); + // 异常 + Exception ex = null; + try { + // 将临时数据改成待删除状态 + int tempCount = jobTempToDelete(); + // 删除待删除状态的数据 + int delCount = jobDeleteFile(); + info = "执行完成,共[{}]条临时数据转换成待删除数据,共[{}]条数据被删除"; + info = TemplateUtils.format(info, tempCount, delCount); + } catch (Exception e) { + ex = e; + info = "执行失败"; + throw e; + } finally { + // 保存任务 + TaskStatus status = Objects.isNull(ex) ? TaskStatus.SUCCESS : TaskStatus.ERROR; + TaskBus.init(code, taskType, status).info(info).save(); + if (Objects.nonNull(ex)) { + // 保存异常日志 + LogBus.init(LogLevel.ERROR, LogBusBaseType.TASK).error(ex).save(); + } + } + } + + /** + * 将临时数据改成待删除状态 + */ + private int jobTempToDelete() { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysFile::getDataType, FileDataType.TEMP.code()); + query.le(SysFile::getExpireTime, Instant.now()); + SysFile updateEntity = new SysFile(); + updateEntity.setDataType(FileDataType.DELETE.code()); + return sysFileBaseService.getBaseMapper().update(updateEntity, query); + } + + /** + * 删除待删除状态的数据 + */ + private int jobDeleteFile() { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysFile::getId, SysFile::getBucket, SysFile::getStorageType, SysFile::getFilePath); + query.eq(SysFile::getDataType, FileDataType.DELETE.code()); + List list = sysFileBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + return CP_NUM0; + } + String type = storageConfig.getType(); + Set ids = new HashSet<>(list.size()); + for (SysFile item : list) { + if (!Objects.equals(type, item.getStorageType())) { + continue; + } + try { + storageService.del(item.getBucket(), item.getFilePath()); + } catch (Exception e) { + log.error("删除文件失败", e); + continue; + } + ids.add(item.getId()); + } + return sysFileBaseService.getBaseMapper().deleteByIds(ids); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysHomeServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysHomeServiceImpl.java new file mode 100644 index 0000000..db3d607 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysHomeServiceImpl.java @@ -0,0 +1,134 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.api.baidu.LocationUtils; +import xtools.api.baidu.WeatherUtils; +import xtools.api.dto.LatAndLngDto; +import xtools.api.dto.LocationDto; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.config.ApiConfig; +import xtools.app.sys.model.dto.resp.SysHomeDataResp; +import xtools.app.sys.service.SysHomeService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.ip.utils.IpUtils; +import xtools.core.StringUtils; +import xtools.core.sys.SysBaseInfoUtils; +import xtools.extend.dto.IpAddrDto; + +import java.util.Objects; + +/** + *

Title : SysHomeServiceImpl

+ *

Description : SysHomeServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 19:50 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysHomeServiceImpl implements SysHomeService { + + private final ApiConfig apiConfig; + + @Resource + private RedisService redisService; + + /** + * 获取数据 + * + * @return 数据 + */ + @Override + public Result getData(String ip) { + // 获取ip地址信息 + IpAddrDto addr = IpUtils.search(ip); + + // 分装数据 + SysHomeDataResp resp = new SysHomeDataResp(); + resp.setJvm(SysBaseInfoUtils.get()); + resp.setIp(ip); + resp.setAddress(IpUtils.searchAddr(addr)); + resp.setWeather(getWeather(addr)); + return Result.ok(resp); + } + + /** + * 获取天气信息 + * + * @param ipAddr 地址信息 + * @return 天气信息 + */ + private String getWeather(IpAddrDto ipAddr) { + if (Objects.isNull(ipAddr)) { + return null; + } + // 获取城市名称 + String city = ipAddr.getCity(); + + AppCache cacheParam = AppCache.SYS_CACHE_HOME_WEATHER; + // 缓存key + String key = cacheParam.key() + city; + // 从缓存获取数据 + String data = redisService.get(key, String.class); + if (StringUtils.isNotBlank(data)) { + return data; + } + + // 获取百度AK + String baiduAk = apiConfig.getBaidu().getAk(); + // 获取位置信息 + LatAndLngDto latAndLng = LocationUtils.getLatAndLng(baiduAk, city); + if (Objects.isNull(latAndLng)) { + return null; + } + // 获取城市信息 + LocationDto cityInfo = LocationUtils.getCityInfo(baiduAk, latAndLng.getLng(), latAndLng.getLat()); + if (Objects.isNull(cityInfo)) { + return null; + } + // 获取天气信息 + JSONObject weather = WeatherUtils.getWeatherFromBaidu(baiduAk, cityInfo.getAdCode().toString()); + if (Objects.isNull(weather)) { + return null; + } + // 获取今天的天气 + data = getToDayWeather(weather); + // 缓存天气信息 + redisService.set(key, data, cacheParam.expireTime()); + return data; + } + + /** + * 获取当天的天气信息 + * + * @param weather 天气信息 + * @return 当天的天气信息 + */ + private String getToDayWeather(JSONObject weather) { + // 天气信息 + JSONObject now = weather.getJSONObject("now"); + // 数据 + String data = ""; + // 地区 + // 天气情况(晴) + data += now.getString("text") + " "; + // 温度 + data += now.getInteger("temp") + "℃ "; + // 风向 + data += now.getString("wind_dir") + now.getString("wind_class") + " "; + // 湿度 + data += "湿度" + now.getInteger("rh") + "%"; + return data; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLogServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLogServiceImpl.java new file mode 100644 index 0000000..96980d6 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLogServiceImpl.java @@ -0,0 +1,198 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import xtools.app.sys.convert.SysLogConvert; +import xtools.app.sys.model.dto.req.SysLogPageReq; +import xtools.app.sys.model.dto.resp.SysLogResp; +import xtools.app.sys.model.entity.SysLog; +import xtools.app.sys.service.SysLogService; +import xtools.app.sys.service.base.SysLogBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.ArrUtils; +import xtools.core.StringUtils; + +import java.time.Instant; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysLogServiceImpl

+ *

Description : 日志记录表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +public class SysLogServiceImpl implements SysLogService, BaseParams { + + @Resource + private SysLogBaseService sysLogBaseService; + + @Resource + private SysLogConvert sysLogConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysLogConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据日志 ID 查询 + * + * @param logId 日志 ID + * @return 结果 + */ + @Override + public Result getByLogId(String logId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysLog::getLogBody); + query.eq(SysLog::getLogId, logId); + SysLog data = sysLogBaseService.getOne(query); + return Result.ok(sysLogConvert.entityToResp(data)); + } + + /** + * 根据traceId查询 + * + * @param traceId traceId + * @return 日志列表 + */ + @Override + public Result> getByTraceId(String traceId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select( + SysLog::getLogId, + SysLog::getTraceId, + SysLog::getParentId, + SysLog::getLogTime, + SysLog::getLogType, + SysLog::getLogLevel, + SysLog::getTitle, + SysLog::getIp, + SysLog::getUri, + SysLog::getThreadType, + SysLog::getAppName, + SysLog::getLocalIp, + SysLog::getPort, + SysLog::getLogBody, + SysLog::getStackTrace, + SysLog::getLogError + ); + query.eq(SysLog::getTraceId, traceId); + query.orderByAsc(SysLog::getLogIndex); + query.orderByAsc(SysLog::getLogTime); + return Result.ok(sysLogConvert.entityToRespList(sysLogBaseService.list(query))); + } + + /** + * 保存 + * + * @param sysLog 日志 + * @return 是否保存成功 + */ + @Override + public boolean save(SysLog sysLog) { + return sysLogBaseService.save(sysLog); + } + + /** + * 删除 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 删除数量 + */ + @Override + public long delete(Instant startTime, Instant endTime) { + if (Objects.isNull(endTime)) { + return CP_NUM0; + } + long end = endTime.toEpochMilli(); + long start = CP_NUM0; + if (Objects.nonNull(startTime)) { + start = startTime.toEpochMilli(); + } + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.between(SysLog::getLogTime, start, end); + return sysLogBaseService.getBaseMapper().delete(query); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysLogPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select( + SysLog::getLogId, + SysLog::getTraceId, + SysLog::getLogTime, + SysLog::getLogType, + SysLog::getLogLevel, + SysLog::getTitle, + SysLog::getIp, + SysLog::getUri, + SysLog::getThreadType, + SysLog::getAppName, + SysLog::getLocalIp, + SysLog::getPort + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysLog::getGmtCreate); + return sysLogBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysLogPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.like(StringUtils.isNotBlank(req.getTraceId()), SysLog::getTraceId, req.getTraceId()); + query.like(StringUtils.isNotBlank(req.getThreadType()), SysLog::getThreadType, req.getThreadType()); + query.eq(Objects.nonNull(req.getLogLevel()), SysLog::getLogLevel, req.getLogLevel()); + query.like(StringUtils.isNotBlank(req.getAppName()), SysLog::getAppName, req.getAppName()); + query.like(StringUtils.isNotBlank(req.getLocalIp()), SysLog::getLocalIp, req.getLocalIp()); + query.like(StringUtils.isNotBlank(req.getPort()), SysLog::getPort, req.getPort()); + query.like(StringUtils.isNotBlank(req.getTitle()), SysLog::getTitle, req.getTitle()); + query.eq(Objects.nonNull(req.getLogType()), SysLog::getLogType, req.getLogType()); + query.like(StringUtils.isNotBlank(req.getIp()), SysLog::getIp, req.getIp()); + query.like(StringUtils.isNotBlank(req.getUri()), SysLog::getUri, req.getUri()); + + Instant[] logTimeRange = req.getLogTimeRange(); + if (ArrUtils.isNotEmpty(logTimeRange) && Objects.equals(logTimeRange.length, CP_NUM2)) { + query.ge(SysLog::getLogTime, logTimeRange[CP_NUM0].toEpochMilli()); + query.le(SysLog::getLogTime, logTimeRange[CP_NUM1].toEpochMilli()); + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLoginServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLoginServiceImpl.java new file mode 100644 index 0000000..f66d3c0 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysLoginServiceImpl.java @@ -0,0 +1,182 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.wf.captcha.GifCaptcha; +import com.wf.captcha.base.Captcha; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.model.dto.TokenDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysLoginConvert; +import xtools.app.sys.model.dto.Sm2KeyDto; +import xtools.app.sys.model.dto.req.SysLoginReq; +import xtools.app.sys.model.entity.SysUser; +import xtools.app.sys.service.SysCommonService; +import xtools.app.sys.service.SysLoginService; +import xtools.app.sys.service.base.SysUserBaseService; +import xtools.app.sys.service.base.SysUserRoleBaseService; +import xtools.app.sys.utils.PasswdUtils; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.base.RedisService; +import xtools.core.StringUtils; +import xtools.core.dto.ArithmeticDto; +import xtools.core.encrypt.Base64Utils; +import xtools.core.extend.ArithmeticUtils; +import xtools.core.extend.RandomUtils; +import xtools.core.img.ImgUtils; + +import java.awt.*; +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysLoginServiceImpl

+ *

Description : SysLoginServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/1/31 14:02 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysLoginServiceImpl implements SysLoginService, BaseParams { + + private final SysCommonService sysCommonService; + private final SysUserRoleBaseService sysUserRoleBaseService; + private final SysUserBaseService sysUserBaseService; + private final SysLoginConvert sysLoginConvert; + @Resource + private RedisService redisService; + + /** + * 获取图片验证码 + * + * @param uid 用户id + * @return 图片验证码 + */ + @Override + public Result captcha(String uid) { + String captcha; + if (Objects.equals(RandomUtils.getRandomInt(CP_NUM2), CP_NUM0)) { + captcha = baseCaptcha(uid); + } else { + captcha = arithmeticCaptcha(uid); + } + return Result.ok(captcha); + } + + /** + * 获取基本验证码 + * + * @param uid 用户id + * @return 验证码 + */ + private String baseCaptcha(String uid) { + // 验证码参数 + int width = 132; + int height = 48; + int len = 4; + // 生成验证码 + // 动态验证码 + GifCaptcha captcha = new GifCaptcha(width, height, len); + captcha.setCharType(Captcha.TYPE_DEFAULT); + + // 常规验证码 +// SpecCaptcha captcha = new SpecCaptcha(width, height, len); + + // 设置内置字体 + try { + captcha.setFont(Captcha.FONT_1); + } catch (IOException | FontFormatException e) { + throw new BizError("验证码生成失败"); + } + + // 获取验证码 + String code = captcha.text().toLowerCase(); + AppCache cacheParam = AppCache.UID_CAPTCHA; + redisService.set(cacheParam.key(uid), code, cacheParam.expireTime()); + + // 获取图片验证码 + return captcha.toBase64(); + } + + /** + * 获取算术验证码 + * + * @param uid 用户id + * @return 算术验证码 + */ + private String arithmeticCaptcha(String uid) { + // 生成验证码 + ArithmeticDto arithmeticDto = ArithmeticUtils.create(); + // 根据随机验证码生成图片验证码 + byte[] imgCode = ImgUtils.getBytesImgCode(128, 36, arithmeticDto.getArithmetic()); + if (imgCode == null) { + throw new BizError("验证码生成失败"); + } + AppCache cacheParam = AppCache.UID_CAPTCHA; + redisService.set(cacheParam.key(uid), arithmeticDto.getResult(), cacheParam.expireTime()); + + // 转换为base64的验证码 + return "data:image/png;base64," + new String(Base64Utils.encode(imgCode)); + } + + /** + * 密码登录 + * + * @param req 登录参数 + * @return 登录结果 + */ + @Override + public Result passwd(SysLoginReq req) { + // 获取uid + String uid = req.getUid(); + // 校验验证码 + AppCache cacheParam = AppCache.UID_CAPTCHA; + String captchaKey = cacheParam.key(uid); + String code = redisService.get(captchaKey, String.class); + if (StringUtils.isBlank(code)) { + throw new BizWarning("验证码已过期"); + } + if (!code.equalsIgnoreCase(req.getCaptcha())) { + throw new BizWarning("验证码错误"); + } + + // 解密密码 + Sm2KeyDto sm2Key = sysCommonService.getSm2Key(uid); + String passwd = PasswdUtils.decrypt(sm2Key, req.getPublicKey(), req.getPasswd()); + + // 查询账号 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysUser::getAccount, req.getAccount()); + List userList = sysUserBaseService.list(query); + + // 数据校验 + if (Objects.isNull(userList) || userList.size() != CP_NUM1) { + throw new BizWarning("账户不存在"); + } + SysUser user = userList.get(CP_NUM0); + if (!Objects.equals(user.getStatus(), CP_NUM1)) { + throw new BizWarning("账户被禁用"); + } + if (!PasswdUtils.check(passwd, user.getPasswd())) { + throw new BizWarning("密码错误"); + } + LoginUserDto loginUserDto = sysLoginConvert.entityToCacheDto(user); + loginUserDto.setRoleIds(sysUserRoleBaseService.getUserRole(user.getId())); + redisService.del(captchaKey); + return Result.ok(AuthUtils.createToken(loginUserDto)); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMenuServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..84f70f3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,466 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysMenuConvert; +import xtools.app.sys.mapper.SysMenuMapper; +import xtools.app.sys.model.dto.req.SysMenuAddReq; +import xtools.app.sys.model.dto.req.SysMenuPageReq; +import xtools.app.sys.model.dto.req.SysMenuTreesReq; +import xtools.app.sys.model.dto.req.SysMenuUpdateReq; +import xtools.app.sys.model.dto.resp.SysMenuResp; +import xtools.app.sys.model.dto.resp.SysMenuTreeResp; +import xtools.app.sys.model.entity.SysMenu; +import xtools.app.sys.service.SysMenuService; +import xtools.app.sys.service.SysPermService; +import xtools.app.sys.service.base.SysMenuBaseService; +import xtools.app.sys.service.base.SysRoleMenuBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.resp.TreeResp; +import xtools.boot.core.utils.TreeUtils; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.ArrUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +/** + *

Title : SysMenuServiceImpl

+ *

Description : 系统菜单表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 22:18:12 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysMenuServiceImpl implements SysMenuService, BaseParams { + + private final SysPermService sysPermService; + + private final SysRoleMenuBaseService sysRoleMenuBaseService; + + private final SysMenuBaseService sysMenuBaseService; + + private final SysMenuConvert sysMenuConvert; + + private final SysMenuMapper sysMenuMapper; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysMenuConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysMenu data = sysMenuBaseService.getById(id); + return Result.ok(sysMenuConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysMenuAddReq req) { + SysMenu entity = sysMenuConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + Long parentId = req.getParentId(); + if (CheckUtils.id(parentId)) { + List treeIdList = new ArrayList<>(); + while (true) { + SysMenu parent = sysMenuBaseService.getParent(parentId); + if (Objects.isNull(parent)) { + break; + } + treeIdList.add(parent.getId()); + parentId = parent.getParentId(); + } + StringJoiner treePath = new StringJoiner(CP_COMMA); + for (Long id : treeIdList.reversed()) { + treePath.add(id.toString()); + } + entity.setTreePath(treePath.toString()); + } else { + entity.setTreePath(CP_EMPTY); + } + boolean saved = sysMenuBaseService.save(entity); + if (!saved) { + throw new BizError("添加失败"); + } + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysMenuUpdateReq req) { + SysMenu entity = sysMenuConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + Long parentId = req.getParentId(); + if (CheckUtils.id(parentId)) { + List treeIdList = new ArrayList<>(); + while (true) { + SysMenu parent = sysMenuBaseService.getParent(parentId); + if (Objects.isNull(parent)) { + break; + } + treeIdList.add(parent.getId()); + parentId = parent.getParentId(); + } + StringJoiner treePath = new StringJoiner(CP_COMMA); + for (Long id : treeIdList.reversed()) { + treePath.add(id.toString()); + } + entity.setTreePath(treePath.toString()); + } else { + entity.setTreePath(CP_EMPTY); + } + boolean updated = sysMenuBaseService.updateById(entity); + if (!updated) { + throw new BizError("修改失败"); + } + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + if (CollectionUtils.isEmpty(idList)) { + throw new BizError("删除失败"); + } + for (Long id : idList) { + if (existsByPid(id)) { + throw new BizWarning("该菜单下有子菜单,请先删除子菜单"); + } + } + boolean removed = sysMenuBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + sysRoleMenuBaseService.delByMenuId(idList); + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 判断根据 Pid 部门是否存在 + * + * @param pid 部门 ID + * @return 存在结果 + */ + private boolean existsByPid(Long pid) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询条件 + query.eq(SysMenu::getParentId, pid); + return sysMenuBaseService.exists(query); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysMenuPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysMenu::getId, + SysMenu::getMenuName, + SysMenu::getMenuIcon, + SysMenu::getMenuType, + SysMenu::getMenuVisible, + SysMenu::getRouteName, + SysMenu::getRoutePath, + SysMenu::getComponent, + SysMenu::getBtnPerm, + SysMenu::getInterfacePermType, + SysMenu::getInterfacePermUri, + SysMenu::getMenuCache, + SysMenu::getGmtCreate, + SysMenu::getGmtModified + ); + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysMenu::getGmtCreate); + return sysMenuBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysMenuPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysMenu::getId, req.getId()); + query.eq(Objects.nonNull(req.getParentId()), SysMenu::getParentId, req.getParentId()); + query.like(StringUtils.isNotBlank(req.getTreePath()), SysMenu::getTreePath, req.getTreePath()); + query.eq(Objects.nonNull(req.getAppId()), SysMenu::getAppId, req.getAppId()); + query.like(StringUtils.isNotBlank(req.getMenuName()), SysMenu::getMenuName, req.getMenuName()); + query.like(StringUtils.isNotBlank(req.getMenuIcon()), SysMenu::getMenuIcon, req.getMenuIcon()); + query.like(StringUtils.isNotBlank(req.getMenuType()), SysMenu::getMenuType, req.getMenuType()); + query.eq(Objects.nonNull(req.getMenuVisible()), SysMenu::getMenuVisible, req.getMenuVisible()); + query.eq(Objects.nonNull(req.getSort()), SysMenu::getSort, req.getSort()); + query.like(StringUtils.isNotBlank(req.getRouteName()), SysMenu::getRouteName, req.getRouteName()); + query.like(StringUtils.isNotBlank(req.getRoutePath()), SysMenu::getRoutePath, req.getRoutePath()); + query.like(StringUtils.isNotBlank(req.getComponent()), SysMenu::getComponent, req.getComponent()); + query.like(StringUtils.isNotBlank(req.getBtnPerm()), SysMenu::getBtnPerm, req.getBtnPerm()); + query.like(StringUtils.isNotBlank(req.getInterfacePermType()), SysMenu::getInterfacePermType, req.getInterfacePermType()); + query.like(StringUtils.isNotBlank(req.getInterfacePermUri()), SysMenu::getInterfacePermUri, req.getInterfacePermUri()); + query.eq(Objects.nonNull(req.getAlwaysShow()), SysMenu::getAlwaysShow, req.getAlwaysShow()); + query.eq(Objects.nonNull(req.getMenuCache()), SysMenu::getMenuCache, req.getMenuCache()); + query.like(StringUtils.isNotBlank(req.getMenuRedirect()), SysMenu::getMenuRedirect, req.getMenuRedirect()); + query.like(StringUtils.isNotBlank(req.getMenuParams()), SysMenu::getMenuParams, req.getMenuParams()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysMenu::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysMenu::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysMenu::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(SysMenu entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysMenu::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getParentId()), SysMenu::getParentId, entity.getParentId()); + query.eq(StringUtils.isNotBlank(entity.getMenuType()), SysMenu::getMenuType, entity.getMenuType()); + query.eq(StringUtils.isNotBlank(entity.getMenuName()), SysMenu::getMenuName, entity.getMenuName()); + return sysMenuBaseService.exists(query); + } + + /** + * 获取表格菜单树 + * + * @param req 请求参数 + * @return 菜单树 + */ + @Override + public Result> treeTable(SysMenuPageReq req) { + JSONObject reqJson = JSONObject.from(req); + boolean hasReq = false; + for (String key : reqJson.keySet()) { + String data = reqJson.getString(key); + if (StringUtils.isNotBlank(data)) { + hasReq = true; + break; + } + } + Set noParentIdSet = getNoInParentId(req); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + if (hasReq) { + query.or(q -> setQueryWrapper(q, req)); + } + if (CollectionUtils.isNotEmpty(noParentIdSet)) { + query.or(q -> q.in(SysMenu::getId, noParentIdSet)); + } + // 排序 + query.orderByAsc(SysMenu::getSort); + query.orderByAsc(SysMenu::getGmtCreate); + return Result.ok(buildTree(sysMenuBaseService.list(query))); + } + + /** + * 获取菜单树 + * + * @param req 请求参数 + * @return 菜单树 + */ + @Override + public Result> trees(SysMenuTreesReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询字段 + query.select(SysMenu::getId, SysMenu::getParentId, SysMenu::getMenuName, SysMenu::getMenuType); + // 添加查询条件 + query.in(CollectionUtils.isNotEmpty(req.getMenuType()), SysMenu::getMenuType, req.getMenuType()); + // 排序 + query.orderByAsc(SysMenu::getSort); + query.orderByAsc(SysMenu::getGmtCreate); + // 查询 + List sysMenuList = sysMenuBaseService.list(query); + if (CollectionUtils.isEmpty(sysMenuList)) { + return Result.ok(new ArrayList<>()); + } + // 数据处理 + Boolean labelAddMenuType = req.getLabelAddMenuType(); + if (Objects.isNull(labelAddMenuType)) { + labelAddMenuType = false; + } + List list = new ArrayList<>(); + for (SysMenu item : sysMenuList) { + TreeResp treeResp = new TreeResp(); + treeResp.setParentId(item.getParentId()); + treeResp.setValue(item.getId()); + treeResp.setLabel(labelAddMenuType ? item.getMenuType() + CP_COLON + item.getMenuName() : item.getMenuName()); + list.add(treeResp); + } + return Result.ok(TreeUtils.getChild(0L, list)); + } + + /** + * 构建菜单树 + * + * @param list 菜单数据 + * @return 菜单树 + */ + @Override + public List buildTree(List list) { + if (CollectionUtils.isEmpty(list)) { + return new ArrayList<>(); + } + List dataList = sysMenuConvert.entityToTreeRespList(list); + return sysMenuBaseService.getChildren(0L, dataList); + } + + /** + * 获取路由列表 + * + * @param list 菜单数据 + * @return 路由列表 + */ + @Override + public List getRouteList(List list) { + List sysMenuRespList = sysMenuConvert.entityToRespList(list); + // 过滤路由数据 + return sysMenuRespList.stream().filter(item -> "M".equals(item.getMenuType())).toList(); + } + + /** + * 根据角色 ID 获取菜单列表 + * + * @param roleIds 角色 ID 集合 + * @return 菜单列表 + */ + @Override + public List getMenuByRoleIds(List roleIds) { + return sysMenuMapper.getMenuByRoleIds(roleIds); + } + + /** + * 获取按钮权限 + * + * @param roleIds 角色 ID 集合 + * @return 按钮权限 + */ + @Override + public List getBtnPermByRoleIds(List roleIds) { + List btnPerms = sysMenuMapper.getBtnPermByRoleIds(roleIds); + if (CollectionUtils.isEmpty(btnPerms)) { + return null; + } + return btnPerms.stream().map(SysMenu::getBtnPerm).toList(); + } + + /** + * 获取没有列表的父部门的 ID 集合 + * + * @param req 请求参数 + * @return ID 集合 + */ + private Set getNoInParentId(SysMenuPageReq req) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysMenu::getId, SysMenu::getTreePath); + setQueryWrapper(query, req); + return getNoInParentIdSet(sysMenuBaseService.list(query)); + } + + /** + * 获取没有在列表的父部门的 ID 集合 + * + * @param list 数据 + * @return ID 集合 + */ + private Set getNoInParentIdSet(List list) { + if (CollectionUtils.isEmpty(list)) { + return null; + } + Set idSet = list.stream().map(SysMenu::getId).collect(Collectors.toSet()); + Set noParentIdSet = new HashSet<>(); + for (SysMenu entity : list) { + String treePath = entity.getTreePath(); + if (StringUtils.isBlank(treePath)) { + continue; + } + List treeIds = ArrUtils.toLongList(treePath); + treeIds.forEach(item -> { + if (!idSet.contains(item)) { + noParentIdSet.add(item); + } + }); + } + return noParentIdSet; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMonitorServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMonitorServiceImpl.java new file mode 100644 index 0000000..c8f2f64 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysMonitorServiceImpl.java @@ -0,0 +1,72 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.service.SysMonitorService; +import xtools.boot.api.model.dto.Result; +import xtools.boot.cache.redis.monitor.RedisMonitor; +import xtools.boot.db.mybatis.enums.MySqlMonitorEnums; +import xtools.boot.db.mybatis.monitor.MySqlMonitor; +import xtools.boot.elasticsearch.enums.ElasticsearchMonitorEnums; +import xtools.boot.elasticsearch.monitor.ElasticsearchMonitor; + +import java.util.List; + +/** + *

Title : SysMonitorServiceImpl

+ *

Description : SysMonitorServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 11:51 + */ +@Primary +@Service +public class SysMonitorServiceImpl implements SysMonitorService { + + @Resource + private RedisMonitor redisMonitor; + + @Resource + private MySqlMonitor mySqlMonitor; + + @Resource + private ElasticsearchMonitor elasticsearchMonitor; + + /** + * 获取redis监控数据 + * + * @return redis监控数据 + */ + @Override + public Result redis() { + return Result.ok(redisMonitor.stats()); + } + + /** + * 获取mysql监控数据 + * + * @param type 监控类型 + * @return mysql监控数据 + */ + @Override + public Result> mysql(MySqlMonitorEnums type) { + return Result.ok(mySqlMonitor.info(type)); + } + + /** + * 获取elasticsearch监控数据 + * + * @param type 监控类型 + * @return elasticsearch监控数据 + */ + @Override + public Result elasticsearch(ElasticsearchMonitorEnums type) { + return Result.ok(elasticsearchMonitor.info(type)); + } +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysNoticeServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..45b4370 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,367 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysNoticeConvert; +import xtools.app.sys.file.service.SysFileOptService; +import xtools.app.sys.file.utils.FileIdUtils; +import xtools.app.sys.model.dto.req.SysNoticeAddReq; +import xtools.app.sys.model.dto.req.SysNoticePageReq; +import xtools.app.sys.model.dto.req.SysNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysNoticeResp; +import xtools.app.sys.model.entity.SysNotice; +import xtools.app.sys.model.entity.SysUser; +import xtools.app.sys.model.entity.SysUserNotice; +import xtools.app.sys.service.SysNoticeService; +import xtools.app.sys.service.SysUserNoticeService; +import xtools.app.sys.service.base.SysNoticeBaseService; +import xtools.app.sys.service.base.SysUserBaseService; +import xtools.app.sys.service.base.SysUserNoticeBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

Title : SysNoticeServiceImpl

+ *

Description : 系统通知公告表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-15 10:27:59 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysNoticeServiceImpl implements SysNoticeService, BaseParams { + + private final SysFileOptService sysFileOptService; + + private final SysUserNoticeService sysUserNoticeService; + + private final SysNoticeBaseService sysNoticeBaseService; + + private final SysUserNoticeBaseService sysUserNoticeBaseService; + + private final SysUserBaseService sysUserBaseService; + + private final SysNoticeConvert sysNoticeConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysNoticeConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysNotice data = sysNoticeBaseService.getById(id); + SysNoticeResp resp = sysNoticeConvert.entityToResp(data); + if (Objects.equals(data.getTargetType(), CP_NUM2)) { + resp.setTargetUserIds(sysUserNoticeService.getUserIdByNoticeId(id)); + } + List uid = new ArrayList<>(); + uid.add(data.getPublisherId()); + uid.add(data.getCreateBy()); + uid.add(data.getUpdateBy()); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUser::getId, SysUser::getNickname); + query.in(SysUser::getId, uid); + List userList = sysUserBaseService.list(query); + Map userMap = userList.stream().collect(Collectors.toMap(SysUser::getId, SysUser::getNickname)); + resp.setPublisher(userMap.get(data.getPublisherId())); + resp.setCreateBy(userMap.get(data.getCreateBy())); + resp.setUpdateBy(userMap.get(data.getUpdateBy())); + return Result.ok(resp); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysNoticeAddReq req) { + SysNotice entity = sysNoticeConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + entity.setCreateBy(loginUser.getId()); + entity.setUpdateBy(loginUser.getId()); + boolean save = sysNoticeBaseService.save(entity); + if (!save) { + throw new BizError("数据添加失败"); + } + // 获取所有的文件ID + List ids = FileIdUtils.get(req.getContentMd()); + boolean success = sysFileOptService.success(ids); + if (!success) { + throw new BizError("文件处理失败"); + } + if (Objects.equals(entity.getTargetType(), CP_NUM1)) { + sysUserNoticeService.saveByNoticeId(entity.getId(), null, true); + } else { + sysUserNoticeService.saveByNoticeId(entity.getId(), req.getTargetUserIds(), false); + } + return Result.ok(true); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysNoticeUpdateReq req) { + SysNotice entity = sysNoticeConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + // 获取原始数据 + SysNotice oldEntity = sysNoticeBaseService.getById(req.getId()); + if (Objects.isNull(oldEntity)) { + throw new BizWarning("数据不存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + entity.setUpdateBy(loginUser.getId()); + boolean updated = sysNoticeBaseService.updateById(entity); + if (!updated) { + throw new BizError("数据修改失败"); + } + // 获取所有的原文件ID + List oldIds = FileIdUtils.get(oldEntity.getContentMd()); + boolean delete = sysFileOptService.delete(oldIds); + if (!delete) { + throw new BizError("文件处理失败"); + } + // 获取所有的文件ID + List ids = FileIdUtils.get(req.getContentMd()); + boolean success = sysFileOptService.success(ids); + if (!success) { + throw new BizError("文件处理失败"); + } + if (Objects.equals(entity.getTargetType(), CP_NUM1)) { + sysUserNoticeService.saveByNoticeId(entity.getId(), null, true); + } else { + sysUserNoticeService.saveByNoticeId(entity.getId(), req.getTargetUserIds(), false); + } + return Result.ok(true); + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysNotice::getContentMd); + query.in(SysNotice::getId, req.getIdList()); + List list = sysNoticeBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + throw new BizWarning("数据不存在"); + } + // 获取所有要删除的文件ID + List fileIds = new ArrayList<>(); + for (SysNotice item : list) { + List ids = FileIdUtils.get(item.getContentMd()); + if (CollectionUtils.isEmpty(ids)) { + continue; + } + fileIds.addAll(ids); + } + + // 删除数据 + boolean removed = sysNoticeBaseService.removeByIds(req.getIdList()); + if (!removed) { + throw new BizError("删除失败"); + } + + // 删除文件 + boolean deleted = sysFileOptService.delete(fileIds); + if (!deleted) { + throw new BizError("文件处理失败"); + } + + // 删除关联数据 + LambdaQueryWrapper delete = new LambdaQueryWrapper<>(); + delete.in(SysUserNotice::getNoticeId, req.getIdList()); + sysUserNoticeBaseService.remove(delete); + return Result.ok(true); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysNoticePageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysNotice::getId + , SysNotice::getTitle +// , SysNotice::getContentMd +// , SysNotice::getContentHtml + , SysNotice::getType + , SysNotice::getLevel + , SysNotice::getTargetType + , SysNotice::getPublisherId + , SysNotice::getPublishStatus + , SysNotice::getPublishTime + , SysNotice::getRevokeTime + , SysNotice::getCreateBy + , SysNotice::getUpdateBy + , SysNotice::getIsDeleted + , SysNotice::getMemo + , SysNotice::getGmtCreate + , SysNotice::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysNotice::getGmtCreate); + return sysNoticeBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysNoticePageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysNotice::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getTitle()), SysNotice::getTitle, req.getTitle()); + query.like(StringUtils.isNotBlank(req.getContentMd()), SysNotice::getContentMd, req.getContentMd()); + query.like(StringUtils.isNotBlank(req.getContentHtml()), SysNotice::getContentHtml, req.getContentHtml()); + query.eq(Objects.nonNull(req.getType()), SysNotice::getType, req.getType()); + query.like(StringUtils.isNotBlank(req.getLevel()), SysNotice::getLevel, req.getLevel()); + query.eq(Objects.nonNull(req.getTargetType()), SysNotice::getTargetType, req.getTargetType()); + query.eq(Objects.nonNull(req.getPublisherId()), SysNotice::getPublisherId, req.getPublisherId()); + query.eq(Objects.nonNull(req.getPublishStatus()), SysNotice::getPublishStatus, req.getPublishStatus()); + QueryUtils.addTimeRange(query, req.getPublishTimeRange(), SysNotice::getPublishTime); + QueryUtils.addTimeRange(query, req.getRevokeTimeRange(), SysNotice::getRevokeTime); + query.eq(Objects.nonNull(req.getCreateBy()), SysNotice::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysNotice::getUpdateBy, req.getUpdateBy()); + query.eq(Objects.nonNull(req.getIsDeleted()), SysNotice::getIsDeleted, req.getIsDeleted()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysNotice::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysNotice::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysNotice::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysNotice existsEntity(SysNotice entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysNotice::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysNotice::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getTitle()), SysNotice::getTitle, entity.getTitle()); + return sysNoticeBaseService.getOne(query); + } + + /** + * 发布 + * + * @param req ID 集合 + * @return 发布结果 + */ + @Override + public Result publish(IdListReq req) { + LoginUserDto loginUser = AuthUtils.get(); + + SysNotice entity = new SysNotice(); + entity.setPublisherId(loginUser.getId()); + entity.setPublishStatus(CP_NUM1); + entity.setPublishTime(Instant.now()); + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysNotice::getId, req.getIdList()); + boolean updated = sysNoticeBaseService.update(entity, query); + if (!updated) { + throw new BizError("发布失败"); + } + return Result.ok(true); + } + + /** + * 撤回 + * + * @param req ID 集合 + * @return 撤回结果 + */ + @Override + public Result revoke(IdListReq req) { + SysNotice entity = new SysNotice(); + entity.setPublishStatus(CP_NUM2); + entity.setRevokeTime(Instant.now()); + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysNotice::getId, req.getIdList()); + boolean updated = sysNoticeBaseService.update(entity, query); + if (!updated) { + throw new BizError("撤回失败"); + } + return Result.ok(true); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysParamServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysParamServiceImpl.java new file mode 100644 index 0000000..673af86 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysParamServiceImpl.java @@ -0,0 +1,412 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.api.SysDictItemApi; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysParamConvert; +import xtools.app.sys.model.dto.excel.SysParamExcel; +import xtools.app.sys.model.dto.req.SysParamAddReq; +import xtools.app.sys.model.dto.req.SysParamPageReq; +import xtools.app.sys.model.dto.req.SysParamUpdateReq; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.app.sys.model.dto.resp.SysParamResp; +import xtools.app.sys.model.entity.SysParam; +import xtools.app.sys.param.utils.SysParamUtils; +import xtools.app.sys.service.SysParamService; +import xtools.app.sys.service.base.SysParamBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

Title : SysParamServiceImpl

+ *

Description : 系统参数表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-18 11:35:47 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysParamServiceImpl implements SysParamService, BaseParams { + + private final SysParamBaseService sysParamBaseService; + private final SysDictItemApi sysDictItemApi; + private final SysParamConvert sysParamConvert; + @Resource + private RedisService redisService; + + /** + * 初始化系统参数缓存 + */ + @Override + public void init() { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysParam::getParamKey + , SysParam::getData + , SysParam::getDataType + ); + List list = sysParamBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + log.info("没有需要初始化的系统参数"); + return; + } + for (SysParam item : list) { + redisService.set(SysParamUtils.getCacheKey(item.getDataType(), item.getParamKey()), item.getData()); + log.info("初始化系统参数缓存成功,key={}", item.getParamKey()); + } + } + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysParamConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysParam entity = sysParamBaseService.getById(id); + Integer dataType = entity.getDataType(); + String data = entity.getData(); + if (Objects.equals(dataType, CP_NUM1)) { + data = JSONObject.parseObject(data).toJSONString(JSONWriter.Feature.PrettyFormat); + } else if (Objects.equals(dataType, CP_NUM2)) { + data = JSONArray.parse(data, JSONReader.Feature.TrimString).toJSONString(JSONWriter.Feature.PrettyFormat); + } else { + throw new BizWarning("数据类型错误"); + } + entity.setData(data); + return Result.ok(sysParamConvert.entityToResp(entity)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysParamAddReq req) { + // 校验数据格式 + req.setData(checkDataFormat(req.getData(), req.getDataType())); + SysParam entity = sysParamConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + entity.setCreateBy(loginUser.getId()); + entity.setUpdateBy(loginUser.getId()); + boolean save = sysParamBaseService.save(entity); + if (!save) { + throw new BizWarning("添加失败"); + } + redisService.set(SysParamUtils.getCacheKey(entity.getDataType(), entity.getParamKey()), entity.getData()); + return Result.ok(true); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysParamUpdateReq req) { + // 校验数据格式 + req.setData(checkDataFormat(req.getData(), req.getDataType())); + SysParam entity = sysParamConvert.updateReqToEntity(req); + Long id = entity.getId(); + if (CheckUtils.id(id) && Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + // 获取原数据 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + if (CheckUtils.id(id)) { + query.eq(SysParam::getId, id); + } else { + query.eq(SysParam::getParamKey, req.getParamKey()); + } + SysParam oldEntity = sysParamBaseService.getOne(query); + if (Objects.isNull(oldEntity)) { + throw new BizWarning("数据不存在"); + } + entity.setId(oldEntity.getId()); + LoginUserDto loginUser = AuthUtils.get(); + entity.setUpdateBy(loginUser.getId()); + boolean updated = sysParamBaseService.updateById(entity); + if (!updated) { + throw new BizWarning("修改失败"); + } + redisService.set(SysParamUtils.getCacheKey(entity.getDataType(), entity.getParamKey()), entity.getData()); + // 如果修改了key或数据类型,则删除原缓存 + if (!Objects.equals(oldEntity.getDataType(), entity.getDataType()) || !Objects.equals(oldEntity.getParamKey(), entity.getParamKey())) { + redisService.del(SysParamUtils.getCacheKey(oldEntity.getDataType(), oldEntity.getParamKey())); + } + return Result.ok(true); + } + + /** + * 校验数据格式 + * + * @param data 数据 + * @param dataType 数据类型 + */ + private String checkDataFormat(String data, Integer dataType) { + if (Objects.equals(dataType, CP_NUM1)) { + try { + return JSONObject.parseObject(data).toJSONString(); + } catch (Exception e) { + throw new BizWarning("数据格式非标准JSON"); + } + } else if (Objects.equals(dataType, CP_NUM2)) { + try { + return JSONArray.parse(data, JSONReader.Feature.TrimString).toJSONString(); + } catch (Exception e) { + throw new BizWarning("数据格式非标准JsonArray"); + } + } else { + throw new BizWarning("数据类型错误"); + } + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + List idList = req.getIdList(); + if (CollectionUtils.isEmpty(idList)) { + return Result.ok(true); + } + // 获取待删除的数据(用于清除缓存) + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysParam::getParamKey, SysParam::getDataType); + query.in(SysParam::getId, idList); + List list = sysParamBaseService.list(query); + + // 删除数据 + boolean removed = sysParamBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + + // 清除缓存 + for (SysParam entity : list) { + redisService.del(SysParamUtils.getCacheKey(entity.getDataType(), entity.getParamKey())); + } + return Result.ok(true); + } + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List exportExcel(SysParamPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysParam::getId + , SysParam::getParamKey + , SysParam::getData + , SysParam::getDataType + , SysParam::getCreateBy + , SysParam::getUpdateBy + , SysParam::getMemo + , SysParam::getGmtCreate + , SysParam::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysParam::getGmtCreate); + List dataList = sysParamBaseService.list(query); + + // 获取字典 + List dictList = getDictList(); + Map dictMap = dictList.stream().collect(Collectors.toMap( + SysDictItemResp::getValue, + SysDictItemResp::getLabel + )); + return dataList.stream().map(item -> { + SysParamExcel dto = sysParamConvert.entityToExcel(item); + dto.setDataType(dictMap.get(item.getDataType().toString())); + return dto; + }).toList(); + } + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List dataList) { + // 获取字典 + List dictList = getDictList(); + Map dictMap = dictList.stream().collect(Collectors.toMap( + SysDictItemResp::getLabel, + SysDictItemResp::getValue + )); + for (SysParamExcel excel : dataList) { + SysParam item = sysParamConvert.excelToEntity(excel); + item.setDataType(Integer.parseInt(dictMap.get(excel.getDataType()))); + SysParam dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + boolean save = sysParamBaseService.save(item); + if (!save) { + throw new BizError("新增失败"); + } + } else { + // 修改 + item.setId(dbItem.getId()); + boolean updated = sysParamBaseService.updateById(item); + if (!updated) { + throw new BizError("修改失败"); + } + } + } + for (SysParamExcel excel : dataList) { + redisService.set(SysParamUtils.getCacheKey(Integer.parseInt(dictMap.get(excel.getDataType())), excel.getParamKey()), excel.getData()); + } + } + + /** + * 获取字典列表 + * + * @return 字典列表 + */ + private List getDictList() { + Result> dictResult = sysDictItemApi.getByCode("SYS_PARAM_DATA_TYPE"); + return dictResult.data(); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysParamPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysParam::getId + , SysParam::getParamKey +// , SysParam::getData + , SysParam::getDataType +// , SysParam::getCreateBy +// , SysParam::getUpdateBy + , SysParam::getMemo + , SysParam::getGmtCreate + , SysParam::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysParam::getGmtCreate); + return sysParamBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysParamPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysParam::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getParamKey()), SysParam::getParamKey, req.getParamKey()); + query.like(StringUtils.isNotBlank(req.getData()), SysParam::getData, req.getData()); + query.eq(Objects.nonNull(req.getDataType()), SysParam::getDataType, req.getDataType()); + query.eq(Objects.nonNull(req.getCreateBy()), SysParam::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysParam::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysParam::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysParam::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysParam::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysParam existsEntity(SysParam entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysParam::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysParam::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getParamKey()), SysParam::getParamKey, entity.getParamKey()); + return sysParamBaseService.getOne(query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysPermServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysPermServiceImpl.java new file mode 100644 index 0000000..370db80 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysPermServiceImpl.java @@ -0,0 +1,100 @@ +package xtools.app.sys.service.impl; + +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.auth.model.dto.InterfacePermDto; +import xtools.app.sys.auth.utils.PremUtils; +import xtools.app.sys.mapper.SysMenuMapper; +import xtools.app.sys.model.entity.SysInterfacePerm; +import xtools.app.sys.service.SysPermService; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.core.ArrUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.extend.JsonUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

Title : SysPermServiceImpl

+ *

Description : SysPermServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 20:45 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysPermServiceImpl implements SysPermService, BaseParams { + + private final SysMenuMapper sysMenuMapper; + + @Resource + private RedisService redisService; + + /** + * 重新加载权限缓存 + */ + @Override + public void reloadPermCache() { + Map> interfacePerm = getSysInterfacePerm(); + if (CollectionUtils.isEmpty(interfacePerm)) { + return; + } + Map permCache = new HashMap<>(CP_NUM16); + interfacePerm.forEach((key, value) -> permCache.put(key, JsonUtils.toStr(value))); + + String cacheKey = PremUtils.getCacheKey(); + redisService.del(cacheKey); + redisService.hashPutAll(cacheKey, permCache); + log.info("uri权限缓存加载成功"); + } + + /** + * 获取系统接口权限 + * + * @return 系统接口权限 + */ + private Map> getSysInterfacePerm() { + Map> permMap = new HashMap<>(CP_NUM16); + List sysInterfacePerm = sysMenuMapper.getSysInterfacePerm(); + if (CollectionUtils.isEmpty(sysInterfacePerm)) { + return permMap; + } + for (SysInterfacePerm item : sysInterfacePerm) { + String roleIds = item.getRoleIds(); + String type = item.getType(); + String uri = item.getUri(); + + String moduleName = PremUtils.getModuleName(uri); + if (StringUtils.isBlank(moduleName)) { + continue; + } + + String key = moduleName + CP_COLON + PremUtils.getPermType(type); + + InterfacePermDto data = new InterfacePermDto(); + data.setType(type); + data.setUri(uri); + if (StringUtils.isNotBlank(roleIds)) { + data.setRoleIds(ArrUtils.toLongList(roleIds)); + } + List value = permMap.computeIfAbsent(key, k -> new ArrayList<>()); + value.add(data); + } + return permMap; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRiskServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRiskServiceImpl.java new file mode 100644 index 0000000..4c7ec76 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRiskServiceImpl.java @@ -0,0 +1,428 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysRiskConvert; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.mapper.SysRiskMapper; +import xtools.app.sys.model.dto.excel.SysRiskExcel; +import xtools.app.sys.model.dto.req.SysRiskAddReq; +import xtools.app.sys.model.dto.req.SysRiskPageReq; +import xtools.app.sys.model.dto.req.SysRiskUpdateReq; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.app.sys.model.entity.SysRisk; +import xtools.app.sys.risk.utils.IpRiskUtils; +import xtools.app.sys.risk.utils.UriRiskUtils; +import xtools.app.sys.service.SysRiskService; +import xtools.app.sys.service.base.SysRiskBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.ArrUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysRiskServiceImpl

+ *

Description : 系统风控表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysRiskServiceImpl implements SysRiskService, BaseParams { + + private final SysRiskBaseService sysRiskBaseService; + + private final SysRiskConvert sysRiskConvert; + + private final SysRiskMapper sysRiskMapper; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysRiskConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysRisk data = sysRiskBaseService.getById(id); + return Result.ok(sysRiskConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysRiskAddReq req) { + SysRisk entity = sysRiskConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + entity.setCreateBy(loginUser.getId()); + entity.setUpdateBy(loginUser.getId()); + return Result.ok(sysRiskBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysRiskUpdateReq req) { + SysRisk entity = sysRiskConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + entity.setUpdateBy(loginUser.getId()); + return Result.ok(sysRiskBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + boolean removed = sysRiskBaseService.removeByIds(req.getIdList()); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List exportExcel(SysRiskPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysRisk::getId + , SysRisk::getSysType + , SysRisk::getType + , SysRisk::getData + , SysRisk::getCreateBy + , SysRisk::getUpdateBy + , SysRisk::getMemo + , SysRisk::getGmtCreate + , SysRisk::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysRisk::getGmtCreate); + List dataList = sysRiskBaseService.list(query); + return dataList.stream().map(sysRiskConvert::entityToExcel).toList(); + } + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List dataList) { + for (SysRiskExcel excel : dataList) { + SysRisk item = sysRiskConvert.excelToEntity(excel); + SysRisk dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + sysRiskBaseService.save(item); + } else { + // 修改 + item.setId(dbItem.getId()); + sysRiskBaseService.updateById(item); + } + } + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysRiskPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysRisk::getId + , SysRisk::getSysType + , SysRisk::getType + , SysRisk::getData + , SysRisk::getCreateBy + , SysRisk::getUpdateBy + , SysRisk::getMemo + , SysRisk::getGmtCreate + , SysRisk::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysRisk::getGmtCreate); + return sysRiskBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysRiskPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysRisk::getId, req.getId()); + query.eq(Objects.nonNull(req.getSysType()), SysRisk::getSysType, req.getSysType()); + query.eq(Objects.nonNull(req.getType()), SysRisk::getType, req.getType()); + query.like(StringUtils.isNotBlank(req.getData()), SysRisk::getData, req.getData()); + query.eq(Objects.nonNull(req.getCreateBy()), SysRisk::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysRisk::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysRisk::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysRisk::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysRisk::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysRisk existsEntity(SysRisk entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysRisk::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysRisk::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getSysType()), SysRisk::getSysType, entity.getSysType()); + query.eq(Objects.nonNull(entity.getType()), SysRisk::getType, entity.getType()); + return sysRiskBaseService.getOne(query); + } + + /** + * 根据类型获取数据 + * + * @param type 类型 + * @return 数据 + */ + @Override + public Result> getByType(SysRiskType type) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysRisk::getSysType, SysRisk::getData); + // 查询条件 + query.eq(SysRisk::getType, type.code()); + return Result.ok(sysRiskConvert.entityToRespList(sysRiskBaseService.list(query))); + } + + /** + * 添加IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + @Override + public Result addIp(String sysType, String ip) { + sysRiskMapper.addIp(SysRiskType.IP.code(), sysType, CP_COMMA + ip); + return Result.ok(true); + } + + /** + * 移除IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 移除结果 + */ + @Override + public Result removeIp(String sysType, String ip) { + sysRiskMapper.removeIp(SysRiskType.IP.code(), sysType, CP_COMMA + ip); + return Result.ok(true); + } + + /** + * 获取风控IP数据 + * + * @param sysType 系统类型 + * @return 风控IP数据 + */ + @Override + public Result> getIp(String sysType) { + String data = getData(SysRiskType.IP, sysType); + if (StringUtils.isBlank(data)) { + return Result.ok(new ArrayList<>()); + } else { + if (data.startsWith(CP_COMMA)) { + data = data.substring(CP_NUM1); + } + return Result.ok(ArrUtils.toStringList(data)); + } + } + + /** + * 保存Ip + * + * @param sysType 系统类型 + * @param ipList IP列表 + * @return 保存结果 + */ + @Override + public Result saveIp(String sysType, List ipList) { + String data; + if (CollectionUtils.isEmpty(ipList)) { + data = CP_EMPTY; + } else { + data = CP_COMMA + String.join(CP_COMMA, ipList); + } + boolean saved = saveData(SysRiskType.IP, sysType, data); + if (!saved) { + throw new BizError("保存失败"); + } + IpRiskUtils.addAll(sysType, data); + return Result.ok(true); + } + + /** + * 获取风控URI数据 + * + * @param sysType 系统类型 + * @return 风控URI数据 + */ + @Override + public Result> getUri(String sysType) { + String data = getData(SysRiskType.URI, sysType); + if (StringUtils.isBlank(data)) { + return Result.ok(new ArrayList<>()); + } else { + return Result.ok(ArrUtils.toStringList(data)); + } + } + + /** + * 保存URI + * + * @param sysType 系统类型 + * @param uriList IP列表 + * @return 保存结果 + */ + @Override + public Result saveUri(String sysType, List uriList) { + String data; + if (CollectionUtils.isEmpty(uriList)) { + data = CP_EMPTY; + } else { + data = String.join(CP_COMMA, uriList); + } + boolean saved = saveData(SysRiskType.URI, sysType, data); + if (!saved) { + throw new BizError("保存失败"); + } + UriRiskUtils.save(sysType, data); + return Result.ok(true); + } + + /** + * 获取风控数据 + * + * @param type 风控类型 + * @param sysType 系统类型 + * @return 风控数据 + */ + private String getData(SysRiskType type, String sysType) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysRisk::getData); + // 查询条件 + query.eq(SysRisk::getType, type.code()); + query.eq(SysRisk::getSysType, sysType); + SysRisk data = sysRiskBaseService.getOne(query); + return Objects.isNull(data) ? null : data.getData(); + } + + /** + * 保存数据 + * + * @param type 系统参数类型 + * @param sysType 系统类型 + * @param data 系统参数值 + * @return 保存结果 + */ + private boolean saveData(SysRiskType type, String sysType, String data) { + // 更新实体 + SysRisk entity = new SysRisk(); + entity.setData(data); + + // 创建条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysRisk::getType, type.code()); + query.eq(SysRisk::getSysType, sysType); + + // 更新 + return sysRiskBaseService.update(entity, query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleMenuServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleMenuServiceImpl.java new file mode 100644 index 0000000..849d9f5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleMenuServiceImpl.java @@ -0,0 +1,81 @@ +package xtools.app.sys.service.impl; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.convert.SysRoleMenuConvert; +import xtools.app.sys.model.dto.req.SysRoleMenuReq; +import xtools.app.sys.model.entity.SysRoleMenu; +import xtools.app.sys.service.SysPermService; +import xtools.app.sys.service.SysRoleMenuService; +import xtools.app.sys.service.base.SysRoleMenuBaseService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.core.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + *

Title : SysRoleMenuServiceImpl

+ *

Description : 角色菜单关联表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 19:15:03 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysRoleMenuServiceImpl implements SysRoleMenuService { + + private final SysPermService sysPermService; + + private final SysRoleMenuBaseService sysRoleMenuBaseService; + + private final SysRoleMenuConvert sysRoleMenuConvert; + + /** + * 获取角色菜单 ID 集合 + * + * @param roleId 角色 ID + * @return 角色菜单 ID 集合 + */ + @Override + public Result> getRoleMenu(Long roleId) { + return Result.ok(sysRoleMenuBaseService.getRoleMenu(roleId)); + } + + /** + * 保存角色菜单关联 + * + * @param req 保存参数 + * @return 保存结果 + */ + @Override + public Result saveRoleMenu(SysRoleMenuReq req) { + Long roleId = req.getRoleId(); + List menuIds = req.getMenuIds(); + + sysRoleMenuBaseService.delByRoleId(roleId); + if (CollectionUtils.isEmpty(menuIds)) { + sysPermService.reloadPermCache(); + return Result.ok(true); + } + List list = new ArrayList<>(); + menuIds.forEach(item -> { + SysRoleMenu sysRoleMenu = new SysRoleMenu(); + sysRoleMenu.setRoleId(roleId); + sysRoleMenu.setMenuId(item); + list.add(sysRoleMenu); + }); + boolean saved = sysRoleMenuBaseService.saveBatch(list); + if (!saved) { + throw new BizError("保存失败"); + } + sysPermService.reloadPermCache(); + return Result.ok(true); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..2a3d856 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,231 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysRoleConvert; +import xtools.app.sys.model.dto.req.SysRoleAddReq; +import xtools.app.sys.model.dto.req.SysRolePageReq; +import xtools.app.sys.model.dto.req.SysRoleUpdateReq; +import xtools.app.sys.model.dto.resp.SysRoleResp; +import xtools.app.sys.model.entity.SysRole; +import xtools.app.sys.service.SysPermService; +import xtools.app.sys.service.SysRoleService; +import xtools.app.sys.service.base.SysRoleBaseService; +import xtools.app.sys.service.base.SysUserRoleBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysRoleServiceImpl

+ *

Description : 系统角色表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysRoleServiceImpl implements SysRoleService, BaseParams { + + private final SysPermService sysPermService; + + private final SysUserRoleBaseService sysUserRoleBaseService; + + private final SysRoleBaseService sysRoleBaseService; + + private final SysRoleConvert sysRoleConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysRoleConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysRole data = sysRoleBaseService.getById(id); + return Result.ok(sysRoleConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysRoleAddReq req) { + SysRole entity = sysRoleConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + boolean saved = sysRoleBaseService.save(entity); + if (!saved) { + throw new BizError("添加失败"); + } + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysRoleUpdateReq req) { + SysRole entity = sysRoleConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + boolean updated = sysRoleBaseService.updateById(entity); + if (!updated) { + throw new BizError("修改失败"); + } + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + boolean removed = sysRoleBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + sysUserRoleBaseService.delByRoleId(idList); + sysPermService.reloadPermCache(); + return Result.ok(true); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysRolePageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysRole::getId, + SysRole::getName, + SysRole::getCode, + SysRole::getStatus, + SysRole::getDataScope, + SysRole::getMemo, + SysRole::getGmtCreate, + SysRole::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByAsc(SysRole::getSort); + query.orderByDesc(SysRole::getGmtCreate); + return sysRoleBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysRolePageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysRole::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getName()), SysRole::getName, req.getName()); + query.like(StringUtils.isNotBlank(req.getCode()), SysRole::getCode, req.getCode()); + query.eq(Objects.nonNull(req.getSort()), SysRole::getSort, req.getSort()); + query.eq(Objects.nonNull(req.getStatus()), SysRole::getStatus, req.getStatus()); + query.eq(Objects.nonNull(req.getDataScope()), SysRole::getDataScope, req.getDataScope()); + query.eq(Objects.nonNull(req.getCreateBy()), SysRole::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysRole::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysRole::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysRole::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysRole::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(SysRole entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysRole::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getName()), SysRole::getName, entity.getName()); + return sysRoleBaseService.exists(query); + } + + /** + * 获取所有角色数据 + * + * @return 所有角色数据 + */ + @Override + public Result> all() { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 设置查询字段 + query.select(SysRole::getId, SysRole::getName, SysRole::getCode); + // 查询条件 + query.eq(SysRole::getStatus, CP_NUM1); + // 排序 + query.orderByAsc(SysRole::getSort); + query.orderByDesc(SysRole::getGmtCreate); + // 查询 + List list = sysRoleBaseService.list(query); + return Result.ok(sysRoleConvert.entityToRespList(list)); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysTaskServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysTaskServiceImpl.java new file mode 100644 index 0000000..a472b74 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysTaskServiceImpl.java @@ -0,0 +1,213 @@ +package xtools.app.sys.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.convert.SysTaskConvert; +import xtools.app.sys.model.dto.req.SysTaskPageReq; +import xtools.app.sys.model.dto.resp.SysTaskResp; +import xtools.app.sys.model.entity.SysTask; +import xtools.app.sys.service.SysTaskService; +import xtools.app.sys.service.base.SysTaskBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.log.LogTrack; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.boot.task.enums.TaskStatus; +import xtools.boot.task.model.dto.TaskInfo; +import xtools.core.StringUtils; +import xtools.core.enums.LogLevel; + +import java.time.Instant; +import java.util.Objects; + +/** + *

Title : SysTaskServiceImpl

+ *

Description : 系统任务 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-14 21:47:41 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysTaskServiceImpl implements SysTaskService, BaseParams { + + private final SysTaskBaseService sysTaskBaseService; + + private final SysTaskConvert sysTaskConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysTaskConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysTaskPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysTask::getId + , SysTask::getTraceId + , SysTask::getType + , SysTask::getStatus + , SysTask::getInfo + , SysTask::getStartTime + , SysTask::getEndTime + , SysTask::getMemo + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysTask::getGmtCreate); + return sysTaskBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysTaskPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysTask::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getTraceId()), SysTask::getTraceId, req.getTraceId()); + query.like(StringUtils.isNotBlank(req.getCode()), SysTask::getCode, req.getCode()); + query.eq(Objects.nonNull(req.getType()), SysTask::getType, req.getType()); + query.eq(Objects.nonNull(req.getStatus()), SysTask::getStatus, req.getStatus()); + query.like(StringUtils.isNotBlank(req.getInfo()), SysTask::getInfo, req.getInfo()); + QueryUtils.addTimeRange(query, req.getStartTimeRange(), SysTask::getStartTime); + QueryUtils.addTimeRange(query, req.getEndTimeRange(), SysTask::getEndTime); + query.like(StringUtils.isNotBlank(req.getMemo()), SysTask::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysTask::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysTask::getGmtModified); + } + + /** + * 保存任务 + * + * @param taskInfo 任务信息 + */ + @Override + public void save(TaskInfo taskInfo) { + for (int i = CP_NUM0; i < CP_NUM2; i++) { + try { + doSave(taskInfo); + break; + } catch (Exception e) { + JSONObject data = (JSONObject) JSON.toJSON(taskInfo); + LogBus.init(LogLevel.ERROR, LogBusBaseType.TASK).title("保存任务日志失败").data(data).error(e).save(); + } + try { + Thread.sleep(CP_NUM1000); + } catch (InterruptedException e) { + log.error("线程休眠异常", e); + } + } + } + + /** + * 执行保存任务 + * + * @param taskInfo 任务信息 + */ + public void doSave(TaskInfo taskInfo) { + // 任务Code + String code = taskInfo.getCode(); + // 任务状态 + TaskStatus status = taskInfo.getStatus(); + // 任务时间 + Instant time = taskInfo.getTime(); + // 查询是否有对应日志信息 + Long logId = getLogIdByCode(code); + + LogTrack logTrack = LogTrackHolder.get(); + String traceId = logTrack.traceId(); + + SysTask task = new SysTask(); + boolean result; + if (Objects.isNull(logId)) { + // 新增 + task.setStatus(status.code()); + task.setInfo(taskInfo.getInfo()); + task.setTraceId(traceId); + task.setCode(taskInfo.getCode()); + task.setType(taskInfo.getType()); + if (TaskStatus.ING.equals(status)) { + task.setStartTime(time); + } else { + task.setEndTime(time); + } + result = sysTaskBaseService.save(task); + } else { + // 更新 + task.setId(logId); + if (TaskStatus.ING.equals(status)) { + task.setStartTime(time); + } else { + task.setStatus(status.code()); + task.setInfo(taskInfo.getInfo()); + task.setEndTime(time); + } + result = sysTaskBaseService.updateById(task); + } + if (!result) { + throw new BizWarning("保存任务日志失败"); + } + } + + /** + * 通过任务编码获取任务日志ID + * + * @param code 任务编码 + * @return 任务日志ID + */ + private Long getLogIdByCode(String code) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 添加查询字段 + query.select(SysTask::getId); + // 添加查询条件 + query.eq(SysTask::getCode, code); + // 查询任务日志 + SysTask data = sysTaskBaseService.getOne(query); + return Objects.isNull(data) ? null : data.getId(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUpdateHistoryServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUpdateHistoryServiceImpl.java new file mode 100644 index 0000000..7247f2c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUpdateHistoryServiceImpl.java @@ -0,0 +1,278 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysUpdateHistoryConvert; +import xtools.app.sys.model.dto.req.SysUpdateHistoryAddReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryPageReq; +import xtools.app.sys.model.dto.req.SysUpdateHistoryUpdateReq; +import xtools.app.sys.model.dto.resp.SysUpdateHistoryResp; +import xtools.app.sys.model.entity.SysUpdateHistory; +import xtools.app.sys.param.dto.UpdateHistoryDto; +import xtools.app.sys.param.enums.SysParamEnum; +import xtools.app.sys.param.utils.SysParamUtils; +import xtools.app.sys.service.SysUpdateHistoryService; +import xtools.app.sys.service.base.SysUpdateHistoryBaseService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysUpdateHistoryServiceImpl

+ *

Description : 系统更新历史 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-19 15:21:03 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysUpdateHistoryServiceImpl implements SysUpdateHistoryService { + + /** + * 缓存参数 + */ + private static final SysParamEnum CACHE_PARAM = SysParamEnum.UPDATE_HISTORY; + + private final SysUpdateHistoryBaseService sysUpdateHistoryBaseService; + + private final SysUpdateHistoryConvert sysUpdateHistoryConvert; + + @Resource + private RedisService redisService; + + /** + * 初始化缓存 + */ + @Override + public void init() { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysUpdateHistory::getType); + // 查询 + List list = sysUpdateHistoryBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + log.info("无更新历史数据"); + return; + } + // 获取所有类型 + HashSet typeSet = new HashSet<>(list.stream().map(SysUpdateHistory::getType).toList()); + if (CollectionUtils.isEmpty(typeSet)) { + log.info("无更新历史数据"); + return; + } + for (Integer type : typeSet) { + cacheByType(type); + } + log.info("更新历史数据缓存成功"); + } + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysUpdateHistoryConvert.entityToRespList(page.getRecords())); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysUpdateHistory data = sysUpdateHistoryBaseService.getById(id); + return Result.ok(sysUpdateHistoryConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysUpdateHistoryAddReq req) { + SysUpdateHistory entity = sysUpdateHistoryConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysUpdateHistoryBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysUpdateHistoryUpdateReq req) { + SysUpdateHistory entity = sysUpdateHistoryConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysUpdateHistoryBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + boolean removed = sysUpdateHistoryBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysUpdateHistoryPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysUpdateHistory::getId + , SysUpdateHistory::getType + , SysUpdateHistory::getInfo + , SysUpdateHistory::getShowTime + , SysUpdateHistory::getVersion + , SysUpdateHistory::getMemo + , SysUpdateHistory::getGmtCreate + , SysUpdateHistory::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysUpdateHistory::getShowTime); + query.orderByDesc(SysUpdateHistory::getGmtCreate); + return sysUpdateHistoryBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysUpdateHistoryPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysUpdateHistory::getId, req.getId()); + query.eq(Objects.nonNull(req.getType()), SysUpdateHistory::getType, req.getType()); + query.like(StringUtils.isNotBlank(req.getInfo()), SysUpdateHistory::getInfo, req.getInfo()); + query.like(StringUtils.isNotBlank(req.getShowTime()), SysUpdateHistory::getShowTime, req.getShowTime()); + query.like(StringUtils.isNotBlank(req.getVersion()), SysUpdateHistory::getVersion, req.getVersion()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysUpdateHistory::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysUpdateHistory::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysUpdateHistory::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(SysUpdateHistory entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysUpdateHistory::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(SysUpdateHistory::getType, entity.getType()); + query.eq(SysUpdateHistory::getInfo, entity.getInfo()); + return sysUpdateHistoryBaseService.exists(query); + } + + /** + * 获取所有历史 + * + * @param type 类型 + * @return 所有历史 + */ + @Override + public Result> getAll(Integer type) { + List dataList = SysParamUtils.getArray(CACHE_PARAM, type, SysUpdateHistoryResp.class); + if (Objects.nonNull(dataList)) { + return Result.ok(dataList); + } + return Result.ok(new ArrayList<>()); + } + + /** + * 删除缓存 + * + * @param type 类型 + * @return 删除结果 + */ + @Override + public Result deleteCache(Integer type) { + cacheByType(type); + return Result.ok(true); + } + + /** + * 根据类型获取历史 + * + * @param type 类型 + */ + private void cacheByType(Integer type) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUpdateHistory::getInfo, SysUpdateHistory::getShowTime, SysUpdateHistory::getVersion); + query.eq(SysUpdateHistory::getType, type); + query.orderByDesc(SysUpdateHistory::getShowTime, SysUpdateHistory::getGmtCreate); + List dataList = sysUpdateHistoryConvert.entityToCacheList(sysUpdateHistoryBaseService.list(query)); + if (CollectionUtils.isEmpty(dataList)) { + return; + } + redisService.set(SysParamUtils.getCacheKey(CACHE_PARAM.type(), CACHE_PARAM.desc(), type), dataList); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeInfoServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeInfoServiceImpl.java new file mode 100644 index 0000000..b6a27d5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeInfoServiceImpl.java @@ -0,0 +1,153 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.auth.model.dto.LoginUserDto; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.convert.SysUserNoticeInfoConvert; +import xtools.app.sys.mapper.SysUserNoticeInfoMapper; +import xtools.app.sys.model.dto.req.SysUserNoticeInfoPageReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeInfoResp; +import xtools.app.sys.model.entity.SysNotice; +import xtools.app.sys.model.entity.SysUserNotice; +import xtools.app.sys.service.SysUserNoticeInfoService; +import xtools.app.sys.service.base.SysNoticeBaseService; +import xtools.app.sys.service.base.SysUserNoticeBaseService; +import xtools.app.sys.service.base.SysUserNoticeInfoBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.DeleteEnum; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; + +import java.time.Instant; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysUserNoticeInfoServiceImpl

+ *

Description : 系统用户通知公告信息表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 20:14:58 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysUserNoticeInfoServiceImpl implements SysUserNoticeInfoService, BaseParams { + + private final SysNoticeBaseService sysNoticeBaseService; + + private final SysUserNoticeBaseService sysUserNoticeBaseService; + + private final SysUserNoticeInfoBaseService sysUserNoticeInfoBaseService; + + private final SysUserNoticeInfoConvert sysUserNoticeInfoConvert; + + private final SysUserNoticeInfoMapper sysUserNoticeInfoMapper; + + /** + * 获取用户通知信息分页 + * + * @param pageReq 分页参数 + * @return 分页数据 + */ + @Override + public Result> page(PageReq pageReq) { + LoginUserDto loginUser = AuthUtils.get(); + IPage page = sysUserNoticeInfoMapper.getUserNoticeList(QueryUtils.getPage(pageReq.getCurrentPage(), pageReq.getPageSize()), loginUser.getId(), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), page.getRecords()); + return Result.ok(pageResp); + } + + + /** + * 获取内容 + * + * @param noticeId 通知ID + * @return 内容 + */ + @Override + public Result getContent(Long noticeId) { + SysNotice notice = sysNoticeBaseService.getById(noticeId); + if (Objects.isNull(notice) + || Objects.equals(notice.getIsDeleted(), DeleteEnum.DELETE.code()) + || !Objects.equals(notice.getPublishStatus(), CP_NUM1) + ) { + throw new BizError("通知不存在"); + } + LoginUserDto loginUser = AuthUtils.get(); + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysUserNotice::getNoticeId, noticeId); + query.eq(SysUserNotice::getUserId, loginUser.getId()); + SysUserNotice dbData = sysUserNoticeBaseService.getOne(query); + if (Objects.isNull(dbData)) { + throw new BizError("无法阅读"); + } + + if (!Objects.equals(dbData.getNoticeRead(), CP_NUM1)) { + // 更新为已读 + SysUserNotice entity = new SysUserNotice(); + entity.setId(dbData.getId()); + entity.setNoticeRead(CP_NUM1); + entity.setReadTime(Instant.now()); + sysUserNoticeBaseService.updateById(entity); + } + return Result.ok(notice.getContentMd()); + } + + /** + * 批量已读 + * + * @param req 请求参数 + * @return 是否成功 + */ + @Override + public Result readList(IdListReq req) { + readNotice(req.getIdList()); + return Result.ok(true); + } + + /** + * 全部已读 + * + * @return 是否成功 + */ + @Override + public Result readAll() { + readNotice(null); + return Result.ok(true); + } + + /** + * 已读通知 + * + * @param ids ID列表 + */ + private void readNotice(List ids) { + LoginUserDto loginUser = AuthUtils.get(); + // 创建更新条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysUserNotice::getUserId, loginUser.getId()); + query.in(CollectionUtils.isNotEmpty(ids), SysUserNotice::getNoticeId, ids); + + // 创建更新对象 + SysUserNotice update = new SysUserNotice(); + update.setNoticeRead(CP_NUM1); + update.setReadTime(Instant.now()); + + sysUserNoticeBaseService.update(update, query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeServiceImpl.java new file mode 100644 index 0000000..a428591 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserNoticeServiceImpl.java @@ -0,0 +1,225 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.convert.SysUserNoticeConvert; +import xtools.app.sys.mapper.SysUserNoticeMapper; +import xtools.app.sys.model.dto.req.SysUserNoticePageReq; +import xtools.app.sys.model.dto.req.SysUserNoticeUpdateReq; +import xtools.app.sys.model.dto.resp.SysUserNoticeResp; +import xtools.app.sys.model.entity.SysUser; +import xtools.app.sys.model.entity.SysUserNotice; +import xtools.app.sys.service.SysUserNoticeService; +import xtools.app.sys.service.base.SysNoticeBaseService; +import xtools.app.sys.service.base.SysUserBaseService; +import xtools.app.sys.service.base.SysUserNoticeBaseService; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.DeleteEnum; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysUserNoticeServiceImpl

+ *

Description : 系统用户通知公告表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-16 11:22:01 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysUserNoticeServiceImpl implements SysUserNoticeService, BaseParams { + + private final SysUserNoticeBaseService sysUserNoticeBaseService; + + private final SysUserBaseService SysUserBaseService; + + private final SysNoticeBaseService sysNoticeBaseService; + + private final SysUserNoticeConvert sysUserNoticeConvert; + + private final SysUserNoticeMapper sysUserNoticeMapper; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = sysUserNoticeMapper.getPage(QueryUtils.getPage(pageReq.getCurrentPage(), pageReq.getPageSize()), pageReq.getQuery()); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), page.getRecords()); + return Result.ok(pageResp); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysUserNoticeUpdateReq req) { + SysUserNotice entity = sysUserNoticeConvert.updateReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysUserNoticeBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(IdListReq req) { + boolean removed = sysUserNoticeBaseService.removeByIds(req.getIdList()); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 根据通知 ID 获取用户 ID + * + * @param noticeId 通知 ID + * @return 用户 ID 集合 + */ + @Override + public List getUserIdByNoticeId(Long noticeId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUserNotice::getUserId); + query.eq(SysUserNotice::getNoticeId, noticeId); + query.eq(SysUserNotice::getIsDeleted, DeleteEnum.NORMAL.code()); + List list = sysUserNoticeBaseService.list(query); + if (CollectionUtils.isEmpty(list)) { + return List.of(); + } + return list.stream().map(SysUserNotice::getUserId).toList(); + } + + /** + * 保存 + * + * @param noticeId 通知 ID + * @param uids 用户 ID 集合 + * @param isAll 是否全员推送 + */ + @Override + public void saveByNoticeId(Long noticeId, final List uids, boolean isAll) { + deleteByNoticeId(noticeId); + if (CollectionUtils.isEmpty(uids) && !isAll) { + return; + } + // 获取待通知的用户列表 + List userIdList = new ArrayList<>(isAll ? getAllUser() : uids); + List original = new ArrayList<>(userIdList); + + // 查询已经绑定通知的用户 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUserNotice::getUserId); + query.eq(SysUserNotice::getNoticeId, noticeId); + query.in(SysUserNotice::getUserId, original); + List list = sysUserNoticeBaseService.list(query); + if (CollectionUtils.isNotEmpty(list)) { + List dbUids = list.stream().map(SysUserNotice::getUserId).toList(); + // 找出未通知的用户 + userIdList.removeAll(dbUids); + } + if (CollectionUtils.isNotEmpty(userIdList)) { + // 批量添加为通知用户 + List entities = new ArrayList<>(); + for (Long id : userIdList) { + SysUserNotice entity = new SysUserNotice(); + entity.setNoticeId(noticeId); + entity.setUserId(id); + entities.add(entity); + } + boolean save = sysUserNoticeBaseService.saveBatch(entities); + if (!save) { + throw new BizError("保存失败"); + } + } + // 批量修改为正常 + LambdaUpdateWrapper update = new LambdaUpdateWrapper<>(); + update.eq(SysUserNotice::getNoticeId, noticeId); + update.in(SysUserNotice::getUserId, original); + SysUserNotice entity = new SysUserNotice(); + entity.setIsDeleted(DeleteEnum.NORMAL.code()); + boolean updated = sysUserNoticeBaseService.update(entity, update); + if (!updated) { + throw new BizError("修改失败"); + } + } + + /** + * 获取所有用户ID + * + * @return 所有用户 + */ + private List getAllUser() { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysUser::getId); + List list = SysUserBaseService.list(query); + return list.stream().map(SysUser::getId).toList(); + } + + /** + * 逻辑删除 + * + * @param noticeId 通知ID + */ + private void deleteByNoticeId(Long noticeId) { + // 删除所有该通知关联的用户(逻辑删除) + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysUserNotice::getNoticeId, noticeId); + SysUserNotice update = new SysUserNotice(); + update.setIsDeleted(DeleteEnum.DELETE.code()); + sysUserNoticeBaseService.update(update, query); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysUserNotice existsEntity(SysUserNotice entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysUserNotice::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysUserNotice::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(Objects.nonNull(entity.getNoticeId()), SysUserNotice::getNoticeId, entity.getNoticeId()); + query.eq(Objects.nonNull(entity.getUserId()), SysUserNotice::getUserId, entity.getUserId()); + return sysUserNoticeBaseService.getOne(query); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserRoleServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserRoleServiceImpl.java new file mode 100644 index 0000000..a6d196b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserRoleServiceImpl.java @@ -0,0 +1,21 @@ +package xtools.app.sys.service.impl; + +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import xtools.app.sys.service.SysUserRoleService; + +/** + *

Title : SysUserRoleServiceImpl

+ *

Description : 用户角色关联表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-30 17:16:11 + */ +@Primary +@Service +public class SysUserRoleServiceImpl implements SysUserRoleService { + + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserServiceImpl.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..d4fe896 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/service/impl/SysUserServiceImpl.java @@ -0,0 +1,306 @@ +package xtools.app.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.auth.utils.AuthUtils; +import xtools.app.sys.config.SysConfig; +import xtools.app.sys.convert.SysUserConvert; +import xtools.app.sys.model.dto.req.SysUserAddReq; +import xtools.app.sys.model.dto.req.SysUserPageReq; +import xtools.app.sys.model.dto.req.SysUserUpdateReq; +import xtools.app.sys.model.dto.req.UserInfoEditReq; +import xtools.app.sys.model.dto.resp.SysUserResp; +import xtools.app.sys.model.entity.SysUser; +import xtools.app.sys.service.SysUserService; +import xtools.app.sys.service.base.SysDeptBaseService; +import xtools.app.sys.service.base.SysUserBaseService; +import xtools.app.sys.service.base.SysUserRoleBaseService; +import xtools.app.sys.utils.PasswdUtils; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysUserServiceImpl

+ *

Description : 系统用户表 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-01-28 19:03:42 + */ +@Primary +@Service +@RequiredArgsConstructor +public class SysUserServiceImpl implements SysUserService { + + private final SysConfig sysConfig; + + private final SysDeptBaseService sysDeptBaseService; + + private final SysUserRoleBaseService sysUserRoleBaseService; + + private final SysUserBaseService sysUserBaseService; + + private final SysUserConvert sysUserConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + List sysUserResp = sysUserConvert.entityToRespList(page.getRecords()); + sysUserResp.forEach(item -> { + item.setDeptName(sysDeptBaseService.getDeptNameById(item.getDeptId())); + item.setRoleIds(sysUserRoleBaseService.getUserRole(item.getId())); + }); + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), sysUserResp); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysUser data = sysUserBaseService.getById(id); + SysUserResp sysUserResp = sysUserConvert.entityToResp(data); + sysUserResp.setRoleIds(sysUserRoleBaseService.getUserRole(sysUserResp.getId())); + sysUserResp.setPasswd(null); + return Result.ok(sysUserResp); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysUserAddReq req) { + SysUser entity = sysUserConvert.addReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + entity.setPasswd(PasswdUtils.encrypt(sysConfig.getUser().getPasswd())); + boolean saved = sysUserBaseService.save(entity); + if (!saved) { + throw new BizError("添加失败"); + } + // 保存用户角色信息 + sysUserRoleBaseService.saveBatch(sysUserRoleBaseService.packageUserRoleList(entity.getId(), req.getRoleIds())); + return Result.ok(true); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysUserUpdateReq req) { + SysUser entity = sysUserConvert.updateReqToEntity(req); + if (existsEntity(entity)) { + throw new BizWarning("数据已存在"); + } + entity.setPasswd(null); + boolean updated = sysUserBaseService.updateById(entity); + if (!updated) { + throw new BizError("修改失败"); + } + // 保存用户角色信息 + sysUserRoleBaseService.delByUserId(entity.getId()); + sysUserRoleBaseService.saveBatch(sysUserRoleBaseService.packageUserRoleList(entity.getId(), req.getRoleIds())); + return Result.ok(true); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + boolean removed = sysUserBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + AuthUtils.remove(idList); + return Result.ok(true); + } + + /** + * 根据 ID 集合查询 + * + * @param req ID 集合请求 + * @return 查询结果 + */ + @Override + public Result> getListByIds(IdListReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysUser::getId, + SysUser::getDeptId, + SysUser::getAccount, + SysUser::getNickname, + SysUser::getAvatar, + SysUser::getMobile, + SysUser::getEmail, + SysUser::getSex, + SysUser::getStatus + ); + query.in(SysUser::getId, req.getIdList()); + List list = sysUserBaseService.list(query); + List sysUserResp = sysUserConvert.entityToRespList(list); + sysUserResp.forEach(item -> item.setDeptName(sysDeptBaseService.getDeptNameById(item.getDeptId()))); + return Result.ok(sysUserResp); + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysUserPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysUser::getId, + SysUser::getDeptId, + SysUser::getAccount, + SysUser::getNickname, + SysUser::getAvatar, + SysUser::getMobile, + SysUser::getEmail, + SysUser::getSex, + SysUser::getStatus, + SysUser::getMemo, + SysUser::getGmtCreate, + SysUser::getGmtModified + ); + // 特殊搜索条件处理 + Long deptId = req.getDeptId(); + if (CheckUtils.id(deptId)) { + List queryDeptIdList = new ArrayList<>(); + queryDeptIdList.add(deptId); + + // 获取该部门下的所有部门 + List childrenIdList = sysDeptBaseService.getChildrenId(deptId); + queryDeptIdList.addAll(childrenIdList); + + query.in(SysUser::getDeptId, queryDeptIdList); + req.setDeptId(null); + } + + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysUser::getGmtCreate); + return sysUserBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysUserPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysUser::getId, req.getId()); + query.eq(Objects.nonNull(req.getDeptId()), SysUser::getDeptId, req.getDeptId()); + query.like(StringUtils.isNotBlank(req.getAccount()), SysUser::getAccount, req.getAccount()); + query.like(StringUtils.isNotBlank(req.getNickname()), SysUser::getNickname, req.getNickname()); + query.like(StringUtils.isNotBlank(req.getAvatar()), SysUser::getAvatar, req.getAvatar()); + query.like(StringUtils.isNotBlank(req.getMobile()), SysUser::getMobile, req.getMobile()); + query.like(StringUtils.isNotBlank(req.getEmail()), SysUser::getEmail, req.getEmail()); + query.eq(Objects.nonNull(req.getSex()), SysUser::getSex, req.getSex()); + query.like(StringUtils.isNotBlank(req.getPasswd()), SysUser::getPasswd, req.getPasswd()); + query.eq(Objects.nonNull(req.getStatus()), SysUser::getStatus, req.getStatus()); + query.eq(Objects.nonNull(req.getCreateBy()), SysUser::getCreateBy, req.getCreateBy()); + query.eq(Objects.nonNull(req.getUpdateBy()), SysUser::getUpdateBy, req.getUpdateBy()); + query.like(StringUtils.isNotBlank(req.getMemo()), SysUser::getMemo, req.getMemo()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysUser::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysUser::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private boolean existsEntity(SysUser entity) { + if (StringUtils.isBlank(entity.getAccount())) { + return false; + } + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysUser::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getAccount()), SysUser::getAccount, entity.getAccount()); + return sysUserBaseService.exists(query); + } + + /** + * 获取用户信息 + * + * @param userId 用户 ID + * @return 用户信息 + */ + @Override + public SysUserResp getUserInfo(Long userId) { + return sysUserConvert.entityToResp(sysUserBaseService.getSysUser(userId)); + } + + /** + * 保存用户信息 + * + * @param req 用户信息 + * @return 保存结果 + */ + @Override + public boolean saveSysUser(UserInfoEditReq req) { + SysUser entity = sysUserConvert.saveReqToEntity(req); + return sysUserBaseService.updateById(entity); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/utils/PasswdUtils.java b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/utils/PasswdUtils.java new file mode 100644 index 0000000..916101e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/java/xtools/app/sys/utils/PasswdUtils.java @@ -0,0 +1,66 @@ +package xtools.app.sys.utils; + +import xtools.app.sys.model.dto.Sm2KeyDto; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizPublicKeyError; +import xtools.extend.encrypt.Sm2Utils; +import xtools.extend.encrypt.Sm3Utils; + +import java.util.Objects; + +/** + *

Title : PasswdUtils

+ *

Description : PasswdUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/9 21:15 + */ +public class PasswdUtils { + + /** + * 加密密码 + * + * @param passwd 密码 + * @return 加密后的密码 + */ + public static String encrypt(String passwd) { + return Sm3Utils.encryptToString(passwd); + } + + /** + * 校验密码 + * + * @param passwd 密码 + * @param encryptPasswd 加密后的密码 + * @return 校验结果 + */ + public static boolean check(String passwd, String encryptPasswd) { + return encrypt(passwd).equals(encryptPasswd); + } + + /** + * 解密密码 + * + * @param sm2Key SM2密钥 + * @param publicKey 公钥 + * @param passwd 密码 + * @return 解密后的密码 + */ + public static String decrypt(Sm2KeyDto sm2Key, String publicKey, String passwd) { + // 验证公钥 + if (!Objects.equals(sm2Key.getPublicKey(), publicKey)) { + throw new BizPublicKeyError("公钥过期"); + } + try { + // 解密密码 + return Sm2Utils.decrypt(sm2Key.getPrivateKey(), passwd); + } catch (Exception e) { + throw new BizError("密码解密异常"); + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysMenuMapper.xml b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysMenuMapper.xml new file mode 100644 index 0000000..39a1ea4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysMenuMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysRiskMapper.xml b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysRiskMapper.xml new file mode 100644 index 0000000..8db5c5f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysRiskMapper.xml @@ -0,0 +1,20 @@ + + + + + + UPDATE sys_risk sr + SET sr.DATA = CONCAT( + REPLACE(sr.DATA, #{ip}, ''), + #{ip} + ) + WHERE sr.type = #{type} AND sr.sys_type = #{sysType} + + + + + UPDATE sys_risk sr + SET sr.DATA = REPLACE(sr.DATA, #{ip}, '') + WHERE sr.type = #{type} AND sr.sys_type = #{sysType} + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeInfoMapper.xml b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeInfoMapper.xml new file mode 100644 index 0000000..9978de5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeInfoMapper.xml @@ -0,0 +1,44 @@ + + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeMapper.xml b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeMapper.xml new file mode 100644 index 0000000..82b99f4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-biz/src/main/resources/mapper/SysUserNoticeMapper.xml @@ -0,0 +1,45 @@ + + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-boot/Dockerfile b/xtools-app-sys/xtools-app-sys-boot/Dockerfile new file mode 100644 index 0000000..85014ec --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-boot/Dockerfile @@ -0,0 +1,10 @@ +FROM registry.cn-hangzhou.aliyuncs.com/xujun-public/liberica-openjdk-rocky:25.0.1-11 +MAINTAINER org.xujun + +ENV JVM_OPTS="" + +RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone +WORKDIR /data0/app +COPY target/xtools-app-sys-boot-1.0.0.jar /data0/app/xtools-app-sys-boot.jar + +ENTRYPOINT ["/bin/sh", "-c", "java ${JVM_OPTS} -jar /data0/app/xtools-app-sys-boot.jar"] \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-boot/pom.xml b/xtools-app-sys/xtools-app-sys-boot/pom.xml new file mode 100644 index 0000000..326f689 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-boot/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-boot + + + + + + org.xujun + xtools-app-sys-biz + + + + + + + org.xujun + xtools-app-common-sentinel + + + + org.xujun + xtools-app-monitor-client + + + + org.xujun + xtools-boot-job-xxl + + + + + + + org.xujun + xtools-app-sys-log-bus-elasticsearch + + + + + + + + + org.xujun + xtools-boot-storage-s3 + + + + + + org.xujun + xtools-cloud-alibaba-nacos + + + + org.xujun + xtools-cloud-alibaba-sentinel + + + + + + + + org.cyclonedx + cyclonedx-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-boot/src/main/java/xtools/app/SysApplication.java b/xtools-app-sys/xtools-app-sys-boot/src/main/java/xtools/app/SysApplication.java new file mode 100644 index 0000000..7b7d973 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-boot/src/main/java/xtools/app/SysApplication.java @@ -0,0 +1,45 @@ +package xtools.app; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.util.StopWatch; +import xtools.boot.core.utils.AppUtils; + +/** + *

Title : SysApplication

+ *

Description : SysApplication

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/01/17 12:30 + */ +@Slf4j +@SpringBootApplication +public class SysApplication { + + /** + * Main + * + * @param args 参数 + */ + static void main(String[] args) { + StopWatch sw = new StopWatch(); + sw.start(); + runApp(args); + sw.stop(); + log.info(AppUtils.info(sw.getTotalTimeMillis())); + } + + /** + * 运行 App + * + * @param args 参数 + */ + public static void runApp(String[] args) { + SpringApplication.run(SysApplication.class, args); + } +} diff --git a/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application-nacos.yml b/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application-nacos.yml new file mode 100644 index 0000000..8370c12 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application-nacos.yml @@ -0,0 +1,50 @@ +# Spring 信息 +spring: + cloud: + # Nacos 配置信息 + nacos: + # Nacos 发现配置信息 + discovery: + # Nacos 发现服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 发现服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 发现服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 发现服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_DISCOVERY_NAMESPACE:xtools-cloud} + # 仅ipv4模式 + ip-type: IPv4 + # Nacos 配置中心信息 + config: + # Nacos 配置服务器地址 + server-addr: ${NACOS_SERVICE_HOST:127.0.0.1}:${NACOS_SERVICE_PORT:8848} + # Nacos 配置服务器用户名 + username: ${NACOS_SERVICE_USERNAME:nacos} + # Nacos 配置服务器密码 + password: ${NACOS_SERVICE_PASSWORD:nacos} + # Nacos 配置服务器命名空间(默认为Public),可以省略不写 + namespace: ${NACOS_CONFIG_NAMESPACE:xtools-cloud} + # 配置文件 + config: + import: + # Boot配置文件 + - nacos:application-boot-base.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-db.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-druid.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-elasticsearch.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-knife4j.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-log.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-monitor.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-mybatis-plus.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-rabbitmq.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-redis.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-storage.yaml?refreshEnabled=true&group=BOOT + - nacos:application-boot-xxl-job.yaml?refreshEnabled=true&group=BOOT + # Cloud配置文件 + - nacos:application-cloud-sentinel.yaml?refreshEnabled=true&group=CLOUD + # Customizer配置文件 + - nacos:application-customizer-api.yaml?refreshEnabled=true&group=CUSTOMIZER + - nacos:application-customizer-log.yaml?refreshEnabled=true&group=CUSTOMIZER + # App配置文件 + - nacos:application-app-sys.yaml?refreshEnabled=true&group=APP diff --git a/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application.yml b/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application.yml new file mode 100644 index 0000000..0f681e5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-boot/src/main/resources/application.yml @@ -0,0 +1,16 @@ +# Spring 配置 +spring: + # 应用配置 + application: + # 应用名称 + name: xtools-app-sys + # 环境配置 + profiles: + active: + - info + - nacos + +# 服务器配置 +server: + # 端口 + port: ${SYS_SERVICE_PORT:18001} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-call/pom.xml b/xtools-app-sys/xtools-app-sys-call/pom.xml new file mode 100644 index 0000000..8fb0a3d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-call + + + + + + + org.xujun + xtools-cloud-call + + + + + + org.xujun + xtools-app-common-call + + + + org.xujun + xtools-app-sys-api + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysAddressCall.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysAddressCall.java new file mode 100644 index 0000000..affc27e --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysAddressCall.java @@ -0,0 +1,32 @@ +package xtools.app.sys.call; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; +import xtools.app.sys.api.SysAddressApi; +import xtools.app.sys.model.dto.resp.SysAddressResp; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysAddressCall

+ *

Description : 公用地址表 Call

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-13 15:02:53 + */ +@HttpExchange("/sys/address") +public interface SysAddressCall extends SysAddressApi { + + /** + * 根据code获取地址信息 + * + * @param code Code + * @return 地址信息 + */ + @Override + @GetExchange("/get-by-code/{code}") + Result getByCode(@PathVariable String code); + +} diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysDictItemCall.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysDictItemCall.java new file mode 100644 index 0000000..75125d3 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysDictItemCall.java @@ -0,0 +1,35 @@ +package xtools.app.sys.call; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; +import xtools.app.sys.api.SysDictItemApi; +import xtools.app.sys.model.dto.resp.SysDictItemResp; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysDictItemCall

+ *

Description : SysDictItemCall

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/27 10:49 + */ +@HttpExchange("/sys/dict-item") +public interface SysDictItemCall extends SysDictItemApi { + + /** + * 根据字典编码查询字典项 + * + * @param dictCode 字典编码 + * @return 字典项 + */ + @Override + @GetExchange("/get-by-code/{dictCode}") + Result> getByCode(@PathVariable String dictCode); +} diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysFileCall.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysFileCall.java new file mode 100644 index 0000000..d1d094a --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysFileCall.java @@ -0,0 +1,98 @@ +package xtools.app.sys.call; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.service.annotation.DeleteExchange; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; +import org.springframework.web.service.annotation.PostExchange; +import xtools.app.sys.api.SysFileApi; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileChangeReq; +import xtools.app.sys.model.dto.req.SysFileUpdateReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.req.IdListReq; + +/** + *

Title : SysFileCall

+ *

Description : 系统文件表 Call

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-14 13:44:03 + */ +@HttpExchange("/sys/file") +public interface SysFileCall extends SysFileApi { + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + @GetExchange("base/{id}") + Result getById(@PathVariable Long id); + + /** + * 根据文件名查询 + * + * @param bucket 桶名称 + * @param fileName 文件名 + * @return 结果 + */ + @Override + @GetExchange("base/get-by-name") + Result getByName( + @NotBlank(message = "不能为空") + @RequestParam String bucket, + @NotBlank(message = "不能为空") + @RequestParam String fileName + ); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @PostExchange("base") + Result add(@RequestBody @Valid SysFileAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @GetExchange("base") + Result update(@RequestBody @Valid SysFileUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param req ID 集合 + * @return 删除结果 + */ + @Override + @DeleteExchange("base") + Result delById(@RequestBody @Valid IdListReq req); + + /** + * 改变数据类型 + * + * @param req 请求参数 + * @return 是否成功 + */ + @Override + @PostExchange("change-data-type-by-ids") + Result changeDataTypeByIds(@RequestBody @Valid SysFileChangeReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysParamCall.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysParamCall.java new file mode 100644 index 0000000..02327d4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysParamCall.java @@ -0,0 +1,47 @@ +package xtools.app.sys.call; + +import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.service.annotation.HttpExchange; +import org.springframework.web.service.annotation.PostExchange; +import org.springframework.web.service.annotation.PutExchange; +import xtools.app.sys.api.SysParamApi; +import xtools.app.sys.model.dto.req.SysParamAddReq; +import xtools.app.sys.model.dto.req.SysParamUpdateReq; +import xtools.boot.api.model.dto.Result; + +/** + *

Title : SysParamCall

+ *

Description : 系统参数表 Call

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-03-26 10:15:49 + */ +@HttpExchange("/sys/param") +public interface SysParamCall extends SysParamApi { + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Operation(summary = "添加数据") + @PostExchange("base") + Result add(@RequestBody @Valid SysParamAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @PutExchange("base") + Result update(@RequestBody @Valid SysParamUpdateReq req); + +} diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysRiskCall.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysRiskCall.java new file mode 100644 index 0000000..256d015 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/call/SysRiskCall.java @@ -0,0 +1,73 @@ +package xtools.app.sys.call; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; +import org.springframework.web.service.annotation.PostExchange; +import xtools.app.sys.api.SysRiskApi; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.boot.api.model.dto.Result; + +import java.util.List; + +/** + *

Title : SysRiskCall

+ *

Description : 系统风控表 Call

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-04-08 09:10:45 + */ +@HttpExchange("/sys/risk") +public interface SysRiskCall extends SysRiskApi { + + /** + * 根据类型获取数据 + * + * @param type 类型 + * @return 数据 + */ + @Override + @GetExchange("type") + Result> getByType( + @NotNull(message = "不能为空") + @RequestParam SysRiskType type + ); + + /** + * 添加IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 添加结果 + */ + @Override + @PostExchange("add-ip") + Result addIp( + @NotBlank(message = "不能为空") + @RequestParam String sysType, + @NotBlank(message = "不能为空") + @RequestParam String ip + ); + + /** + * 移除IP + * + * @param sysType 系统类型 + * @param ip IP + * @return 移除结果 + */ + @Override + @PostExchange("remove-ip") + Result removeIp( + @NotBlank(message = "不能为空") + @RequestParam String sysType, + @NotBlank(message = "不能为空") + @RequestParam String ip + ); + +} diff --git a/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/config/SysHttpServiceConfig.java b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/config/SysHttpServiceConfig.java new file mode 100644 index 0000000..b1b42b5 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-call/src/main/java/xtools/app/sys/config/SysHttpServiceConfig.java @@ -0,0 +1,21 @@ +package xtools.app.sys.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.service.registry.ImportHttpServices; + +/** + *

Title : SysHttpServiceConfig

+ *

Description : SysHttpServiceConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/25 08:28 + */ +@Configuration +@ImportHttpServices(group = "xtools-app-sys", basePackages = "xtools.app.sys.call") +public class SysHttpServiceConfig { + +} diff --git a/xtools-app-sys/xtools-app-sys-file-web/pom.xml b/xtools-app-sys/xtools-app-sys-file-web/pom.xml new file mode 100644 index 0000000..82966cb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file-web/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-file-web + + + + + + + org.xujun + xtools-boot-web-base + + + + + + org.xujun + xtools-app-sys-file + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-file-web/src/main/java/xtools/app/sys/file/web/controller/SysCommonFileController.java b/xtools-app-sys/xtools-app-sys-file-web/src/main/java/xtools/app/sys/file/web/controller/SysCommonFileController.java new file mode 100644 index 0000000..1e7a2da --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file-web/src/main/java/xtools/app/sys/file/web/controller/SysCommonFileController.java @@ -0,0 +1,76 @@ +package xtools.app.sys.file.web.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xtools.app.sys.file.enums.FilePermissionType; +import xtools.app.sys.file.service.SysFileDownloadCallback; +import xtools.app.sys.file.service.SysFileOptService; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.boot.api.exection.BizError; +import xtools.core.extend.TemplateUtils; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + *

Title : SysCommonFileController

+ *

Description : SysCommonFileController

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : Windows11

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/11 13:23 + */ +@Slf4j +@Tag(name = "系统通用") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/common") +public class SysCommonFileController { + + private final SysFileOptService sysFileOptService; + + @Operation(summary = "获取公用文件") + @GetMapping("/get/{id}/file") + public void getFile( + @NotNull(message = "不能为空") + @PathVariable Long id, + HttpServletResponse response + ) { + try (ServletOutputStream outputStream = response.getOutputStream()) { + response.setHeader("Cache-Control", "max-age=604800"); + sysFileOptService.download(id, outputStream, new SysFileDownloadCallback() { + @Override + public boolean before(SysFileResp fileInfo) { + // 判断文件权限 + FilePermissionType permissionType = FilePermissionType.valueOfCode(fileInfo.getPermission()); + if (!FilePermissionType.PUBLIC.equals(permissionType)) { + return false; + } + + String fileName = URLEncoder.encode(fileInfo.getFileName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + String contentDisposition = "attachment; filename=\"{}\"; filename*=UTF-8''{}"; + response.setHeader("Content-Disposition", TemplateUtils.format(contentDisposition, fileName, fileName)); + response.setContentLengthLong(fileInfo.getFileSize()); + return true; + } + }); + } catch (IOException e) { + log.error("文件下载失败", e); + throw new BizError("文件下载失败"); + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-file/pom.xml b/xtools-app-sys/xtools-app-sys-file/pom.xml new file mode 100644 index 0000000..199b50c --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-file + + + + + + + + org.bouncycastle + bcprov-jdk18on + + + org.xujun + xtools-extend + + + + + org.xujun + xtools-boot-storage-base + + + + + + + org.xujun + xtools-app-sys-api + + + + + + jakarta.annotation + jakarta.annotation-api + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizBaseEnum.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizBaseEnum.java new file mode 100644 index 0000000..09e31b4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizBaseEnum.java @@ -0,0 +1,46 @@ +package xtools.app.sys.file.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : FileBizBaseEnum

+ *

Description : FileBizBaseEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/24 09:18 + */ +public interface FileBizBaseEnum extends BaseEnum { + + /** + * 存储桶 + * + * @return 存储桶 + */ + String bucket(); + + /** + * 文件权限 + * + * @return 文件权限 + */ + FilePermissionType permission(); + + /** + * 文件过期时间(小时) + * + * @return 文件过期时间 + */ + int expireTime(); + + /** + * 文件扩展名 + * + * @return 文件扩展名 + */ + String[] extArr(); + +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizEnum.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizEnum.java new file mode 100644 index 0000000..c7e40b1 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FileBizEnum.java @@ -0,0 +1,138 @@ +package xtools.app.sys.file.enums; + +/** + *

Title : FileBizEnum

+ *

Description : FileBizEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/17 21:09 + */ +public enum FileBizEnum implements FileBizBaseEnum { + + // 系统通知 + SYS_NOTICE(-10, "系统通知", "sys-notice-editor-img", FilePermissionType.PUBLIC, 12, "png", "jpg", "jpeg", "gif", "bmp", "webp"); + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 存储桶 + */ + private final String bucket; + + /** + * 文件权限 + */ + private final FilePermissionType permission; + + /** + * 文件过期时间(小时) + */ + private final int expireTime; + + /** + * 扩展名 + */ + private final String[] extArr; + + /** + * 构造函数 + * + * @param code 编码 + * @param desc 说明 + * @param bucket 存储桶 + * @param permission 文件权限 + * @param expireTime 文件过期时间(小时) + * @param extArr 扩展名 + */ + FileBizEnum(int code, String desc, String bucket, FilePermissionType permission, int expireTime, String... extArr) { + this.code = code; + this.desc = desc; + this.bucket = bucket; + this.permission = permission; + this.expireTime = expireTime; + this.extArr = extArr; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public FileBizBaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + + /** + * 获取存储桶 + * + * @return 存储桶 + */ + @Override + public String bucket() { + return bucket; + } + + /** + * 文件权限 + * + * @return 文件权限 + */ + @Override + public FilePermissionType permission() { + return permission; + } + + /** + * 获取文件过期时间 + * + * @return 文件过期时间 + */ + @Override + public int expireTime() { + return expireTime; + } + + /** + * 获取扩展名 + * + * @return 扩展名 + */ + @Override + public String[] extArr() { + return extArr; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FilePermissionType.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FilePermissionType.java new file mode 100644 index 0000000..4385dde --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/enums/FilePermissionType.java @@ -0,0 +1,90 @@ +package xtools.app.sys.file.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : FilePermissionType

+ *

Description : FilePermissionType

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/15 10:29 + */ +public enum FilePermissionType implements BaseEnum { + + // 公开 + PUBLIC(0, "公开"), + // 私有 + PRIVATE(1, "私有"), + ; + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 初始化方法 + * + * @param code Code + * @param desc 说明 + */ + FilePermissionType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 判断枚举值类型 + * + * @param code 枚举值 + * @return 枚举值类型 + */ + public static FilePermissionType valueOfCode(int code) { + for (FilePermissionType type : values()) { + if (type.code == code) { + return type; + } + } + return null; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileDownloadCallback.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileDownloadCallback.java new file mode 100644 index 0000000..6495efb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileDownloadCallback.java @@ -0,0 +1,28 @@ +package xtools.app.sys.file.service; + +import xtools.app.sys.model.dto.resp.SysFileResp; + +/** + *

Title : SysFileDownloadCallback

+ *

Description : SysFileDownloadCallback

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : Windows11

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/10 21:59 + */ +public interface SysFileDownloadCallback { + + /** + * 下载前回调 + * + * @param fileInfo 文件信息 + * @return 是否继续下载 + */ + default boolean before(SysFileResp fileInfo) { + return true; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileOptService.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileOptService.java new file mode 100644 index 0000000..eafb1fb --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/SysFileOptService.java @@ -0,0 +1,142 @@ +package xtools.app.sys.file.service; + +import org.jspecify.annotations.NonNull; +import xtools.app.sys.file.enums.FileBizBaseEnum; +import xtools.app.sys.model.dto.resp.SysFileResp; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +/** + *

Title : SysFileOptService

+ *

Description : SysFileOptService

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/14 14:06 + */ +public interface SysFileOptService { + + /** + * 文件是否存在 + * + * @param id 文件ID + * @return 是否存在 + */ + boolean exists(long id); + + /** + * 文件是否存在 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @return 是否存在 + */ + boolean exists(String bucket, String fileName); + + /** + * 文件上传 + * + * @param fileName 文件名 + * @param inputStream 文件输入流 + * @param contentLength 文件长度 + * @param userId 用户ID + * @param userName 用户名 + * @param bizType 业务类型 + * @param bizId 业务ID + * @return 文件ID + */ + Long upload( + @NonNull String fileName, + @NonNull InputStream inputStream, + long contentLength, + @NonNull Long userId, + @NonNull String userName, + @NonNull FileBizBaseEnum bizType, + Long bizId + ); + + /** + * 文件下载 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @param outputStream 输出流 + * @return 文件信息 + */ + SysFileResp download(String bucket, String fileName, @NonNull OutputStream outputStream); + + /** + * 文件下载 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @param outputStream 输出流 + * @param callback 回调 + * @return 文件信息 + */ + SysFileResp download(String bucket, String fileName, @NonNull OutputStream outputStream, SysFileDownloadCallback callback); + + /** + * 文件下载 + * + * @param id 文件ID + * @param outputStream 输出流 + * @return 文件信息 + */ + SysFileResp download( + long id, + @NonNull OutputStream outputStream + ); + + /** + * 文件下载 + * + * @param id 文件ID + * @param outputStream 输出流 + * @param callback 回调 + * @return 文件信息 + */ + SysFileResp download( + long id, + @NonNull OutputStream outputStream, + SysFileDownloadCallback callback + ); + + /** + * 文件删除 + * + * @param id 文件ID + * @return 删除结果 + */ + boolean delete(long id); + + /** + * 文件删除 + * + * @param idList 文件ID列表 + * @return 删除结果 + */ + boolean delete(List idList); + + /** + * 文件成功 + * + * @param id 文件ID + * @return 成功结果 + */ + boolean success(long id); + + /** + * 文件成功 + * + * @param idList 文件ID列表 + * @return 成功结果 + */ + boolean success(List idList); + +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/impl/SysFileOptServiceImpl.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/impl/SysFileOptServiceImpl.java new file mode 100644 index 0000000..158eb67 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/service/impl/SysFileOptServiceImpl.java @@ -0,0 +1,353 @@ +package xtools.app.sys.file.service.impl; + +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jspecify.annotations.NonNull; +import org.springframework.stereotype.Service; +import xtools.app.sys.api.SysFileApi; +import xtools.app.sys.file.enums.FileBizBaseEnum; +import xtools.app.sys.file.service.SysFileDownloadCallback; +import xtools.app.sys.file.service.SysFileOptService; +import xtools.app.sys.model.dto.req.SysFileAddReq; +import xtools.app.sys.model.dto.req.SysFileChangeReq; +import xtools.app.sys.model.dto.resp.SysFileResp; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.FileDataType; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.storage.base.config.StorageConfig; +import xtools.boot.storage.base.service.StorageService; +import xtools.core.CollectionUtils; +import xtools.core.FileUtils; +import xtools.core.HexUtils; +import xtools.core.StringUtils; +import xtools.core.UuidUtils; +import xtools.core.encrypt.Md5Utils; +import xtools.core.extend.CheckUtils; +import xtools.core.time.CalendarUtils; +import xtools.extend.encrypt.Sm3Utils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.time.Instant; +import java.util.Calendar; +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysFileOptServiceImpl

+ *

Description : SysFileOptServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/14 14:16 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SysFileOptServiceImpl implements SysFileOptService, BaseParams { + + /** + * 文件最大长度 + */ + private final static long MAX_FILE_SIZE = 5 * 1024 * 1024 * 1024L; + + private final SysFileApi sysFileApi; + + @Resource + private StorageConfig storageConfig; + + @Resource + private StorageService storageService; + + /** + * 文件是否存在 + * + * @param id 文件ID + * @return 是否存在 + */ + @Override + public boolean exists(long id) { + SysFileResp data = getFileData(id); + return storageService.exists(data.getBucket(), data.getFilePath()); + } + + /** + * 文件是否存在 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @return 是否存在 + */ + @Override + public boolean exists(String bucket, String fileName) { + SysFileResp data = getFileData(bucket, fileName); + return storageService.exists(data.getBucket(), data.getFilePath()); + } + + /** + * 文件上传 + * + * @param fileName 文件名 + * @param inputStream 文件输入流 + * @param contentLength 文件长度 + * @param userId 用户ID + * @param userName 用户名 + * @param bizType 业务类型 + * @param bizId 业务ID + * @return 文件ID + */ + @Override + public Long upload( + @NonNull String fileName, + @NonNull InputStream inputStream, + long contentLength, + @NonNull Long userId, + @NonNull String userName, + @NonNull FileBizBaseEnum bizType, + Long bizId + ) { + // 上传事件 + Instant uploadTime = Instant.now(); + // 计算文件码 + String md5 = null; + String sm3 = null; + if (contentLength <= MAX_FILE_SIZE) { + // 小于5MB的文件才计算文件码 + try { + byte[] bytes = inputStream.readAllBytes(); + inputStream = new ByteArrayInputStream(bytes); + contentLength = bytes.length; + if (contentLength <= 0) { + throw new BizError("文件长度错误"); + } + byte[] md5Bytes = Md5Utils.encrypt(bytes); + if (Objects.nonNull(md5Bytes)) { + md5 = HexUtils.formatHex(md5Bytes); + } + byte[] sm3Bytes = Sm3Utils.encrypt(bytes); + if (Objects.nonNull(sm3Bytes)) { + sm3 = HexUtils.formatHex(sm3Bytes); + } + } catch (IOException e) { + log.error("计算文件码失败", e); + throw new BizError("计算文件码失败"); + } + } + // 获取文件后缀 + String suffix = FileUtils.getSuffix(fileName); + if (StringUtils.isBlank(suffix)) { + throw new BizError("文件格式错误"); + } + // 文件存储器的文件名 + String filePath = UuidUtils.get() + CP_LINE + fileName; + // 获取存储桶 + String bucket = bizType.bucket(); + // 计算过期时间 + int expireTime = bizType.expireTime(); + if (expireTime <= CP_NUM0) { + expireTime = CP_NUM1; + } + Instant expireDate = CalendarUtils.calc(Calendar.HOUR_OF_DAY, expireTime); + // 保存文件 + storageService.save(bucket, filePath, inputStream, contentLength); + SysFileAddReq req = new SysFileAddReq(); + req.setUserId(userId); + req.setUserName(userName); + req.setBizId(Objects.nonNull(bizId) ? bizId : bizType.code()); + req.setBizType(bizType.desc()); + req.setPermission(bizType.permission().code()); + req.setBucket(bucket); + req.setStorageType(storageConfig.getType()); + req.setUploadTime(uploadTime); + req.setFilePath(filePath); + req.setFileName(fileName); + req.setFileSize(contentLength); + req.setFileType(suffix); + req.setMd5(md5); + req.setSm3(sm3); + req.setDataType(FileDataType.TEMP.code()); + req.setExpireTime(expireDate); + Result result = sysFileApi.add(req); + Long id = result.data(); + if (CheckUtils.id(id)) { + return id; + } + // 保存记录失败删除文件 + storageService.del(bucket, fileName); + throw new BizError("文件上传失败"); + } + + /** + * 文件下载 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @param outputStream 输出流 + * @return 文件信息 + */ + @Override + public SysFileResp download(String bucket, String fileName, @NonNull OutputStream outputStream) { + return download(bucket, fileName, outputStream, null); + } + + /** + * 文件下载 + * + * @param bucket 存储桶 + * @param fileName 文件名 + * @param outputStream 输出流 + * @param callback 回调 + * @return 文件信息 + */ + @Override + public SysFileResp download(String bucket, String fileName, @NonNull OutputStream outputStream, SysFileDownloadCallback callback) { + return download(getFileData(bucket, fileName), outputStream, callback); + } + + /** + * 文件下载 + * + * @param id 文件ID + * @param outputStream 输出流 + * @return 文件信息 + */ + @Override + public SysFileResp download(long id, @NonNull OutputStream outputStream) { + return download(id, outputStream, null); + } + + /** + * 文件下载 + * + * @param id 文件ID + * @param outputStream 输出流 + * @param callback 回调 + * @return 文件信息 + */ + @Override + public SysFileResp download(long id, @NonNull OutputStream outputStream, SysFileDownloadCallback callback) { + return download(getFileData(id), outputStream, callback); + } + + /** + * 文件下载 + * + * @param data 文件信息 + * @param outputStream 输出流 + * @param callback 回调 + * @return 文件信息 + */ + private SysFileResp download(SysFileResp data, @NonNull OutputStream outputStream, SysFileDownloadCallback callback) { + if (Objects.isNull(data)) { + throw new BizError("文件不存在"); + } + if (Objects.equals(FileDataType.DELETE.code(), data.getDataType())) { + throw new BizError("文件已删除"); + } + if (Objects.equals(FileDataType.TEMP.code(), data.getDataType()) && Instant.now().isAfter(data.getExpireTime())) { + delete(data.getId()); + throw new BizError("文件已过期"); + } + String type = storageConfig.getType(); + if (!Objects.equals(type, data.getStorageType())) { + throw new BizError("文件不存在"); + } + if (Objects.nonNull(callback)) { + if (!callback.before(data)) { + return data; + } + } + storageService.get(data.getBucket(), data.getFilePath(), outputStream); + return data; + } + + /** + * 文件删除 + * + * @param id 文件ID + * @return 删除结果 + */ + @Override + public boolean delete(long id) { + return delete(List.of(id)); + } + + /** + * 文件删除 + * + * @param idList 文件ID列表 + * @return 删除结果 + */ + @Override + public boolean delete(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return true; + } + sysFileApi.changeDataTypeByIds(new SysFileChangeReq(idList, FileDataType.DELETE)); + return true; + } + + /** + * 文件成功 + * + * @param id 文件ID + * @return 成功结果 + */ + @Override + public boolean success(long id) { + return success(List.of(id)); + } + + /** + * 文件成功 + * + * @param idList 文件ID列表 + * @return 成功结果 + */ + @Override + public boolean success(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return true; + } + sysFileApi.changeDataTypeByIds(new SysFileChangeReq(idList, FileDataType.OK)); + return true; + } + + /** + * 获取文件数据 + * + * @param id 文件ID + * @return 文件数据 + */ + private SysFileResp getFileData(long id) { + Result result = sysFileApi.getById(id); + SysFileResp data = result.data(); + if (Objects.isNull(data)) { + throw new BizError("文件不存在"); + } + return data; + } + + /** + * 获取文件数据 + * + * @param bucket 桶名称 + * @param fileName 文件名 + * @return 文件数据 + */ + private SysFileResp getFileData(String bucket, String fileName) { + Result result = sysFileApi.getByName(bucket, fileName); + SysFileResp data = result.data(); + if (Objects.isNull(data)) { + throw new BizError("文件不存在"); + } + return data; + } +} diff --git a/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/utils/FileIdUtils.java b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/utils/FileIdUtils.java new file mode 100644 index 0000000..ce39cbc --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-file/src/main/java/xtools/app/sys/file/utils/FileIdUtils.java @@ -0,0 +1,82 @@ +package xtools.app.sys.file.utils; + +import lombok.extern.slf4j.Slf4j; +import xtools.boot.api.exection.BizError; +import xtools.core.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *

Title : FileIdUtils

+ *

Description : FileIdUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/17 19:49 + */ +@Slf4j +public class FileIdUtils { + + /** + * 获取基础文件ID的正则表达式 + */ + private final static Pattern BASE_PATTERN = Pattern.compile("/sys/common/get/(\\d+)/file"); + + /** + * 获取文件ID + * + * @param content 文件内容 + * @return 文件ID + */ + public static List get(String content) { + return get(BASE_PATTERN, content); + } + + /** + * 获取文件ID + * + * @param content 文件内容 + * @param regex 正则表达式 + * @return 文件ID + */ + public static List get(String content, String regex) { + if (StringUtils.isBlank(regex)) { + throw new BizError("regex 不能为空"); + } + return get(Pattern.compile(regex), content); + } + + /** + * 获取文件ID + * + * @param pattern 正则表达式 + * @param content 文件内容 + * @return 文件ID + */ + private static List get(Pattern pattern, String content) { + List idList = new ArrayList<>(); + if (StringUtils.isBlank(content)) { + return idList; + } + Matcher matcher = pattern.matcher(content); + while (matcher.find()) { + String number = matcher.group(1); + if (StringUtils.isBlank(number)) { + continue; + } + try { + idList.add(Long.parseLong(number.trim())); + } catch (NumberFormatException e) { + log.info("{}无法转为Long类型", number); + } + } + return idList; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/pom.xml b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/pom.xml new file mode 100644 index 0000000..ceb2237 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-log-bus-elasticsearch + + + + + + org.xujun + xtools-app-sys-biz + + + + + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/config/SysLogElasticsearchConfig.java b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/config/SysLogElasticsearchConfig.java new file mode 100644 index 0000000..43976ce --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/config/SysLogElasticsearchConfig.java @@ -0,0 +1,44 @@ +package xtools.app.sys.log.bus.elasticsearch.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import xtools.app.sys.log.bus.elasticsearch.service.impl.EsSysLogServiceImpl; +import xtools.app.sys.service.SysLogService; + +/** + *

Title : SysLogElasticsearchConfig

+ *

Description : SysLogElasticsearchConfig

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/14 10:29 + */ +@Slf4j +@Configuration +@EnableElasticsearchRepositories(basePackages = "xtools.app.sys.log.bus.elasticsearch.service.base") +public class SysLogElasticsearchConfig { + + /** + * 日志类型elasticsearch + */ + private static final String TYPE_ES = "elasticsearch"; + + /** + * 获取ES日志服务 + * + * @return 日志服务 + */ + @Bean + @ConditionalOnProperty(prefix = "sys.log", name = "type", havingValue = TYPE_ES) + public SysLogService getEsSysLogService() { + log.info("系统日志存储类型:{}", TYPE_ES); + return new EsSysLogServiceImpl(); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/convert/SysLogElasticsearchConvert.java b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/convert/SysLogElasticsearchConvert.java new file mode 100644 index 0000000..8a12902 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/convert/SysLogElasticsearchConvert.java @@ -0,0 +1,27 @@ +package xtools.app.sys.log.bus.elasticsearch.convert; + +import org.mapstruct.Mapper; +import xtools.app.sys.log.bus.elasticsearch.dto.EsSysLog; +import xtools.app.sys.model.entity.SysLog; + +/** + *

Title : SysLogElasticsearchConvert

+ *

Description : SysLogElasticsearchConvert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-07 20:09:03 + */ +@Mapper(componentModel = "spring") +public interface SysLogElasticsearchConvert { + + /** + * 实体转ES + * + * @param data 实体 + * @return ES + */ + EsSysLog entityToEs(SysLog data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/dto/EsSysLog.java b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/dto/EsSysLog.java new file mode 100644 index 0000000..1fe729d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/dto/EsSysLog.java @@ -0,0 +1,143 @@ +package xtools.app.sys.log.bus.elasticsearch.dto; + +import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +/** + *

Title : EsSysLog

+ *

Description : EsSysLog

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/13 19:34 + */ +@Data +@Document(indexName = EsSysLog.INDEX_NAME) +public class EsSysLog { + + /** + * ES索引名称 + **/ + public static final String INDEX_NAME = "log-sys_v16"; + + /** + * 主键 ID + */ + @Id + private String id; + + /** + * 日志ID + */ + @Field(type = FieldType.Text) + private String logId; + + /** + * 日志追踪ID + */ + @Field(type = FieldType.Text) + private String traceId; + + /** + * 日志父ID + */ + @Field(type = FieldType.Text) + private String parentId; + + /** + * 日志线程类型 + */ + @Field(type = FieldType.Text) + private String threadType; + + /** + * 日志时间 + */ + @Field(type = FieldType.Long) + private Long logTime; + + /** + * 日志获取索引 + */ + @Field(type = FieldType.Integer) + private Integer logIndex; + + /** + * 服务名称 + */ + @Field(type = FieldType.Text) + private String appName; + + /** + * 本机IP + */ + @Field(type = FieldType.Text) + private String localIp; + + /** + * 运行端口 + */ + @Field(type = FieldType.Text) + private String port; + + /** + * 日志标题 + */ + @Field(type = FieldType.Text) + private String title; + + /** + * 日志级别 + */ + @Field(type = FieldType.Integer) + private Integer logLevel; + + /** + * 日志类型 + */ + @Field(type = FieldType.Text) + private String logType; + + /** + * 请求IP + */ + @Field(type = FieldType.Text) + private String ip; + + /** + * 请求URI + */ + @Field(type = FieldType.Text) + private String uri; + + /** + * 日志内容 + */ + @Field(type = FieldType.Text) + private String logBody; + + /** + * 堆栈信息 + */ + @Field(type = FieldType.Text) + private String stackTrace; + + /** + * 日志错误信息 + */ + @Field(type = FieldType.Text) + private String logError; + + /** + * 备注 + */ + @Field(type = FieldType.Text) + private String memo; + +} diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/base/EsSysLogRepository.java b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/base/EsSysLogRepository.java new file mode 100644 index 0000000..4cb604f --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/base/EsSysLogRepository.java @@ -0,0 +1,20 @@ +package xtools.app.sys.log.bus.elasticsearch.service.base; + +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Component; +import xtools.app.sys.log.bus.elasticsearch.dto.EsSysLog; + +/** + *

Title : EsSysLogRepository

+ *

Description : EsSysLogRepository

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/13 19:42 + */ +@Component +public interface EsSysLogRepository extends ElasticsearchRepository { +} diff --git a/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/impl/EsSysLogServiceImpl.java b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/impl/EsSysLogServiceImpl.java new file mode 100644 index 0000000..c9f7240 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-log-bus-elasticsearch/src/main/java/xtools/app/sys/log/bus/elasticsearch/service/impl/EsSysLogServiceImpl.java @@ -0,0 +1,307 @@ +package xtools.app.sys.log.bus.elasticsearch.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import jakarta.annotation.Resource; +import xtools.app.sys.log.bus.elasticsearch.convert.SysLogElasticsearchConvert; +import xtools.app.sys.log.bus.elasticsearch.dto.EsSysLog; +import xtools.app.sys.log.bus.elasticsearch.service.base.EsSysLogRepository; +import xtools.app.sys.model.dto.req.SysLogPageReq; +import xtools.app.sys.model.dto.resp.SysLogResp; +import xtools.app.sys.model.entity.SysLog; +import xtools.app.sys.service.SysLogService; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.elasticsearch.utils.EsQueryUtils; +import xtools.boot.elasticsearch.utils.EsUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.core.CollectionUtils; +import xtools.core.enums.LogLevel; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

Title : EsSysLogServiceImpl

+ *

Description : EsSysLogServiceImpl

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/13 19:43 + */ +public class EsSysLogServiceImpl implements SysLogService, BaseParams { + + @Resource + private EsSysLogRepository esSysLogRepository; + + @Resource + private SysLogElasticsearchConvert sysLogElasticsearchConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 查询条件 + JSONObject req = getPageReq(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + // 结果 + JSONObject resp = null; + try { + resp = EsUtils.exec(getDbUri() + "_search", req); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.ELASTICSEARCH).data(req).title("系统日志ES查询失败").error(e).save(); + } + return Result.ok(getPageResult(pageReq.getCurrentPage(), pageReq.getPageSize(), resp)); + } + + /** + * 获取分页结果 + * + * @param currentPage 当前页 + * @param pageSize 页大小 + * @param resp 查询结果 + * @return 分页结果 + */ + private PageResp getPageResult(Integer currentPage, Integer pageSize, JSONObject resp) { + PageResp pageResp = new PageResp<>(); + pageResp.setCurrentPage(currentPage); + pageResp.setPageSize(pageSize); + pageResp.setTotal(0L); + if (CollectionUtils.isEmpty(resp)) { + return pageResp; + } + JSONObject hits = resp.getJSONObject("hits"); + if (CollectionUtils.isEmpty(hits)) { + return pageResp; + } + Long total = hits.getJSONObject("total").getLong("value"); + JSONArray resultList = hits.getJSONArray("hits"); + if (CollectionUtils.isEmpty(resultList)) { + return pageResp; + } + List dataList = new ArrayList<>(); + for (Object obj : resultList) { + if (obj instanceof JSONObject item) { + JSONObject source = item.getJSONObject("_source"); + source.remove("logBody"); + source.remove("stackTrace"); + source.remove("logError"); + dataList.add(JSON.to(SysLogResp.class, source)); + } + } + pageResp.setData(dataList); + pageResp.setTotal(total); + return pageResp; + } + + + /** + * 获取分页查询条件 + * + * @param currentPage 当前页 + * @param pageSize 页大小 + * @param req 请求参数 + * @return 查询条件 + */ + private JSONObject getPageReq(Integer currentPage, Integer pageSize, SysLogPageReq req) { + // 查询条件处理 + JSONArray must = new JSONArray(); + EsQueryUtils.setTimeRange(must, "logTime", req.getLogTimeRange()); + + EsQueryUtils.setMatchPhrase(must, "traceId", req.getTraceId()); + EsQueryUtils.setMatchPhrase(must, "logType", req.getLogType()); + EsQueryUtils.setMatchPhrase(must, "logLevel", req.getLogLevel()); + + EsQueryUtils.setWildcard(must, "title", req.getTitle()); + EsQueryUtils.setWildcard(must, "ip", req.getIp()); + EsQueryUtils.setWildcard(must, "uri", req.getUri()); + + EsQueryUtils.setMatchPhrase(must, "threadType", req.getThreadType()); + + EsQueryUtils.setWildcard(must, "appName", req.getAppName()); + EsQueryUtils.setWildcard(must, "localIp", req.getLocalIp()); + EsQueryUtils.setWildcard(must, "port", req.getPort()); + + JSONObject query = JSONObject.of("bool", JSONObject.of("must", must)); + + // 排序条件 + JSONArray sort = new JSONArray(); + sort.add(JSONObject.of("logTime", JSONObject.of("order", "desc"))); + sort.add(JSONObject.of("logIndex", JSONObject.of("order", "desc"))); + + // 完整查询器 + return JSONObject.of("from", ((currentPage - 1) * pageSize), "size", pageSize, "query", query, "sort", sort); + } + + /** + * 根据日志 ID 查询 + * + * @param logId 日志 ID + * @return 结果 + */ + @Override + public Result getByLogId(String logId) { + // 查询条件 + JSONArray fields = new JSONArray(); + fields.add("logId"); + JSONObject query = JSONObject.of("multi_match", JSONObject.of("query", logId, "fields", fields)); + // 完整查询器 + JSONObject req = JSONObject.of("from", CP_NUM0, "size", CP_NUM1, "query", query); + // 结果 + JSONObject resp = null; + try { + resp = EsUtils.exec(getDbUri() + "_search", req); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.ELASTICSEARCH).data(req).title("系统日志ES查询失败").error(e).save(); + } + List result = getQueryByTraceIdResult(resp); + if (CollectionUtils.isEmpty(result)) { + throw new BizError("日志ID不存在"); + } + SysLogResp data = new SysLogResp(); + data.setLogBody(result.getFirst().getLogBody()); + return Result.ok(data); + } + + /** + * 根据traceId查询 + * + * @param traceId traceId + * @return 日志列表 + */ + @Override + public Result> getByTraceId(String traceId) { + // 获取查询器 + JSONObject req = getQueryByTraceIdReq(traceId); + // 结果 + JSONObject resp = null; + try { + resp = EsUtils.exec(getDbUri() + "_search", req); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.ELASTICSEARCH).data(req).title("系统日志ES查询失败").error(e).save(); + } + return Result.ok(getQueryByTraceIdResult(resp)); + } + + /** + * 获取查询请求参数 + * + * @param traceId 日志追踪ID + * @return 查询请求参数 + */ + private JSONObject getQueryByTraceIdReq(String traceId) { + // 查询条件 + JSONArray fields = new JSONArray(); + fields.add("traceId"); + JSONObject query = JSONObject.of("multi_match", JSONObject.of("query", traceId, "fields", fields)); + // 排序条件 + JSONArray sort = new JSONArray(); + sort.add(JSONObject.of("logIndex", JSONObject.of("order", "asc"))); + sort.add(JSONObject.of("logTime", JSONObject.of("order", "asc"))); + // 完整查询器 + return JSONObject.of("from", CP_NUM0, "size", CP_NUM10 * CP_NUM1000, "query", query, "sort", sort); + } + + /** + * 获取查询结果 + * + * @param resp 结果集 + * @return 查询结果 + */ + private List getQueryByTraceIdResult(JSONObject resp) { + if (CollectionUtils.isEmpty(resp)) { + return null; + } + JSONArray resultList = resp.getJSONObject("hits").getJSONArray("hits"); + if (CollectionUtils.isEmpty(resultList)) { + return null; + } + List dataList = new ArrayList<>(); + for (Object obj : resultList) { + if (obj instanceof JSONObject item) { + JSONObject source = item.getJSONObject("_source"); + dataList.add(JSON.to(SysLogResp.class, source)); + } + } + return dataList; + } + + /** + * 保存 + * + * @param sysLog 日志 + * @return 是否保存成功 + */ + @Override + public boolean save(SysLog sysLog) { + EsSysLog esSysLog = sysLogElasticsearchConvert.entityToEs(sysLog); + esSysLogRepository.save(esSysLog); + return true; + } + + /** + * 删除 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 删除数量 + */ + @Override + public long delete(Instant startTime, Instant endTime) { + if (Objects.isNull(endTime)) { + return CP_NUM0; + } + long end = endTime.toEpochMilli(); + long start = CP_NUM0; + if (Objects.nonNull(startTime)) { + start = startTime.toEpochMilli(); + } + JSONObject req = JSONObject.of( + "query", + JSONObject.of( + "range", + JSONObject.of( + "logTime", + JSONObject.of( + "gte", start, + "lte", end + ) + ) + ) + ); + // 结果 + JSONObject resp = null; + try { + resp = EsUtils.exec(getDbUri() + "_delete_by_query", req); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.ELASTICSEARCH).data(req).title("系统日志ES删除失败").error(e).save(); + } + if (CollectionUtils.isEmpty(resp)) { + return CP_NUM0; + } + Long deleted = resp.getLong("deleted"); + return Objects.nonNull(deleted) ? deleted : CP_NUM0; + } + + /** + * 获取DB的请求路径 + * + * @return DB的请求路径 + */ + private String getDbUri() { + return CP_SLASH + EsSysLog.INDEX_NAME + CP_SLASH; + } +} diff --git a/xtools-app-sys/xtools-app-sys-param/pom.xml b/xtools-app-sys/xtools-app-sys-param/pom.xml new file mode 100644 index 0000000..16cccfa --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-param + + + + + + + org.xujun + xtools-boot-api + + + + org.xujun + xtools-boot-cache-redis + + + + + + org.xujun + xtools-app-common-cache + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/SysBlacklistDto.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/SysBlacklistDto.java new file mode 100644 index 0000000..c4cf8f9 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/SysBlacklistDto.java @@ -0,0 +1,32 @@ +package xtools.app.sys.param.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *

Title : SysBlacklistDto

+ *

Description : SysBlacklistDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/18 16:03 + */ +@Data +public class SysBlacklistDto implements Serializable { + + /** + * ip + */ + private List ipList; + + /** + * uri + */ + private List uriList; + +} diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/UpdateHistoryDto.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/UpdateHistoryDto.java new file mode 100644 index 0000000..b9401ad --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/dto/UpdateHistoryDto.java @@ -0,0 +1,40 @@ +package xtools.app.sys.param.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +/** + *

Title : UpdateHistoryDto

+ *

Description : UpdateHistoryDto

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/3 09:39 + */ +@Data +public class UpdateHistoryDto implements Serializable { + + /** + * 信息 + */ + @Schema(description = "信息") + private String info; + + /** + * 显示时间 + */ + @Schema(description = "显示时间") + private String showTime; + + /** + * 所属版本 + */ + @Schema(description = "所属版本") + private String version; + +} diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamBaseEnum.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamBaseEnum.java new file mode 100644 index 0000000..10c0c35 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamBaseEnum.java @@ -0,0 +1,25 @@ +package xtools.app.sys.param.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysParamBaseEnum

+ *

Description : SysParamBaseEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/26 10:29 + */ +public interface SysParamBaseEnum extends BaseEnum { + + /** + * 获取数据类型 + * + * @return 数据类型 + */ + SysParamDataType type(); + +} diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamDataType.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamDataType.java new file mode 100644 index 0000000..5087c32 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamDataType.java @@ -0,0 +1,75 @@ +package xtools.app.sys.param.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysParamDataType

+ *

Description : SysParamDataType

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/4 16:27 + */ +public enum SysParamDataType implements BaseEnum { + + // json + JSON(1, "json"), + // array + ARRAY(2, "array"), + ; + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 构造函数 + * + * @param code 编码 + * @param desc 说明 + */ + SysParamDataType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamEnum.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamEnum.java new file mode 100644 index 0000000..5ea2569 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/enums/SysParamEnum.java @@ -0,0 +1,89 @@ +package xtools.app.sys.param.enums; + +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysParamEnum

+ *

Description : SysParamEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/4 16:27 + */ +public enum SysParamEnum implements SysParamBaseEnum { + + // 系统更新历史 + UPDATE_HISTORY(2, "sys-update-history", SysParamDataType.ARRAY); + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 数据类型 + */ + private final SysParamDataType type; + + /** + * 构造函数 + * + * @param code 编码 + * @param desc 说明 + * @param type 数据类型 + */ + SysParamEnum(int code, String desc, SysParamDataType type) { + this.code = code; + this.desc = desc; + this.type = type; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + + /** + * 获取数据类型 + * + * @return 数据类型 + */ + @Override + public SysParamDataType type() { + return type; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/utils/SysParamUtils.java b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/utils/SysParamUtils.java new file mode 100644 index 0000000..d78dd01 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-param/src/main/java/xtools/app/sys/param/utils/SysParamUtils.java @@ -0,0 +1,244 @@ +package xtools.app.sys.param.utils; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import xtools.app.common.cache.enums.AppCache; +import xtools.app.sys.param.enums.SysParamBaseEnum; +import xtools.app.sys.param.enums.SysParamDataType; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.core.CollectionUtils; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysParamUtils

+ *

Description : SysParamUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/3/18 15:50 + */ +@Slf4j +public class SysParamUtils implements BaseParams { + + /** + * 系统参数缓存 + */ + private static final AppCache CACHE_PARAM = AppCache.SYS_CACHE_PARAM; + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param bizType 业务类型 + * @param clazz 数据类型 + * @param 数据类型 + * @return 数据 + */ + public static T get(SysParamBaseEnum sysParamEnum, Object bizType, Class clazz) { + RedisService redisService = RedisUtils.get(); + try { + return redisService.get(getCacheKey(sysParamEnum.type(), sysParamEnum.desc(), bizType), clazz); + } catch (Exception e) { + log.error("获取缓存异常,dataType:{},dataKey:{}", sysParamEnum.type(), sysParamEnum.desc(), e); + throw new BizError("获取缓存异常"); + } + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param clazz 数据类型 + * @param defaultValue 默认值 + * @param 数据类型 + * @return 数据 + */ + public static T getOrDefault(SysParamBaseEnum sysParamEnum, Class clazz, T defaultValue) { + T data = get(sysParamEnum, clazz); + if (Objects.nonNull(data)) { + return data; + } + return defaultValue; + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param clazz 数据类型 + * @param 数据类型 + * @return 数据 + */ + public static T get(SysParamBaseEnum sysParamEnum, Class clazz) { + RedisService redisService = RedisUtils.get(); + try { + return redisService.get(getCacheKey(sysParamEnum.type(), sysParamEnum.desc()), clazz); + } catch (Exception e) { + log.error("获取缓存异常,dataType:{},dataKey:{}", sysParamEnum.type(), sysParamEnum.desc(), e); + throw new BizError("获取缓存异常"); + } + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param defaultValue 默认值 + * @return 数据 + */ + public static JSONObject getJsonOrDefault(SysParamBaseEnum sysParamEnum, JSONObject defaultValue) { + JSONObject data = getJson(sysParamEnum); + if (CollectionUtils.isNotEmpty(data)) { + return data; + } + return defaultValue; + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @return 数据 + */ + public static JSONObject getJson(SysParamBaseEnum sysParamEnum) { + RedisService redisService = RedisUtils.get(); + try { + return redisService.get(getCacheKey(sysParamEnum.type(), sysParamEnum.desc()), JSONObject.class); + } catch (Exception e) { + log.error("获取缓存异常,dataType:{},dataKey:{}", sysParamEnum.type(), sysParamEnum.desc(), e); + throw new BizError("获取缓存异常"); + } + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param bizType 业务类型 + * @param clazz 数据类型 + * @param 数据类型 + * @return 数据 + */ + public static List getArray(SysParamBaseEnum sysParamEnum, Object bizType, Class clazz) { + RedisService redisService = RedisUtils.get(); + try { + JSONArray array = redisService.get(getCacheKey(sysParamEnum.type(), sysParamEnum.desc(), bizType), JSONArray.class); + if (Objects.nonNull(array)) { + return array.toJavaList(clazz); + } + return null; + } catch (Exception e) { + log.error("获取缓存异常,dataType:{},dataKey:{}", sysParamEnum.type(), sysParamEnum.desc(), e); + throw new BizError("获取缓存异常"); + } + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param clazz 数据类型 + * @param defaultValue 默认值 + * @param 数据类型 + * @return 数据 + */ + public static List getArrayOrDefault(SysParamBaseEnum sysParamEnum, Class clazz, List defaultValue) { + List array = getArray(sysParamEnum, clazz); + if (Objects.nonNull(array)) { + return array; + } + return defaultValue; + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param clazz 数据类型 + * @param 数据类型 + * @return 数据 + */ + public static List getArray(SysParamBaseEnum sysParamEnum, Class clazz) { + JSONArray array = getArray(sysParamEnum); + if (Objects.nonNull(array)) { + return array.toJavaList(clazz); + } + return null; + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @param defaultValue 默认值 + * @return 数据 + */ + public static JSONArray getArrayOrDefault(SysParamBaseEnum sysParamEnum, JSONArray defaultValue) { + JSONArray data = getArray(sysParamEnum); + if (Objects.nonNull(data)) { + return data; + } + return defaultValue; + } + + /** + * 获取系统缓存数据 + * + * @param sysParamEnum 系统参数枚举 + * @return 数据 + */ + public static JSONArray getArray(SysParamBaseEnum sysParamEnum) { + RedisService redisService = RedisUtils.get(); + try { + return redisService.get(getCacheKey(sysParamEnum.type(), sysParamEnum.desc()), JSONArray.class); + } catch (Exception e) { + log.error("获取缓存异常,dataType:{},dataKey:{}", sysParamEnum.type(), sysParamEnum.desc(), e); + throw new BizError("获取缓存异常"); + } + } + + /** + * 获取缓存的 key + * + * @param dataType 数据类型 + * @param dataKey 数据 key + * @param bizType 业务类型 + * @return 缓存的 key + */ + public static String getCacheKey(SysParamDataType dataType, String dataKey, Object bizType) { + return CACHE_PARAM.key() + dataType.desc() + CP_COLON + dataKey + bizType; + } + + /** + * 获取缓存的 key + * + * @param dataType 数据类型 + * @param dataKey 数据 key + * @return 缓存的 key + */ + public static String getCacheKey(SysParamDataType dataType, String dataKey) { + return CACHE_PARAM.key() + dataType.desc() + CP_COLON + dataKey; + } + + /** + * 获取缓存的 key + * + * @param dataType 数据类型 + * @param dataKey 数据 key + * @return 缓存的 key + */ + public static String getCacheKey(Integer dataType, String dataKey) { + String type = Objects.equals(dataType, CP_NUM1) ? "json" : "array"; + return CACHE_PARAM.key() + type + CP_COLON + dataKey; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-risk/pom.xml b/xtools-app-sys/xtools-app-sys-risk/pom.xml new file mode 100644 index 0000000..4ecf797 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-risk + + + + + + + org.xujun + xtools-boot-cache-redis + + + + + + org.xujun + xtools-app-common-cache + + + + org.xujun + xtools-app-sys-api + + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/IpRisk.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/IpRisk.java new file mode 100644 index 0000000..2dd07a8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/IpRisk.java @@ -0,0 +1,86 @@ +package xtools.app.sys.risk; + +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import xtools.app.sys.api.SysRiskApi; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.app.sys.risk.utils.IpRiskUtils; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.core.CollectionUtils; + +import java.util.List; + +/** + *

Title : IpRisk

+ *

Description : IpRisk

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : Windows11

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/6 17:22 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class IpRisk implements BaseParams { + + private final SysRiskApi sysRiskApi; + + @Resource + private RedisService redisService; + + /** + * 初始化 + */ + public void init() { + List dataList = sysRiskApi.getByType(SysRiskType.IP).data(); + if (CollectionUtils.isEmpty(dataList)) { + log.info("无IP风控数据"); + return; + } + for (SysRiskResp item : dataList) { + IpRiskUtils.addAll(item.getSysType(), item.getData()); + log.info("初始化[{}]IP风控成功", item.getSysType()); + } + } + + /** + * 添加IP风控 + * + * @param sysType 系统类型 + * @param ip IP + */ + public void add(String sysType, String ip) { + redisService.hashPut(IpRiskUtils.getKey(sysType), ip, CP_NUM0); + sysRiskApi.addIp(sysType, ip); + } + + /** + * 删除IP风控 + * + * @param sysType 系统类型 + * @param ip IP + */ + public void remove(String sysType, String ip) { + redisService.hashDelete(IpRiskUtils.getKey(sysType), ip); + sysRiskApi.removeIp(sysType, ip); + } + + /** + * 判断IP是否风控 + * + * @param sysType 系统类型 + * @param ip IP + * @return 是否风控 + */ + public boolean risk(String sysType, String ip) { + return redisService.hashExists(IpRiskUtils.getKey(sysType), ip); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/UriRisk.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/UriRisk.java new file mode 100644 index 0000000..cd353df --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/UriRisk.java @@ -0,0 +1,77 @@ +package xtools.app.sys.risk; + +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import xtools.app.sys.api.SysRiskApi; +import xtools.app.sys.enums.SysRiskType; +import xtools.app.sys.model.dto.resp.SysRiskResp; +import xtools.app.sys.risk.utils.UriRiskUtils; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; + +import java.util.List; + +/** + *

Title : UriRisk

+ *

Description : UriRisk

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : Windows11

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/6 17:22 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class UriRisk implements BaseParams { + + private final SysRiskApi sysRiskApi; + + @Resource + private RedisService redisService; + + /** + * 初始化 + */ + public void init() { + List dataList = sysRiskApi.getByType(SysRiskType.URI).data(); + if (CollectionUtils.isEmpty(dataList)) { + log.info("无URI风控数据"); + return; + } + for (SysRiskResp item : dataList) { + UriRiskUtils.save(item.getSysType(), item.getData()); + log.info("初始化[{}]URI风控成功", item.getSysType()); + } + } + + /** + * 判断URI是否风控 + * + * @param sysType 系统类型 + * @param uri uri + * @return 是否风控 + * + */ + public boolean risk(String sysType, String uri) { + String cache = redisService.get(UriRiskUtils.getKey(sysType), String.class); + if (StringUtils.isBlank(cache)) { + return false; + } + String[] arr = cache.split(CP_COMMA); + // 匹配uri + for (String str : arr) { + if (uri.contains(str)) { + return true; + } + } + return false; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskBaseEnum.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskBaseEnum.java new file mode 100644 index 0000000..51bbedf --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskBaseEnum.java @@ -0,0 +1,32 @@ +package xtools.app.sys.risk.enums; + +import xtools.app.sys.enums.SysRiskType; +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysRiskBaseEnum

+ *

Description : SysRiskBaseEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/8 09:37 + */ +public interface SysRiskBaseEnum extends BaseEnum { + + /** + * 风控类型 + * + * @return 风控类型 + */ + SysRiskType type(); + + /** + * 系统类型 + * + * @return 系统类型 + */ + String sysType(); +} diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskEnum.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskEnum.java new file mode 100644 index 0000000..2af5511 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/enums/SysRiskEnum.java @@ -0,0 +1,106 @@ +package xtools.app.sys.risk.enums; + +import xtools.app.sys.enums.SysRiskType; +import xtools.boot.api.enums.BaseEnum; + +/** + *

Title : SysRiskEnum

+ *

Description : SysRiskEnum

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/4 16:27 + */ +public enum SysRiskEnum implements SysRiskBaseEnum { + + // 系统IP风控 + IP(1, "系统IP风控", SysRiskType.IP, "sys-ip"); + + /** + * 编码 + */ + private final int code; + + /** + * 说明 + */ + private final String desc; + + /** + * 风控类型 + */ + private final SysRiskType type; + + /** + * 系统类型 + */ + private final String sysType; + + /** + * 构造函数 + * + * @param code 编码 + * @param desc 说明 + * @param type 风控类型 + * @param sysType 系统类型 + */ + SysRiskEnum(int code, String desc, SysRiskType type, String sysType) { + this.code = code; + this.desc = desc; + this.type = type; + this.sysType = sysType; + } + + /** + * 获取所有枚举 + * + * @return 所有枚举 + */ + @Override + public BaseEnum[] all() { + return values(); + } + + /** + * 获取枚举编码 + * + * @return 枚举编码 + */ + @Override + public int code() { + return code; + } + + /** + * 获取枚举说明 + * + * @return 枚举说明 + */ + @Override + public String desc() { + return desc; + } + + /** + * 获取风控类型 + * + * @return 风控类型 + */ + @Override + public SysRiskType type() { + return type; + } + + /** + * 获取系统类型 + * + * @return 系统类型 + */ + @Override + public String sysType() { + return sysType; + } +} diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/IpRiskUtils.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/IpRiskUtils.java new file mode 100644 index 0000000..0c3a501 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/IpRiskUtils.java @@ -0,0 +1,61 @@ +package xtools.app.sys.risk.utils; + +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.core.ArrUtils; +import xtools.core.StringUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

Title : IpRiskUtils

+ *

Description : IpRiskUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/8 16:29 + */ +public class IpRiskUtils implements BaseParams { + + /** + * IP风控缓存 + */ + private final static AppCache IP_RISK = AppCache.RISK_IP; + + /** + * 获取缓存kEY + * + * @param sysType 系统类型 + * @return 缓存kEY + */ + public static String getKey(String sysType) { + return IP_RISK.key() + sysType; + } + + /** + * 添加IP风控 + * + * @param sysType 系统类型 + * @param data IP + */ + public static void addAll(String sysType, String data) { + RedisService redisService = RedisUtils.get(); + String key = getKey(sysType); + if (StringUtils.isBlank(data)) { + redisService.del(key); + } else { + List ipList = ArrUtils.toStringList(data); + Map map = ipList.stream().filter(StringUtils::isNotBlank).collect(Collectors.toMap(ip -> ip, ip -> String.valueOf(CP_NUM0))); + redisService.del(key); + redisService.hashPutAll(key, map); + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/UriRiskUtils.java b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/UriRiskUtils.java new file mode 100644 index 0000000..d577e5d --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-risk/src/main/java/xtools/app/sys/risk/utils/UriRiskUtils.java @@ -0,0 +1,53 @@ +package xtools.app.sys.risk.utils; + +import xtools.app.common.cache.enums.AppCache; +import xtools.base.config.BaseParams; +import xtools.boot.cache.redis.base.RedisService; +import xtools.boot.cache.redis.utils.RedisUtils; +import xtools.core.StringUtils; + +/** + *

Title : UriRiskUtils

+ *

Description : UriRiskUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/4/8 16:32 + */ +public class UriRiskUtils implements BaseParams { + + /** + * URI风控缓存 + */ + private final static AppCache URI_RISK = AppCache.RISK_URI; + + /** + * 获取缓存kEY + * + * @param sysType 系统类型 + * @return 缓存kEY + */ + public static String getKey(String sysType) { + return URI_RISK.key() + sysType; + } + + /** + * 保存Uri风控 + * + * @param sysType 系统类型 + * @param data 风控数据 + */ + public static void save(String sysType, String data) { + String key = getKey(sysType); + RedisService redisService = RedisUtils.get(); + if (StringUtils.isBlank(data)) { + redisService.del(key); + } else { + redisService.set(key, data); + } + } + +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/pom.xml b/xtools-app-sys/xtools-app-sys-scheduled/pom.xml new file mode 100644 index 0000000..6b11ab7 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + org.xujun + xtools-app-sys + 1.0.0 + + xtools-app-sys-scheduled + + + + + + org.xujun + xtools-web + + + + + org.apache.fesod + fesod-sheet + + + org.xujun + xtools-extend + + + + + org.xujun + xtools-boot-core + + + + org.xujun + xtools-boot-db-mybatis-plus + + + + + + org.xujun + xtools-app-common-log-bus + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-processor + + + + + + com.alibaba.fastjson2 + fastjson2 + + + + \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/controller/SysScheduledController.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/controller/SysScheduledController.java new file mode 100644 index 0000000..de91153 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/controller/SysScheduledController.java @@ -0,0 +1,171 @@ +package xtools.app.sys.scheduled.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import xtools.app.sys.scheduled.model.dto.excel.SysScheduledExcel; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledAddReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledPageReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledUpdateReq; +import xtools.app.sys.scheduled.model.dto.resp.SysScheduledResp; +import xtools.app.sys.scheduled.service.SysScheduledService; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.api.model.dto.req.IdListReq; +import xtools.core.CollectionUtils; +import xtools.extend.office.FesodUtils; +import xtools.web.HttpServletUtils; + +import java.io.IOException; +import java.util.List; + +/** + *

Title : SysScheduledController

+ *

Description : 定时任务 Controller

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:27:18 + */ +@Tag(name = "定时任务") +@RequiredArgsConstructor +@RestController +@RequestMapping("/sys/scheduled") +public class SysScheduledController { + + private final SysScheduledService sysScheduledService; + + @Operation(summary = "分页请求") + @PostMapping("page") + public Result> page(@RequestBody @Valid PageReq pageReq) { + return sysScheduledService.page(pageReq); + } + + @Operation(summary = "获取数据") + @GetMapping("base/{id}") + public Result getById( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + return sysScheduledService.getById(id); + } + + @Operation(summary = "添加数据") + @PostMapping("base") + public Result add(@RequestBody @Valid SysScheduledAddReq req) { + return sysScheduledService.add(req); + } + + @Operation(summary = "更新数据") + @PutMapping("base") + public Result update(@RequestBody @Valid SysScheduledUpdateReq req) { + return sysScheduledService.update(req); + } + + @Operation(summary = "删除数据") + @DeleteMapping("base") + public Result delById(@RequestBody @Valid IdListReq req) { + return sysScheduledService.delById(req.getIdList()); + } + + @Operation(summary = "导出Excel") + @PostMapping("export") + public void exportExcel(@RequestBody @Valid SysScheduledPageReq req, HttpServletResponse response) { + String sheetName = "定时任务"; + String filename = sheetName + ".xlsx"; + List dataList = sysScheduledService.exportExcel(req); + try { + FesodUtils.write(response.getOutputStream(), SysScheduledExcel.class, sheetName, dataList); + } catch (IOException e) { + throw new BizError("导出Excel失败"); + } + // 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改 + HttpServletUtils.addDownloadHeader(response, filename); + } + + @Operation(summary = "导入Excel") + @PostMapping("import") + public Result importExcel(@RequestParam("file") MultipartFile file) { + List dataList; + try { + dataList = FesodUtils.read(file.getInputStream(), SysScheduledExcel.class); + } catch (IOException e) { + throw new BizError("导入Excel失败"); + } + if (CollectionUtils.isEmpty(dataList)) { + throw new BizWarning("导入Excel没有包含有效数据"); + } + sysScheduledService.importExcel(dataList); + return Result.ok(true); + } + + @Operation(summary = "运行定时任务") + @PostMapping("run/{id}") + public Result run( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + sysScheduledService.run(id); + return Result.ok(true); + } + + @Operation(summary = "启动定时任务") + @PostMapping("start/{id}") + public Result start( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + sysScheduledService.start(id); + return Result.ok(true); + } + + @Operation(summary = "停止定时任务") + @PostMapping("stop/{id}") + public Result stop( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + sysScheduledService.stop(id); + return Result.ok(true); + } + + @Operation(summary = "重启定时任务") + @PostMapping("restart/{id}") + public Result restart( + @Schema(description = "ID", example = "1") + @Min(value = 1L, message = "不能小于1") + @NotNull(message = "不能为空") + @PathVariable Long id + ) { + sysScheduledService.restart(id); + return Result.ok(true); + } + +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/convert/SysScheduledConvert.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/convert/SysScheduledConvert.java new file mode 100644 index 0000000..accf391 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/convert/SysScheduledConvert.java @@ -0,0 +1,74 @@ +package xtools.app.sys.scheduled.convert; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import xtools.app.sys.scheduled.model.dto.excel.SysScheduledExcel; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledAddReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledUpdateReq; +import xtools.app.sys.scheduled.model.dto.resp.SysScheduledResp; +import xtools.app.sys.scheduled.model.entity.SysScheduled; + +import java.util.List; + +/** + *

Title : SysScheduledConvert

+ *

Description : 定时任务 Convert

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Mapper(componentModel = "spring") +public interface SysScheduledConvert { + + /** + * 添加请求转实体 + * + * @param req 添加请求 + * @return 实体 + */ + SysScheduled addReqToEntity(SysScheduledAddReq req); + + /** + * 修改请求转实体 + * + * @param req 修改请求 + * @return 实体 + */ + SysScheduled updateReqToEntity(SysScheduledUpdateReq req); + + /** + * 实体转响应 + * + * @param data 实体 + * @return 响应 + */ + SysScheduledResp entityToResp(SysScheduled data); + + /** + * 批量实体转响应 + * + * @param dataList 批量实体 + * @return 响应 + */ + List entityToRespList(List dataList); + + /** + * 实体转Excel + * + * @param data 实体 + * @return Excel + */ + SysScheduledExcel entityToExcel(SysScheduled data); + + /** + * Excel转实体 + * + * @param data Excel + * @return 实体 + */ + @Mapping(target = "status", ignore = true) + SysScheduled excelToEntity(SysScheduledExcel data); + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/init/InitSysScheduled.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/init/InitSysScheduled.java new file mode 100644 index 0000000..573cbe8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/init/InitSysScheduled.java @@ -0,0 +1,53 @@ +package xtools.app.sys.scheduled.init; + +import lombok.RequiredArgsConstructor; +import org.jspecify.annotations.NonNull; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import xtools.app.sys.scheduled.service.SysScheduledService; +import xtools.base.config.BaseParams; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.boot.log.holder.LogTrackHolder; +import xtools.core.enums.LogLevel; + + +/** + *

Title : InitSysScheduled

+ *

Description : InitSysScheduled

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/2 14:13 + */ +@Component +@Order(BaseParams.CP_NUM200) +@RequiredArgsConstructor +public class InitSysScheduled implements ApplicationRunner { + + private final SysScheduledService sysScheduledService; + + @Override + public void run(@NonNull ApplicationArguments args) { + ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newMain()).run(() -> { + try { + init(); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.OTHER).title("初始化异常").error(e).save(); + } + }); + + } + + /** + * 初始化 + */ + private void init() { + sysScheduledService.init(); + } +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/mapper/SysScheduledMapper.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/mapper/SysScheduledMapper.java new file mode 100644 index 0000000..77c9925 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/mapper/SysScheduledMapper.java @@ -0,0 +1,19 @@ +package xtools.app.sys.scheduled.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xtools.app.sys.scheduled.model.entity.SysScheduled; + +/** + *

Title : SysScheduledMapper

+ *

Description : 定时任务 Mapper 接口

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Mapper +public interface SysScheduledMapper extends BaseMapper { + +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/excel/SysScheduledExcel.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/excel/SysScheduledExcel.java new file mode 100644 index 0000000..d12a74b --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/excel/SysScheduledExcel.java @@ -0,0 +1,54 @@ +package xtools.app.sys.scheduled.model.dto.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.fesod.sheet.annotation.ExcelProperty; + +import java.io.Serializable; + +/** + *

Title : SysScheduledExcel

+ *

Description : 定时任务Excel对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysScheduledExcel implements Serializable { + + /** + * 描述 + */ + @ExcelProperty("任务描述") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @ExcelProperty("Bean名称") + private String beanName; + + /** + * 执行参数 + */ + @ExcelProperty("执行参数") + private String params; + + /** + * 表达式 + */ + @ExcelProperty("表达式") + private String cron; + + /** + * 状态(默认1) + */ + @ExcelProperty("任务状态") + private String status; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledAddReq.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledAddReq.java new file mode 100644 index 0000000..14cf5d4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledAddReq.java @@ -0,0 +1,53 @@ +package xtools.app.sys.scheduled.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysScheduledAddReq

+ *

Description : 定时任务添加请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysScheduledAddReq implements Serializable { + + /** + * 描述 + */ + @Schema(description = "描述") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @Schema(description = "需要执行的SpringBean的名称") + private String beanName; + + /** + * 执行参数 + */ + @Schema(description = "执行参数") + private String params; + + /** + * 表达式 + */ + @Schema(description = "表达式") + private String cron; + + /** + * 状态(默认1) + */ + @Schema(description = "状态(默认1)") + private Integer status; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledPageReq.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledPageReq.java new file mode 100644 index 0000000..45a8db4 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledPageReq.java @@ -0,0 +1,72 @@ +package xtools.app.sys.scheduled.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; + +/** + *

Title : SysScheduledPageReq

+ *

Description : 定时任务分页请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysScheduledPageReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 描述 + */ + @Schema(description = "描述") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @Schema(description = "需要执行的SpringBean的名称") + private String beanName; + + /** + * 执行参数 + */ + @Schema(description = "执行参数") + private String params; + + /** + * 表达式 + */ + @Schema(description = "表达式") + private String cron; + + /** + * 状态(默认1) + */ + @Schema(description = "状态(默认1)") + private Integer status; + + /** + * 创建时间(范围) + */ + @Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtCreateRange; + + /** + * 更新时间(范围) + */ + @Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']") + private Instant[] gmtModifiedRange; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledUpdateReq.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledUpdateReq.java new file mode 100644 index 0000000..8e0a083 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/req/SysScheduledUpdateReq.java @@ -0,0 +1,60 @@ +package xtools.app.sys.scheduled.model.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *

Title : SysScheduledUpdateReq

+ *

Description : 定时任务更新请求对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysScheduledUpdateReq implements Serializable { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 描述 + */ + @Schema(description = "描述") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @Schema(description = "需要执行的SpringBean的名称") + private String beanName; + + /** + * 执行参数 + */ + @Schema(description = "执行参数") + private String params; + + /** + * 表达式 + */ + @Schema(description = "表达式") + private String cron; + + /** + * 状态(默认1) + */ + @Schema(description = "状态(默认1)") + private Integer status; + +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/resp/SysScheduledResp.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/resp/SysScheduledResp.java new file mode 100644 index 0000000..0f6d3ab --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/dto/resp/SysScheduledResp.java @@ -0,0 +1,66 @@ +package xtools.app.sys.scheduled.model.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysScheduledResp

+ *

Description : 定时任务响应对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class SysScheduledResp extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + private Long id; + + /** + * 描述 + */ + @Schema(description = "描述") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @Schema(description = "需要执行的SpringBean的名称") + private String beanName; + + /** + * 执行参数 + */ + @Schema(description = "执行参数") + private String params; + + /** + * 表达式 + */ + @Schema(description = "表达式") + private String cron; + + /** + * 状态(默认1) + */ + @Schema(description = "状态") + private Integer status; + + /** + * 运行状态 + */ + @Schema(description = "运行状态") + private Integer run; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/entity/SysScheduled.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/entity/SysScheduled.java new file mode 100644 index 0000000..3d858ab --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/model/entity/SysScheduled.java @@ -0,0 +1,71 @@ +package xtools.app.sys.scheduled.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import xtools.boot.api.model.entity.BaseEntity; + +/** + *

Title : SysScheduled

+ *

Description : 定时任务实体对象

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName("sys_scheduled") +public class SysScheduled extends BaseEntity { + + /** + * 主键 ID + */ + @Schema(description = "主键 ID") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 描述 + */ + @Schema(description = "描述") + @TableField(value = "title") + private String title; + + /** + * 需要执行的SpringBean的名称 + */ + @Schema(description = "需要执行的SpringBean的名称") + @TableField(value = "bean_name") + private String beanName; + + /** + * 执行参数 + */ + @Schema(description = "执行参数") + @TableField(value = "params") + private String params; + + /** + * 表达式 + */ + @Schema(description = "表达式") + @TableField(value = "cron") + private String cron; + + /** + * 状态(默认1) + */ + @Schema(description = "状态(默认1)") + @TableField(value = "status") + private Integer status; +} \ No newline at end of file diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/SysScheduledService.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/SysScheduledService.java new file mode 100644 index 0000000..a4eced8 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/SysScheduledService.java @@ -0,0 +1,113 @@ +package xtools.app.sys.scheduled.service; + +import xtools.app.sys.scheduled.model.dto.excel.SysScheduledExcel; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledAddReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledPageReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledUpdateReq; +import xtools.app.sys.scheduled.model.dto.resp.SysScheduledResp; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; + +import java.util.List; + +/** + *

Title : SysScheduledService

+ *

Description : 定时任务 Service

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +public interface SysScheduledService { + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + Result> page(PageReq pageReq); + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + Result getById(Long id); + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + Result add(SysScheduledAddReq req); + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + Result update(SysScheduledUpdateReq req); + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + Result delById(List idList); + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + List exportExcel(SysScheduledPageReq req); + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + void importExcel(List dataList); + + /** + * 初始化定时任务 + */ + void init(); + + /** + * 运行定时任务 + * + * @param id 定时任务ID + */ + void run(Long id); + + /** + * 启动定时任务 + * + * @param id 定时任务ID + */ + void start(Long id); + + /** + * 停止定时任务 + * + * @param id 定时任务ID + */ + void stop(Long id); + + /** + * 重启定时任务 + * + * @param id 定时任务ID + */ + void restart(Long id); + +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/base/SysScheduledBaseService.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/base/SysScheduledBaseService.java new file mode 100644 index 0000000..bc9ad7a --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/base/SysScheduledBaseService.java @@ -0,0 +1,19 @@ +package xtools.app.sys.scheduled.service.base; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Component; +import xtools.app.sys.scheduled.mapper.SysScheduledMapper; +import xtools.app.sys.scheduled.model.entity.SysScheduled; + +/** + *

Title : SysScheduledBaseService

+ *

Description : 定时任务 BaseService

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Component +public class SysScheduledBaseService extends ServiceImpl { +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/impl/SysScheduledServiceImpl.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/impl/SysScheduledServiceImpl.java new file mode 100644 index 0000000..d9e8f48 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/service/impl/SysScheduledServiceImpl.java @@ -0,0 +1,389 @@ +package xtools.app.sys.scheduled.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xtools.app.sys.scheduled.convert.SysScheduledConvert; +import xtools.app.sys.scheduled.model.dto.excel.SysScheduledExcel; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledAddReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledPageReq; +import xtools.app.sys.scheduled.model.dto.req.SysScheduledUpdateReq; +import xtools.app.sys.scheduled.model.dto.resp.SysScheduledResp; +import xtools.app.sys.scheduled.model.entity.SysScheduled; +import xtools.app.sys.scheduled.service.SysScheduledService; +import xtools.app.sys.scheduled.service.base.SysScheduledBaseService; +import xtools.app.sys.scheduled.utils.ScheduledUtils; +import xtools.base.config.BaseParams; +import xtools.boot.api.enums.StatusEnum; +import xtools.boot.api.exection.BizError; +import xtools.boot.api.exection.BizWarning; +import xtools.boot.api.model.dto.Result; +import xtools.boot.api.model.dto.page.PageReq; +import xtools.boot.api.model.dto.page.PageResp; +import xtools.boot.core.utils.SpringContextUtils; +import xtools.boot.db.mybatisplus.utils.QueryUtils; +import xtools.boot.log.LogBus; +import xtools.boot.log.enums.LogBusBaseType; +import xtools.core.CollectionUtils; +import xtools.core.StringUtils; +import xtools.core.enums.LogLevel; + +import java.util.List; +import java.util.Objects; + +/** + *

Title : SysScheduledServiceImpl

+ *

Description : 定时任务 ServiceImpl

+ *

Company : org.xujun

+ * + * @author : xujun + * @version : 1.0.0 + * @date : 2026-02-23 10:15:23 + */ +@Slf4j +@Primary +@Service +@RequiredArgsConstructor +public class SysScheduledServiceImpl implements SysScheduledService, BaseParams { + + private final SysScheduledBaseService sysScheduledBaseService; + + private final SysScheduledConvert sysScheduledConvert; + + /** + * 分页查询 + * + * @param pageReq 分页请求 + * @return 分页结果 + */ + @Override + public Result> page(PageReq pageReq) { + // 分页查询 + Page page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery()); + List dataList = sysScheduledConvert.entityToRespList(page.getRecords()); + if (CollectionUtils.isNotEmpty(dataList)) { + dataList.forEach(item -> item.setRun(ScheduledUtils.isRun(item.getId()) ? CP_NUM1 : CP_NUM0)); + } + // 分装结果 + PageResp pageResp = new PageResp<>(pageReq, page.getTotal(), dataList); + return Result.ok(pageResp); + } + + /** + * 根据 ID 查询 + * + * @param id ID + * @return 结果 + */ + @Override + public Result getById(Long id) { + SysScheduled data = sysScheduledBaseService.getById(id); + return Result.ok(sysScheduledConvert.entityToResp(data)); + } + + /** + * 添加 + * + * @param req 添加请求 + * @return 添加结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result add(SysScheduledAddReq req) { + SysScheduled entity = sysScheduledConvert.addReqToEntity(req); + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysScheduledBaseService.save(entity)); + } + + /** + * 修改 + * + * @param req 修改请求 + * @return 修改结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result update(SysScheduledUpdateReq req) { + SysScheduled entity = sysScheduledConvert.updateReqToEntity(req); + if (ScheduledUtils.isRun(entity.getId())) { + throw new BizWarning("任务正在运行中,请先停止任务"); + } + if (Objects.nonNull(existsEntity(entity))) { + throw new BizWarning("数据已存在"); + } + return Result.ok(sysScheduledBaseService.updateById(entity)); + } + + /** + * 根据 ID 删除 + * + * @param idList ID 集合 + * @return 删除结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Result delById(List idList) { + idList.forEach(id -> { + if (ScheduledUtils.isRun(id)) { + throw new BizWarning("有任务正在运行中,请先停止任务"); + } + }); + boolean removed = sysScheduledBaseService.removeByIds(idList); + if (!removed) { + throw new BizError("删除失败"); + } + return Result.ok(true); + } + + /** + * 导出 Excel + * + * @param req 请求参数 + * @return Excel 数据 + */ + @Override + public List exportExcel(SysScheduledPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysScheduled::getTitle + , SysScheduled::getBeanName + , SysScheduled::getParams + , SysScheduled::getCron + , SysScheduled::getStatus + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysScheduled::getGmtCreate); + List dataList = sysScheduledBaseService.list(query); + return dataList.stream().map(item -> { + StatusEnum status = StatusEnum.valueOf(item.getStatus()); + SysScheduledExcel excel = sysScheduledConvert.entityToExcel(item); + excel.setStatus(status.desc()); + return excel; + }).toList(); + } + + /** + * 导入 Excel + * + * @param dataList Excel 数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importExcel(List dataList) { + for (SysScheduledExcel excel : dataList) { + StatusEnum status = StatusEnum.valueOfDesc(excel.getStatus()); + + SysScheduled item = sysScheduledConvert.excelToEntity(excel); + item.setStatus(status.code()); + + SysScheduled dbItem = existsEntity(item); + if (Objects.isNull(dbItem)) { + // 新增 + sysScheduledBaseService.save(item); + } else { + // 修改 + item.setId(dbItem.getId()); + sysScheduledBaseService.updateById(item); + } + } + } + + /** + * 获取分页数据 + * + * @param currentPage 当前页 + * @param pageSize 每页数量 + * @param req 请求参数 + * @return 分页数据 + */ + private Page getPageData(Integer currentPage, Integer pageSize, SysScheduledPageReq req) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysScheduled::getId + , SysScheduled::getTitle + , SysScheduled::getBeanName + , SysScheduled::getParams + , SysScheduled::getCron + , SysScheduled::getStatus + , SysScheduled::getGmtCreate + , SysScheduled::getGmtModified + ); + // 设置查询条件 + setQueryWrapper(query, req); + // 排序 + query.orderByDesc(SysScheduled::getGmtCreate); + return sysScheduledBaseService.page(QueryUtils.getPage(currentPage, pageSize), query); + } + + /** + * 设置查询条件 + * + * @param query 查询条件 + * @param req 请求参数 + */ + private void setQueryWrapper(LambdaQueryWrapper query, SysScheduledPageReq req) { + if (Objects.isNull(req)) { + return; + } + // 查询条件 + query.eq(Objects.nonNull(req.getId()), SysScheduled::getId, req.getId()); + query.like(StringUtils.isNotBlank(req.getTitle()), SysScheduled::getTitle, req.getTitle()); + query.like(StringUtils.isNotBlank(req.getBeanName()), SysScheduled::getBeanName, req.getBeanName()); + query.like(StringUtils.isNotBlank(req.getParams()), SysScheduled::getParams, req.getParams()); + query.like(StringUtils.isNotBlank(req.getCron()), SysScheduled::getCron, req.getCron()); + query.eq(Objects.nonNull(req.getStatus()), SysScheduled::getStatus, req.getStatus()); + QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysScheduled::getGmtCreate); + QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysScheduled::getGmtModified); + } + + /** + * 判断实体是否存在 + * + * @param entity 实体 + * @return 是否存在 + */ + private SysScheduled existsEntity(SysScheduled entity) { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select(SysScheduled::getId); + // 排除当前数据 + query.ne(Objects.nonNull(entity.getId()), SysScheduled::getId, entity.getId()); + // 校验数据时候存在的条件 + query.eq(StringUtils.isNotBlank(entity.getBeanName()), SysScheduled::getBeanName, entity.getBeanName()); + return sysScheduledBaseService.getOne(query); + } + + /** + * 初始化定时任务 + */ + @Override + public void init() { + // 创建查询条件 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 查询字段 + query.select( + SysScheduled::getId + , SysScheduled::getTitle + , SysScheduled::getBeanName + , SysScheduled::getParams + , SysScheduled::getCron + ); + query.eq(SysScheduled::getStatus, StatusEnum.NORMAL.code()); + List dataList = sysScheduledBaseService.list(query); + if (CollectionUtils.isEmpty(dataList)) { + log.info("初始化定时任务成功,无定时任务"); + return; + } + for (SysScheduled item : dataList) { + String beanName = item.getBeanName(); + Runnable task = getTask(beanName); + if (Objects.isNull(task)) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.JOB).title("定时任务不存在").data(item).save(); + continue; + } + try { + ScheduledUtils.add(item.getId(), task, item.getCron()); + log.info("定时任务添加成功,任务名称:{}", item.getTitle()); + } catch (Exception e) { + LogBus.init(LogLevel.ERROR, LogBusBaseType.JOB).title("定时任务添加异常").error(e).data(item).save(); + } + } + } + + /** + * 运行定时任务 + * + * @param id 定时任务ID + */ + @Override + public void run(Long id) { + SysScheduled item = sysScheduledBaseService.getById(id); + if (Objects.isNull(item)) { + throw new BizError("定时任务不存在"); + } + boolean run = ScheduledUtils.isRun(id); + if (run) { + throw new BizError("定时任务已启动"); + } + Runnable task = getTask(item.getBeanName()); + if (Objects.isNull(task)) { + throw new BizError("定时任务bean不存在"); + } + task.run(); + } + + /** + * 启动定时任务 + * + * @param id 定时任务ID + */ + @Override + public void start(Long id) { + SysScheduled item = sysScheduledBaseService.getById(id); + if (Objects.isNull(item)) { + throw new BizError("定时任务不存在"); + } + boolean run = ScheduledUtils.isRun(id); + if (run) { + throw new BizError("定时任务已启动"); + } + ScheduledUtils.add(id, getTask(item.getBeanName()), item.getCron()); + } + + /** + * 停止定时任务 + * + * @param id 定时任务ID + */ + @Override + public void stop(Long id) { + SysScheduled item = sysScheduledBaseService.getById(id); + if (Objects.isNull(item)) { + throw new BizError("定时任务不存在"); + } + boolean run = ScheduledUtils.isRun(id); + if (!run) { + throw new BizError("定时任务未启动"); + } + ScheduledUtils.remove(id); + } + + /** + * 重启定时任务 + * + * @param id 定时任务ID + */ + @Override + public void restart(Long id) { + stop(id); + start(id); + } + + /** + * 获取任务 + * + * @param beanName 任务bean名称 + * @return 任务 + */ + private Runnable getTask(String beanName) { + Object obj = SpringContextUtils.getBeanDefNull(beanName); + if (obj instanceof Runnable task) { + return task; + } + return null; + } + +} diff --git a/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/utils/ScheduledUtils.java b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/utils/ScheduledUtils.java new file mode 100644 index 0000000..f078d22 --- /dev/null +++ b/xtools-app-sys/xtools-app-sys-scheduled/src/main/java/xtools/app/sys/scheduled/utils/ScheduledUtils.java @@ -0,0 +1,112 @@ +package xtools.app.sys.scheduled.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import xtools.base.config.BaseParams; +import xtools.boot.api.exection.BizError; +import xtools.core.StringUtils; +import xtools.core.extend.CheckUtils; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; + +/** + *

Title : ScheduledUtils

+ *

Description : ScheduledUtils

+ *

DevelopTools : Idea_x64_v2026.1

+ *

DevelopSystem : macOS Sequoia 15.7.5

+ *

Company : org.xujun

+ * + * @author : XuJun + * @version : 1.0.0 + * @date : 2026/2/23 09:46 + */ +@Slf4j +public class ScheduledUtils implements BaseParams { + + /** + * 任务线程池 + */ + private final static TaskScheduler TASK_SCHEDULER; + + /** + * 任务列表 + */ + private static final ConcurrentHashMap> TASKS = new ConcurrentHashMap<>(); + + // 初始化 + static { + // 创建任务虚拟线程池 + ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + scheduler.setVirtualThreads(true); + scheduler.initialize(); + TASK_SCHEDULER = scheduler; + } + + /** + * 添加任务 + * + * @param id 任务ID + * @param task 任务执行线程 + * @param cron 执行时间表达式 + */ + public static void add(Long id, Runnable task, String cron) { + // 参数校验 + if (!CheckUtils.id(id) || Objects.isNull(task) || StringUtils.isBlank(cron)) { + throw new BizError("参数错误"); + } + // 如果任务已存在,先取消 + if (TASKS.containsKey(id)) { + remove(id); + } + CronTrigger trigger; + try { + trigger = new CronTrigger(cron); + } catch (Exception e) { + throw new BizError("时间表达式错误"); + } + + // 用虚拟线程包装任务 + Runnable virtualTask = () -> Thread.startVirtualThread(task); + ScheduledFuture future = TASK_SCHEDULER.schedule(virtualTask, trigger); + if (Objects.isNull(future)) { + throw new BizError("定时任务添加失败"); + } + TASKS.put(id, future); + } + + /** + * 删除任务 + * + * @param id 任务ID + */ + public static void remove(Long id) { + ScheduledFuture future = TASKS.remove(id); + if (Objects.isNull(future)) { + return; + } + future.cancel(true); + } + + /** + * 是否在运行 + * + * @param id 任务ID + * @return true or false + */ + public static boolean isRun(Long id) { + if (!CheckUtils.id(id)) { + return false; + } + // 获取任务实例 + ScheduledFuture task = TASKS.get(id); + if (Objects.isNull(task)) { + return false; + } + return !task.isCancelled(); + } + +}