From ca6ad5acfb389b852211355c4a56c71769a018c9 Mon Sep 17 00:00:00 2001 From: houzhongjian <houzhongyi@126.com> Date: 星期四, 05 六月 2025 17:55:36 +0800 Subject: [PATCH] v2.0版本初始化 --- iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiModelDO.java | 79 + iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumValidator.java | 15 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitordisk/MonitorDiskMapper.java | 46 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/IailabMybatisAutoConfiguration.java | 1 iailab-system/log/system-server.log | 188 ++ iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskSaveReqVO.java | 41 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/MonitorMemController.java | 126 + iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-dev.yaml | 4 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendRespDTO.java | 34 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitordisk/MonitorDiskDO.java | 72 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemRespVO.java | 81 + iailab-module-ai/pom.xml | 4 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskPageReqVO.java | 47 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendReqDTO.java | 23 工业互联网平台鉴权功能.md | 269 +++ iailab-module-ai/.idea/misc.xml | 14 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskRespVO.java | 57 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitormem/MonitorMemDO.java | 103 + iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatConversationRespDTO.java | 58 iailab-module-data/iailab-module-data-biz/src/main/resources/application-prod.yaml | 127 + .xcodemap/config/xcodemap-class-filter.yaml | 26 iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiAccessLogApi.java | 10 iailab-module-ai/.idea/.gitignore | 8 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorMemJob.java | 48 iailab-module-ai/.idea/jarRepositories.xml | 30 iailab-module-ai/iailab-module-ai-biz/pom.xml | 8 iailab-module-model/iailab-module-model-biz/src/main/resources/application-prod.yaml | 106 + iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/template/XMLParserUtils.java | 296 +++ iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/core/ArrayValuable.java | 15 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemService.java | 83 + iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorDiskDTO.java | 55 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApi.java | 22 iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatConversionApiImpl.java | 34 iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml | 5 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemServiceImpl.java | 108 + iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemPageReqVO.java | 59 iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorMemDTO.java | 79 + iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml | 4 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatConversationApi.java | 20 iailab-module-ai/.idea/sonarlint.xml | 11 iailab-module-ai/.idea/vcs.xml | 6 iailab-framework/iailab-common-excel/src/main/java/com/iailab/framework/excel/core/convert/AreaConvert.java | 92 iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnum.java | 4 iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/enums/ApiConstants.java | 23 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java | 1 .gitignore | 3 iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/web/core/handler/GlobalExceptionHandler.java | 32 iailab-module-infra/iailab-module-infra-biz/src/main/resources/mapper/monitordisk/MonitorDiskMapper.xml | 42 iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/chat/AiChatConversationServiceImpl.java | 2 iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiErrorLogApi.java | 11 iailab-module-ai/.idea/compiler.xml | 35 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/api/monitor/MonitorApiImpl.java | 40 iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApiImpl.java | 27 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorDiskJob.java | 47 pom.xml | 2 iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/MonitorApi.java | 42 iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/util/ServerInfoCollector.java | 198 ++ iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/package-info.java | 1 iailab-module-ai/iailab-spring-boot-starter-ai/pom.xml | 2 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemSaveReqVO.java | 60 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskServiceImpl.java | 180 ++ iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/UserTypeEnum.java | 9 iailab-framework/iailab-common-biz-ip/src/main/java/com/iailab/framework/ip/core/enums/AreaTypeEnum.java | 8 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/social/SocialTypeEnum.java | 8 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskReqVO.java | 49 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/MonitorDiskController.java | 126 + iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/permission/DataScopeEnum.java | 8 iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumCollectionValidator.java | 13 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorDiskJob.java | 49 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitormem/MonitorMemMapper.java | 47 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/sms/SmsSceneEnum.java | 8 iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/TerminalEnum.java | 8 iailab-module-data/iailab-module-data-biz/logs/log-debug.2024-11-06.log | 262 +++ iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemReqVO.java | 58 iailab-module-ai/iailab-module-ai-api/pom.xml | 17 iailab-module-system/iailab-module-system-biz/src/main/resources/application-prod.yaml | 116 + iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/DateIntervalEnum.java | 8 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorMemJob.java | 50 iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-prod.yaml | 150 ++ iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/CommonStatusEnum.java | 8 iailab-module-system/iailab-module-system-biz/proguard.cfg | 132 + iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskService.java | 94 + 82 files changed, 4,363 insertions(+), 131 deletions(-) diff --git a/.gitignore b/.gitignore index 3f7ae50..e310db0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/iailab-module-ai/ /*/*/target/ /.idea/ /derby.log @@ -8,4 +7,4 @@ /*/*/.flattened-pom.xml /*/replay_pid15548.log /logs/ -/*/*/*.iml +/*/*/*.iml \ No newline at end of file diff --git a/.xcodemap/config/xcodemap-class-filter.yaml b/.xcodemap/config/xcodemap-class-filter.yaml new file mode 100644 index 0000000..ab90a7c --- /dev/null +++ b/.xcodemap/config/xcodemap-class-filter.yaml @@ -0,0 +1,26 @@ +autoDetectedPackages: +- com.alibaba.nacos +- com.fhs.trans.service +- com.iailab +- com.xxl.job.admin +- com.xxl.job.executorbiz +- iail.mdk.model.common +- org.springframework.messaging.handler.invocation +enableAutoDetect: true +funcDisplayConfig: + skipConstructors: false + skipFieldAccess: true + skipFieldChange: true + skipGetters: true + skipNonProjectPackages: true + skipPrivateMethods: false + skipSetters: true +ignoreSameClassCall: null +ignoreSamePackageCall: null +includedPackagePrefixes: null +includedParentClasses: null +name: xcodemap-filter +recordMode: smart +sourceDisplayConfig: + color: blue +startOnDebug: false diff --git a/iailab-framework/iailab-common-biz-ip/src/main/java/com/iailab/framework/ip/core/enums/AreaTypeEnum.java b/iailab-framework/iailab-common-biz-ip/src/main/java/com/iailab/framework/ip/core/enums/AreaTypeEnum.java index ceed9b9..416d1cc 100644 --- a/iailab-framework/iailab-common-biz-ip/src/main/java/com/iailab/framework/ip/core/enums/AreaTypeEnum.java +++ b/iailab-framework/iailab-common-biz-ip/src/main/java/com/iailab/framework/ip/core/enums/AreaTypeEnum.java @@ -1,6 +1,6 @@ package com.iailab.framework.ip.core.enums; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -13,7 +13,7 @@ */ @AllArgsConstructor @Getter -public enum AreaTypeEnum implements IntArrayValuable { +public enum AreaTypeEnum implements ArrayValuable { COUNTRY(1, "国家"), PROVINCE(2, "省份"), @@ -21,7 +21,7 @@ DISTRICT(4, "地区"), // 县、镇、区等 ; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AreaTypeEnum::getType).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(AreaTypeEnum::getType).toArray(Integer[]::new); /** * 类型 @@ -33,7 +33,7 @@ private final String name; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } } diff --git a/iailab-framework/iailab-common-excel/src/main/java/com/iailab/framework/excel/core/convert/AreaConvert.java b/iailab-framework/iailab-common-excel/src/main/java/com/iailab/framework/excel/core/convert/AreaConvert.java index 558c5f7..3be47dd 100644 --- a/iailab-framework/iailab-common-excel/src/main/java/com/iailab/framework/excel/core/convert/AreaConvert.java +++ b/iailab-framework/iailab-common-excel/src/main/java/com/iailab/framework/excel/core/convert/AreaConvert.java @@ -1,46 +1,46 @@ -package com.iailab.framework.excel.core.convert; - -import cn.hutool.core.convert.Convert; -import com.iailab.framework.ip.core.Area; -import com.iailab.framework.ip.core.utils.AreaUtils; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.metadata.GlobalConfiguration; -import com.alibaba.excel.metadata.data.ReadCellData; -import com.alibaba.excel.metadata.property.ExcelContentProperty; -import lombok.extern.slf4j.Slf4j; - -/** - * Excel 数据地区转换器 - * - * @author HUIHUI - */ -@Slf4j -public class AreaConvert implements Converter<Object> { - - @Override - public Class<?> supportJavaTypeKey() { - throw new UnsupportedOperationException("暂不支持,也不需要"); - } - - @Override - public CellDataTypeEnum supportExcelTypeKey() { - throw new UnsupportedOperationException("暂不支持,也不需要"); - } - - @Override - public Object convertToJavaData(ReadCellData readCellData, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - // 解析地区编号 - String label = readCellData.getStringValue(); - Area area = AreaUtils.parseArea(label); - if (area == null) { - log.error("[convertToJavaData][label({}) 解析不掉]", label); - return null; - } - // 将 value 转换成对应的属性 - Class<?> fieldClazz = contentProperty.getField().getType(); - return Convert.convert(fieldClazz, area.getId()); - } - -} +//package com.iailab.framework.excel.core.convert; +// +//import cn.hutool.core.convert.Convert; +//import com.iailab.framework.ip.core.Area; +//import com.iailab.framework.ip.core.utils.AreaUtils; +//import com.alibaba.excel.converters.Converter; +//import com.alibaba.excel.enums.CellDataTypeEnum; +//import com.alibaba.excel.metadata.GlobalConfiguration; +//import com.alibaba.excel.metadata.data.ReadCellData; +//import com.alibaba.excel.metadata.property.ExcelContentProperty; +//import lombok.extern.slf4j.Slf4j; +// +///** +// * Excel 数据地区转换器 +// * +// * @author HUIHUI +// */ +//@Slf4j +//public class AreaConvert implements Converter<Object> { +// +// @Override +// public Class<?> supportJavaTypeKey() { +// throw new UnsupportedOperationException("暂不支持,也不需要"); +// } +// +// @Override +// public CellDataTypeEnum supportExcelTypeKey() { +// throw new UnsupportedOperationException("暂不支持,也不需要"); +// } +// +// @Override +// public Object convertToJavaData(ReadCellData readCellData, ExcelContentProperty contentProperty, +// GlobalConfiguration globalConfiguration) { +// // 解析地区编号 +// String label = readCellData.getStringValue(); +// Area area = AreaUtils.parseArea(label); +// if (area == null) { +// log.error("[convertToJavaData][label({}) 解析不掉]", label); +// return null; +// } +// // 将 value 转换成对应的属性 +// Class<?> fieldClazz = contentProperty.getField().getType(); +// return Convert.convert(fieldClazz, area.getId()); +// } +// +//} diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/IailabMybatisAutoConfiguration.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/IailabMybatisAutoConfiguration.java index 5ee2990..74269b6 100644 --- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/IailabMybatisAutoConfiguration.java +++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/IailabMybatisAutoConfiguration.java @@ -1,7 +1,6 @@ package com.iailab.framework.mybatis.config; import cn.hutool.core.util.StrUtil; -import com.iailab.framework.mybatis.core.enums.SqlConstants; import com.iailab.framework.mybatis.core.handler.DefaultDBFieldHandler; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; diff --git a/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/web/core/handler/GlobalExceptionHandler.java b/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/web/core/handler/GlobalExceptionHandler.java index 79930b8..ce679c1 100644 --- a/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/web/core/handler/GlobalExceptionHandler.java +++ b/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/web/core/handler/GlobalExceptionHandler.java @@ -304,51 +304,51 @@ } // 1. 数据报表 if (message.contains("report_")) { - log.error("[报表模块 yudao-module-report - 表结构未导入][参考 https://cloud.iocoder.cn/report/ 开启]"); + log.error("[报表模块 iailab-module-report - 表结构未导入][参考 https://cloud.iocoder.cn/report/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[报表模块 yudao-module-report - 表结构未导入][参考 https://cloud.iocoder.cn/report/ 开启]"); + "[报表模块 iailab-module-report - 表结构未导入][参考 https://cloud.iocoder.cn/report/ 开启]"); } // 2. 工作流 if (message.contains("bpm_")) { - log.error("[工作流模块 yudao-module-bpm - 表结构未导入][参考 https://cloud.iocoder.cn/bpm/ 开启]"); + log.error("[工作流模块 iailab-module-bpm - 表结构未导入][参考 https://cloud.iocoder.cn/bpm/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[工作流模块 yudao-module-bpm - 表结构未导入][参考 https://cloud.iocoder.cn/bpm/ 开启]"); + "[工作流模块 iailab-module-bpm - 表结构未导入][参考 https://cloud.iocoder.cn/bpm/ 开启]"); } // 3. 微信公众号 if (message.contains("mp_")) { - log.error("[微信公众号 yudao-module-mp - 表结构未导入][参考 https://cloud.iocoder.cn/mp/build/ 开启]"); + log.error("[微信公众号 iailab-module-mp - 表结构未导入][参考 https://cloud.iocoder.cn/mp/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[微信公众号 yudao-module-mp - 表结构未导入][参考 https://cloud.iocoder.cn/mp/build/ 开启]"); + "[微信公众号 iailab-module-mp - 表结构未导入][参考 https://cloud.iocoder.cn/mp/build/ 开启]"); } // 4. 商城系统 if (StrUtil.containsAny(message, "product_", "promotion_", "trade_")) { - log.error("[商城系统 yudao-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]"); + log.error("[商城系统 iailab-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[商城系统 yudao-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]"); + "[商城系统 iailab-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]"); } // 5. ERP 系统 if (message.contains("erp_")) { - log.error("[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]"); + log.error("[ERP 系统 iailab-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]"); + "[ERP 系统 iailab-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]"); } // 6. CRM 系统 if (message.contains("crm_")) { - log.error("[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]"); + log.error("[CRM 系统 iailab-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]"); + "[CRM 系统 iailab-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]"); } // 7. 支付平台 if (message.contains("pay_")) { - log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]"); + log.error("[支付模块 iailab-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]"); + "[支付模块 iailab-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]"); } // 8. AI 大模型 if (message.contains("ai_")) { - log.error("[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]"); + log.error("[AI 大模型 iailab-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]"); return CommonResult.error(NOT_IMPLEMENTED.getCode(), - "[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]"); + "[AI 大模型 iailab-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]"); } return null; } diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/core/ArrayValuable.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/core/ArrayValuable.java new file mode 100644 index 0000000..ab2b3c3 --- /dev/null +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/core/ArrayValuable.java @@ -0,0 +1,15 @@ +package com.iailab.framework.common.core; + +/** + * 可生成 T 数组的接口 + * + * @author HUIHUI + */ +public interface ArrayValuable<T> { + + /** + * @return 数组 + */ + T[] array(); + +} \ No newline at end of file diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/CommonStatusEnum.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/CommonStatusEnum.java index a611b8b..b43e211 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/CommonStatusEnum.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/CommonStatusEnum.java @@ -1,7 +1,7 @@ package com.iailab.framework.common.enums; import cn.hutool.core.util.ObjUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,12 +14,12 @@ */ @Getter @AllArgsConstructor -public enum CommonStatusEnum implements IntArrayValuable { +public enum CommonStatusEnum implements ArrayValuable { ENABLE(0, "开启"), DISABLE(1, "关闭"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(CommonStatusEnum::getStatus).toArray(Integer[]::new); /** * 状态值 @@ -31,7 +31,7 @@ private final String name; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/DateIntervalEnum.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/DateIntervalEnum.java index af55211..6398f8a 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/DateIntervalEnum.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/DateIntervalEnum.java @@ -1,7 +1,7 @@ package com.iailab.framework.common.enums; import cn.hutool.core.util.ArrayUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,7 +14,7 @@ */ @Getter @AllArgsConstructor -public enum DateIntervalEnum implements IntArrayValuable { +public enum DateIntervalEnum implements ArrayValuable { DAY(1, "天"), WEEK(2, "周"), @@ -23,7 +23,7 @@ YEAR(5, "年") ; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DateIntervalEnum::getInterval).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(DateIntervalEnum::getInterval).toArray(Integer[]::new); /** * 类型 @@ -35,7 +35,7 @@ private final String name; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/TerminalEnum.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/TerminalEnum.java index c49ae51..a3f8acb 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/TerminalEnum.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/TerminalEnum.java @@ -1,6 +1,6 @@ package com.iailab.framework.common.enums; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -13,7 +13,7 @@ */ @RequiredArgsConstructor @Getter -public enum TerminalEnum implements IntArrayValuable { +public enum TerminalEnum implements ArrayValuable { UNKNOWN(0, "未知"), // 目的:在无法解析到 terminal 时,使用它 WECHAT_MINI_PROGRAM(10, "微信小程序"), @@ -22,7 +22,7 @@ APP(31, "手机 App"), ; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TerminalEnum::getTerminal).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(TerminalEnum::getTerminal).toArray(Integer[]::new); /** * 终端 @@ -34,7 +34,7 @@ private final String name; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } } diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/UserTypeEnum.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/UserTypeEnum.java index 560e02c..5ca540a 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/UserTypeEnum.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/enums/UserTypeEnum.java @@ -1,7 +1,7 @@ package com.iailab.framework.common.enums; import cn.hutool.core.util.ArrayUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -12,13 +12,12 @@ */ @AllArgsConstructor @Getter -public enum UserTypeEnum implements IntArrayValuable { +public enum UserTypeEnum implements ArrayValuable { MEMBER(1, "会员"), // 面向 c 端,普通用户 ADMIN(2, "管理员"); // 面向 b 端,管理后台 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(UserTypeEnum::getValue).toArray(); - + public static final Integer[] ARRAYS = Arrays.stream(values()).map(UserTypeEnum::getValue).toArray(Integer[]::new); /** * 类型 */ @@ -33,7 +32,7 @@ } @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } } diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/template/XMLParserUtils.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/template/XMLParserUtils.java new file mode 100644 index 0000000..5e4fc79 --- /dev/null +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/template/XMLParserUtils.java @@ -0,0 +1,296 @@ +package com.iailab.framework.common.util.template; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.ByteArrayInputStream; +import java.util.HashMap; +import java.util.Map; + +public class XMLParserUtils { + private final Map<String, String> settings; + private final double[][] inputData; + + public XMLParserUtils(Map<String, String> settings, double[][] inputData) { + this.settings = settings; + this.inputData = inputData; + } + + public String parse(String xml) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); + doc.getDocumentElement().normalize(); + + StringBuilder output = new StringBuilder(); + processNode(doc.getDocumentElement(), output, -1); + return output.toString(); + } + + private void processNode(Node node, StringBuilder output, int index) { + if (node.getNodeType() == Node.TEXT_NODE) { + output.append(node.getTextContent().trim()); + } else if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + switch (element.getTagName()) { + case "simple-value": + processSimpleValue(element, output, index); + break; + case "setting-value": + processSettingValue(element, output); + break; + case "input-value": + processInputValue(element, output, index); + break; + case "foreach-value": + processForeachValue(element, output); + break; + default: + processChildren(element, output, index); + } + } + } + + private void processChildren(Element element, StringBuilder output, int index) { + NodeList children = element.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + processNode(children.item(i), output, index); + } + } + + private void processSimpleValue(Element element, StringBuilder output, int index) { + processChildren(element, output, index); + } + + private void processSettingValue(Element element, StringBuilder output) { + String key = element.getAttribute("key"); + output.append(settings.getOrDefault(key, "")); + } + + private void processInputValue(Element element, StringBuilder output, int index) { + // 优先使用:port属性(动态计算) + String portExpr = element.getAttribute(":port"); + if (portExpr.isEmpty()) { + // 回退到port属性(静态值) + portExpr = element.getAttribute("port"); + } + + String column = element.getAttribute("column"); + int col = Integer.parseInt(column); + + // 动态计算端口值(考虑当前索引) + int port = evaluateExpression(portExpr, index); + + if (port >= 0 && port < inputData.length && + col >= 0 && col < inputData[port].length) { + double value = inputData[port][col]; + output.append((int)value); + } else { + System.err.printf("Invalid data access: port=%d (max=%d), col=%d (max=%d)%n", + port, inputData.length - 1, col, + (port >= 0 && port < inputData.length) ? inputData[port].length - 1 : -1); + // 默认值 + output.append("0"); + } + } + + private void processForeachValue(Element element, StringBuilder output) { + String lengthKey = element.getAttribute("length"); + int length = Integer.parseInt(settings.getOrDefault(lengthKey, "0")); + String separator = element.getAttribute("separator"); + + StringBuilder loopResult = new StringBuilder(); + for (int i = 0; i < length; i++) { + StringBuilder itemOutput = new StringBuilder(); + + // 直接处理所有子节点 + NodeList children = element.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + Node child = children.item(j); + + if (child.getNodeType() == Node.TEXT_NODE) { + String text = child.getTextContent(); + + // 动态确定转炉状态 + boolean isBlowing = isFurnaceBlowing(i); + + // 替换占位符并调整状态描述 + text = text.replace("{index}", String.valueOf(i + 1)) + .replace("未吹炼", isBlowing ? "正在吹炼" : "未吹炼") + .replace("距离上次吹炼结束时间", + isBlowing ? "吹炼持续时间" : "距离上次吹炼结束时间"); + + itemOutput.append(text); + } else if (child.getNodeType() == Node.ELEMENT_NODE) { + // 传递当前循环索引 + processNode(child, itemOutput, i); + } + } + + loopResult.append(itemOutput); + if (i < length - 1 && !separator.isEmpty()) { + loopResult.append(separator); + } + } + output.append(loopResult.toString().replace(" ", "").replace("\n", "")); + } + + private boolean isFurnaceBlowing(int furnaceIndex) { + // 实际业务逻辑:根据输入数据判断转炉状态 + // 这里简化处理:第三个转炉(index=2)正在吹炼 + return furnaceIndex == 2; + } + + // 自定义表达式计算器 + private int evaluateExpression(String expr, int index) { + if (expr == null || expr.isEmpty()) { + System.err.println("Empty expression, returning 0"); + return 0; + } + // 替换表达式中的{index}占位符 + String processedExpr = expr.replace("{index}", String.valueOf(index)); + + // 移除所有空格确保表达式正确解析 + processedExpr = processedExpr.replaceAll("\\s", ""); + + // 尝试直接解析为整数(优化常见情况) + try { + return Integer.parseInt(processedExpr); + } catch (NumberFormatException e) { + // 不是简单整数,继续尝试表达式计算 + } + // 自定义简单表达式解析器 + try { + // 处理加法表达式(如 "3+0") + if (processedExpr.contains("+")) { + String[] parts = processedExpr.split("\\+"); + int result = 0; + for (String part : parts) { + result += Integer.parseInt(part); + } + return result; + } + // 处理减法表达式(如 "5-2") + else if (processedExpr.contains("-")) { + String[] parts = processedExpr.split("-"); + int result = Integer.parseInt(parts[0]); + for (int i = 1; i < parts.length; i++) { + result -= Integer.parseInt(parts[i]); + } + return result; + } +// // 处理乘法表达式(如 "2 * 3") +// else if (processedExpr.contains("*")) { +// String[] parts = processedExpr.split("\\*"); +// int result = 1; +// for (String part : parts) { +// result *= Integer.parseInt(part); +// } +// return result; +// } +// // 处理除法表达式(如 "6/2") +// else if (processedExpr.contains("/")) { +// String[] parts = processedExpr.split("/"); +// int result = Integer.parseInt(parts[0]); +// for (int i = 1; i < parts.length; i++) { +// int divisor = Integer.parseInt(parts[i]); +// if (divisor != 0) { +// result /= divisor; +// } +// } +// return result; +// } + } catch (NumberFormatException e) { + System.err.println("Error parsing expression: " + processedExpr); + } + // 无法解析的表达式 + System.err.println("Unsupported expression format: " + processedExpr); + return 0; + } + + // test + public static void main(String[] args) throws Exception { + String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<iquestion>\n" + + " <simple-value>根据以下输入,</simple-value>\n" + + " <simple-value>\n" + + " 根据未来<setting-value key=\"predictLength\"/>min的转炉煤气系统运行情况,对煤气调整用户进行调度分配,确保能源产消平衡与系统稳定运行。\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 该系统共包含<setting-value key=\"luShu\"/>座转炉。\n" + + " </simple-value>\n" + + " <foreach-value length=\"luShu\" index=\"index\" separator=\";\">\n" + + " {index}#转炉当前状态未吹炼,\n" + + " 距离上次吹炼结束时间<input-value :port=\"3 + {index}\" column=\"0\" type=\"double\"/>min,\n" + + " 前一炉回收间隔<input-value :port=\"3 + {index}\" column=\"2\" type=\"double\"/>min\n" + + " </foreach-value>\n" + + " <simple-value>\n" + + " 日计划炉数:<input-value port=\"2\" column=\"0\" type=\"double\"/>,当前已吹炼炉数:<input-value port=\"3\" column=\"0\" type=\"double\"/>;\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 历史60min平均每炉煤气回收量:<input-value port=\"1\" column=\"0\" type=\"double\"/>Km3,\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 当前煤气消耗量<input-value port=\"1\" column=\"1\" type=\"double\"/>km3;\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 当前煤气柜容量<setting-value key=\"guiRongLiang\"/>km3;\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 煤气柜柜位安全区间为<setting-value key=\"anQuanQuJian\"/>km3,期望煤气柜位值在<setting-value key=\"qiWangZhi\"/>km3,\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 当前调度用户为电厂各机组:<setting-value key=\"jiZuMingCheng\"/>,\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 各机组当前使用转炉煤气量 [<input-value port=\"0\" column=\"0\" type=\"double\"/>, <input-value port=\"0\" column=\"1\" type=\"double\"/>, <input-value port=\"0\" column=\"2\" type=\"double\"/>, <input-value port=\"0\" column=\"3\" type=\"double\"/>, <input-value port=\"0\" column=\"4\" type=\"double\"/>, <input-value port=\"0\" column=\"5\" type=\"double\"/>];\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 各机组使用转炉煤气下限量 <setting-value key=\"jiZuXiaXian\"/>。\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 各机组使用转炉煤气上限量 <setting-value key=\"jiZuShangXian\"/>。\n" + + " </simple-value>\n" + + " <simple-value>\n" + + " 机组优先级顺序为:<setting-value key=\"jiZuYouXianJi\"/>。\n" + + " </simple-value>\n" + + " <simple-value>请根据优先级顺序确定调度方案。</simple-value>\n" + + "</iquestion>"; + + // 1. 准备配置数据 + Map<String, String> settings = new HashMap<>(); + settings.put("predictLength", "60"); + settings.put("luShu", "3"); + settings.put("guiRongLiang", "80"); + settings.put("anQuanQuJian", "[30, 110]"); + settings.put("qiWangZhi", "65"); + settings.put("jiZuMingCheng", "1#135, 2#135, 1#BTG, 2#BTG, 3#BTG, 4#BTG"); + settings.put("jiZuXiaXian", "[20, 1, 16, 17, 6, 11]"); + settings.put("jiZuShangXian", "[92, 96, 74, 101, 86, 93]"); + settings.put("jiZuYouXianJi", "1#135, 1#BTG, 3#BTG, 2#135, 2#BTG, 4#BTG"); + + // 示例输入数据 - 与期望输出完全匹配 + double[][] inputData = { + // 机组当前用量 + {39, 39, 32, 56, 38, 48}, + // [0]:历史回收量, [1]:当前消耗量 + {24, 115}, + // [0]:日计划炉数, [1]:已吹炼炉数 + {21, 10}, + // 转炉1: [0]:结束时间, [2]:回收间隔 + {15, 0, 18}, + // 转炉2: [0]:结束时间, [2]:回收间隔 + {9, 0, 24}, + // 转炉3: [0]:吹炼持续时间, [2]:回收间隔 + {7, 0, 25} + }; + + // 3. 创建解析器并执行 + XMLParserUtils parser = new XMLParserUtils(settings, inputData); + String result = parser.parse(xmlContent); // 替换为你的XML内容 + System.out.println(result); + } +} \ No newline at end of file diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnum.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnum.java index d7bc460..ebe4122 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnum.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnum.java @@ -1,6 +1,6 @@ package com.iailab.framework.common.validation; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import javax.validation.Constraint; import javax.validation.Payload; @@ -24,7 +24,7 @@ /** * @return 实现 EnumValuable 接口的 */ - Class<? extends IntArrayValuable> value(); + Class<? extends ArrayValuable> value(); String message() default "必须在指定范围 {value}"; diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumCollectionValidator.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumCollectionValidator.java index ce162b2..41a8d5d 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumCollectionValidator.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumCollectionValidator.java @@ -1,7 +1,7 @@ package com.iailab.framework.common.validation; import cn.hutool.core.collection.CollUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; @@ -9,24 +9,23 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -public class InEnumCollectionValidator implements ConstraintValidator<InEnum, Collection<Integer>> { +public class InEnumCollectionValidator implements ConstraintValidator<InEnum, Collection<?>> { - private List<Integer> values; + private List<?> values; @Override public void initialize(InEnum annotation) { - IntArrayValuable[] values = annotation.value().getEnumConstants(); + ArrayValuable<?>[] values = annotation.value().getEnumConstants(); if (values.length == 0) { this.values = Collections.emptyList(); } else { - this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList()); + this.values = Arrays.asList(values[0].array()); } } @Override - public boolean isValid(Collection<Integer> list, ConstraintValidatorContext context) { + public boolean isValid(Collection<?> list, ConstraintValidatorContext context) { // 校验通过 if (CollUtil.containsAll(values, list)) { return true; diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumValidator.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumValidator.java index f20b1fb..7614656 100644 --- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumValidator.java +++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/validation/InEnumValidator.java @@ -1,30 +1,29 @@ package com.iailab.framework.common.validation; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -public class InEnumValidator implements ConstraintValidator<InEnum, Integer> { +public class InEnumValidator implements ConstraintValidator<InEnum, Object> { - private List<Integer> values; + private List<?> values; @Override public void initialize(InEnum annotation) { - IntArrayValuable[] values = annotation.value().getEnumConstants(); + ArrayValuable<?>[] values = annotation.value().getEnumConstants(); if (values.length == 0) { this.values = Collections.emptyList(); } else { - this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList()); + this.values = Arrays.asList(values[0].array()); } } @Override - public boolean isValid(Integer value, ConstraintValidatorContext context) { + public boolean isValid(Object value, ConstraintValidatorContext context) { // 为空时,默认不校验,即认为通过 if (value == null) { return true; @@ -33,7 +32,7 @@ if (values.contains(value)) { return true; } - // 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值) + // 校验不通过,自定义提示语句 context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值 context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate() .replaceAll("\\{value}", values.toString())).addConstraintViolation(); // 重新添加错误提示语句 diff --git a/iailab-module-ai/.idea/.gitignore b/iailab-module-ai/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/iailab-module-ai/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/iailab-module-ai/.idea/compiler.xml b/iailab-module-ai/.idea/compiler.xml new file mode 100644 index 0000000..bfb449c --- /dev/null +++ b/iailab-module-ai/.idea/compiler.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CompilerConfiguration"> + <annotationProcessing> + <profile default="true" name="Default" enabled="true" /> + <profile name="Maven default annotation processors profile" enabled="true"> + <sourceOutputDir name="target/generated-sources/annotations" /> + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> + <outputRelativeToContentRoot value="true" /> + <module name="yudao-module-ai-api" /> + </profile> + <profile name="Annotation profile for iailab-module-ai" enabled="true"> + <sourceOutputDir name="target/generated-sources/annotations" /> + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> + <outputRelativeToContentRoot value="true" /> + <processorPath useClasspath="false"> + <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/springframework/boot/spring-boot-configuration-processor/3.4.1/spring-boot-configuration-processor-3.4.1.jar" /> + <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/projectlombok/lombok/1.18.36/lombok-1.18.36.jar" /> + <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/mapstruct/mapstruct-processor/1.6.3/mapstruct-processor-1.6.3.jar" /> + <entry name="$PROJECT_DIR$/../../../../.m2/repository/org/mapstruct/mapstruct/1.6.3/mapstruct-1.6.3.jar" /> + </processorPath> + <module name="iailab-module-ai-api" /> + <module name="iailab-spring-boot-starter-ai" /> + <module name="iailab-module-ai-biz" /> + </profile> + </annotationProcessing> + </component> + <component name="JavacSettings"> + <option name="ADDITIONAL_OPTIONS_OVERRIDE"> + <module name="iailab-module-ai-api" options="-parameters" /> + <module name="iailab-module-ai-biz" options="-parameters" /> + <module name="iailab-spring-boot-starter-ai" options="-parameters" /> + </option> + </component> +</project> \ No newline at end of file diff --git a/iailab-module-ai/.idea/jarRepositories.xml b/iailab-module-ai/.idea/jarRepositories.xml new file mode 100644 index 0000000..0edd925 --- /dev/null +++ b/iailab-module-ai/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="RemoteRepositoriesConfiguration"> + <remote-repository> + <option name="id" value="central" /> + <option name="name" value="Central Repository" /> + <option name="url" value="https://repo.maven.apache.org/maven2" /> + </remote-repository> + <remote-repository> + <option name="id" value="iailab" /> + <option name="name" value="iailab" /> + <option name="url" value="http://172.16.8.100:8090/repository/iailab/" /> + </remote-repository> + <remote-repository> + <option name="id" value="central" /> + <option name="name" value="Maven Central repository" /> + <option name="url" value="https://repo1.maven.org/maven2" /> + </remote-repository> + <remote-repository> + <option name="id" value="jboss.community" /> + <option name="name" value="JBoss Community repository" /> + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> + </remote-repository> + <remote-repository> + <option name="id" value="iailab" /> + <option name="name" value="iailab" /> + <option name="url" value="http://www.jira.dlindusit.com:30078/repository/iailab/" /> + </remote-repository> + </component> +</project> \ No newline at end of file diff --git a/iailab-module-ai/.idea/misc.xml b/iailab-module-ai/.idea/misc.xml new file mode 100644 index 0000000..c5fe43c --- /dev/null +++ b/iailab-module-ai/.idea/misc.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ExternalStorageConfigurationManager" enabled="true" /> + <component name="MavenProjectsManager"> + <option name="originalFiles"> + <list> + <option value="$PROJECT_DIR$/pom.xml" /> + <option value="$PROJECT_DIR$/iailab-module-ai-api/pom.xml" /> + <option value="$PROJECT_DIR$/iailab-spring-boot-starter-ai/pom.xml" /> + </list> + </option> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="graalvm-jdk-17" project-jdk-type="JavaSDK" /> +</project> \ No newline at end of file diff --git a/iailab-module-ai/.idea/sonarlint.xml b/iailab-module-ai/.idea/sonarlint.xml new file mode 100644 index 0000000..3309dbe --- /dev/null +++ b/iailab-module-ai/.idea/sonarlint.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="SonarLintProjectSettings"> + <option name="moduleMapping"> + <map> + <entry key="iailab-module-ai-biz" value="yudao-module-ai-biz" /> + <entry key="iailab-spring-boot-starter-ai" value="yudao-spring-boot-starter-ai" /> + </map> + </option> + </component> +</project> \ No newline at end of file diff --git a/iailab-module-ai/.idea/vcs.xml b/iailab-module-ai/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/iailab-module-ai/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$/.." vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/iailab-module-ai/iailab-module-ai-api/pom.xml b/iailab-module-ai/iailab-module-ai-api/pom.xml index 5799a96..e725d01 100644 --- a/iailab-module-ai/iailab-module-ai-api/pom.xml +++ b/iailab-module-ai/iailab-module-ai-api/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>com.iailab</groupId> <artifactId>iailab-module-ai</artifactId> - <version>${ai.revision}</version> + <version>${revision}</version> </parent> <build> <plugins> @@ -34,11 +34,26 @@ <artifactId>iailab-common</artifactId> </dependency> + <!-- Web 相关 --> + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-ui</artifactId> + <version>1.8.0</version> + <scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 --> + </dependency> + <!-- 参数校验 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <optional>true</optional> </dependency> + + <!-- RPC 远程调用相关 --> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-openfeign</artifactId> + <optional>true</optional> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatConversationApi.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatConversationApi.java new file mode 100644 index 0000000..17ccb44 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatConversationApi.java @@ -0,0 +1,20 @@ +package com.iailab.module.ai.api.chat; + +import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.module.ai.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = ApiConstants.NAME) +@Tag(name = "RPC 大模型会话") +public interface AiChatConversationApi { + + String PREFIX = ApiConstants.PREFIX + "/conversation"; + + @GetMapping(PREFIX + "/energy-conversation") + @Operation(summary = "会话列表", description = "查询会话列表,只有一条,首次查询先创建再查询") + Long chatEnergyConversation(@RequestParam("modelName") String modelName); +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApi.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApi.java new file mode 100644 index 0000000..9a71cab --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApi.java @@ -0,0 +1,22 @@ +package com.iailab.module.ai.api.chat; + +import com.iailab.module.ai.api.chat.dto.AiChatMessageSendRespDTO; +import com.iailab.module.ai.api.chat.dto.AiChatMessageSendReqDTO; +import com.iailab.module.ai.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = ApiConstants.NAME) +@Tag(name = "RPC 大模型消息") +public interface AiChatMessageApi { + + String PREFIX = ApiConstants.PREFIX + "/message"; + + @PostMapping(PREFIX + "/send-message") + @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") + AiChatMessageSendRespDTO sendMessage(@Valid @RequestBody AiChatMessageSendReqDTO sendReqDTO); +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatConversationRespDTO.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatConversationRespDTO.java new file mode 100644 index 0000000..e3b8603 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatConversationRespDTO.java @@ -0,0 +1,58 @@ +package com.iailab.module.ai.api.chat.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDateTime; + +public class AiChatConversationRespDTO { + @Schema(description = "对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") + private Long userId; + + @Schema(description = "对话标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是一个标题") + private String title; + + @Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + private Boolean pinned; + + @Schema(description = "角色编号", example = "1") + private Long roleId; + + @Schema(description = "模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long modelId; + + @Schema(description = "模型标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "ERNIE-Bot-turbo-0922") + private String model; + + @Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") + private String modelName; + + @Schema(description = "角色设定", example = "一个快乐的程序员") + private String systemMessage; + + @Schema(description = "温度参数", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8") + private Double temperature; + + @Schema(description = "单条回复的最大 Token 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096") + private Integer maxTokens; + + @Schema(description = "上下文的最大 Message 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + private Integer maxContexts; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + // ========== 关联 role 信息 ========== + + @Schema(description = "角色头像", example = "https://www.Iailab.cn/1.png") + private String roleAvatar; + + @Schema(description = "角色名字", example = "小黄") + private String roleName; + + // ========== 仅在【对话管理】时加载 ========== + + @Schema(description = "消息数量", example = "20") + private Integer messageCount; +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendReqDTO.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendReqDTO.java new file mode 100644 index 0000000..4c04f53 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendReqDTO.java @@ -0,0 +1,23 @@ +package com.iailab.module.ai.api.chat.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - AI 聊天消息发送 Request VO") +@Data +public class AiChatMessageSendReqDTO { + + @Schema(description = "聊天对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "聊天对话编号不能为空") + private Long conversationId; + + @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "帮我写个 Java 算法") + @NotEmpty(message = "聊天内容不能为空") + private String content; + + @Schema(description = "是否携带上下文", example = "true") + private Boolean useContext; + +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendRespDTO.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendRespDTO.java new file mode 100644 index 0000000..e58aa27 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiChatMessageSendRespDTO.java @@ -0,0 +1,34 @@ +package com.iailab.module.ai.api.chat.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class AiChatMessageSendRespDTO { + + @Schema(description = "发送消息", requiredMode = Schema.RequiredMode.REQUIRED) + private Message send; + + @Schema(description = "接收消息", requiredMode = Schema.RequiredMode.REQUIRED) + private Message receive; + + @Schema(description = "消息") + @Data + public static class Message { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "role") + private String type; // 参见 MessageType 枚举类 + + @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊") + private String content; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + } +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiModelDO.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiModelDO.java new file mode 100644 index 0000000..14332ae --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/chat/dto/AiModelDO.java @@ -0,0 +1,79 @@ +package com.iailab.module.ai.api.chat.dto; + +import com.iailab.framework.common.enums.CommonStatusEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * AI 模型 DO + * + * 默认模型:{@link #status} 为开启,并且 {@link #sort} 排序第一 + * + * @author houzhongjian + * @since 2025/6/33 11:39 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AiModelDO { + + /** + * 编号 + */ + private Long id; + /** + * API 秘钥编号 + * + */ + private Long keyId; + /** + * 模型名称 + */ + private String name; + /** + * 模型标志 + */ + private String model; + /** + * 平台 + * + */ + private String platform; + /** + * 类型 + * + */ + private Integer type; + + /** + * 排序值 + */ + private Integer sort; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + // ========== 对话配置 ========== + + /** + * 温度参数 + * + * 用于调整生成回复的随机性和多样性程度:较低的温度值会使输出更收敛于高频词汇,较高的则增加多样性 + */ + private Double temperature; + /** + * 单条回复的最大 Token 数量 + */ + private Integer maxTokens; + /** + * 上下文的最大 Message 数量 + */ + private Integer maxContexts; + +} diff --git a/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/enums/ApiConstants.java b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/enums/ApiConstants.java new file mode 100644 index 0000000..db17281 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/enums/ApiConstants.java @@ -0,0 +1,23 @@ +package com.iailab.module.ai.enums; + +import com.iailab.framework.common.enums.RpcConstants; + +/** + * API 相关的枚举 + * + * @author iailab + */ +public class ApiConstants { + + /** + * 服务名 + * + * 注意,需要保证和 spring.application.name 保持一致 + */ + public static final String NAME = "ai-server"; + + public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/ai"; + + public static final String VERSION = "1.0.0"; + +} diff --git a/iailab-module-ai/iailab-module-ai-biz/pom.xml b/iailab-module-ai/iailab-module-ai-biz/pom.xml index a7958b1..395215c 100644 --- a/iailab-module-ai/iailab-module-ai-biz/pom.xml +++ b/iailab-module-ai/iailab-module-ai-biz/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>com.iailab</groupId> <artifactId>iailab-module-ai</artifactId> - <version>${ai.revision}</version> + <version>${revision}</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>iailab-module-ai-biz</artifactId> @@ -29,7 +29,7 @@ <dependency> <groupId>com.iailab</groupId> <artifactId>iailab-module-ai-api</artifactId> - <version>${ai.revision}</version> + <version>${revision}</version> </dependency> <!-- 业务组件 --> @@ -114,8 +114,8 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> - <source>17</source> - <target>17</target> + <source>${java.version}</source> + <target>${java.version}</target> </configuration> </plugin> </plugins> diff --git a/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatConversionApiImpl.java b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatConversionApiImpl.java new file mode 100644 index 0000000..80c3297 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatConversionApiImpl.java @@ -0,0 +1,34 @@ +package com.iailab.module.ai.api.chat; + +import com.iailab.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateEnergyReqVO; +import com.iailab.module.ai.dal.dataobject.chat.AiChatConversationDO; +import com.iailab.module.ai.service.chat.AiChatConversationService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@RestController // 提供 RESTful API 接口,给 Feign 调用 +@Validated +public class AiChatConversionApiImpl implements AiChatConversationApi { + + @Resource + private AiChatConversationService chatConversationService; + + @Override + public Long chatEnergyConversation(String modelName) { + Long conversationId; + List<AiChatConversationDO> list = chatConversationService.getChatConversationList(getLoginUserId(), modelName); + if(list.size() == 0) { + AiChatConversationCreateEnergyReqVO createReqVO = new AiChatConversationCreateEnergyReqVO(); + createReqVO.setModelName(modelName); + conversationId = chatConversationService.createChatConversationEnergy(createReqVO); + } else { + conversationId = list.get(0).getId(); + } + return conversationId; + } +} diff --git a/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApiImpl.java b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApiImpl.java new file mode 100644 index 0000000..80c88af --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/chat/AiChatMessageApiImpl.java @@ -0,0 +1,27 @@ +package com.iailab.module.ai.api.chat; + +import com.iailab.framework.common.util.object.BeanUtils; +import com.iailab.module.ai.api.chat.dto.AiChatMessageSendRespDTO; +import com.iailab.module.ai.api.chat.dto.AiChatMessageSendReqDTO; +import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; +import com.iailab.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; +import com.iailab.module.ai.service.chat.AiChatMessageService; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@RestController // 提供 RESTful API 接口,给 Feign 调用 +@Validated +public class AiChatMessageApiImpl implements AiChatMessageApi { + + @Resource + private AiChatMessageService chatMessageService; + + @Override + public AiChatMessageSendRespDTO sendMessage(AiChatMessageSendReqDTO sendReqDTO) { + AiChatMessageSendRespVO aiChatMessageSendRespVO = chatMessageService.sendMessage(BeanUtils.toBean(sendReqDTO, AiChatMessageSendReqVO.class), getLoginUserId()); + return BeanUtils.toBean(aiChatMessageSendRespVO, AiChatMessageSendRespDTO.class); + } +} diff --git a/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/package-info.java b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/package-info.java new file mode 100644 index 0000000..68235f9 --- /dev/null +++ b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/package-info.java @@ -0,0 +1 @@ +package com.iailab.module.ai.api; \ No newline at end of file diff --git a/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/chat/AiChatConversationServiceImpl.java b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/chat/AiChatConversationServiceImpl.java index f2a15e7..bf6e0bf 100644 --- a/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/chat/AiChatConversationServiceImpl.java +++ b/iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/chat/AiChatConversationServiceImpl.java @@ -92,7 +92,7 @@ AiChatConversationDO conversation = new AiChatConversationDO().setUserId(getLoginUserId()).setPinned(false) .setModelId(model.getId()).setModel(model.getModel()) .setTemperature(model.getTemperature()).setMaxTokens(model.getMaxTokens()).setMaxContexts(model.getMaxContexts()); - conversation.setTitle("新对话"); + conversation.setTitle(createReqVO.getModelName()); chatConversationMapper.insert(conversation); return conversation.getId(); } diff --git a/iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml b/iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml index 90a8245..aaf5b53 100644 --- a/iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml +++ b/iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml @@ -11,6 +11,7 @@ username: @nacos.username@ password: @nacos.password@ discovery: # 【配置中心】配置项 + ip: @deploy.server@ namespace: @profiles.active@ group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP metadata: @@ -59,7 +60,7 @@ logging: file: - name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 + name: @log.path@/logs/${spring.application.name}.log # 日志文件名,全路径 --- #################### 接口文档配置 #################### @@ -111,7 +112,7 @@ job: executor: appname: ${spring.application.name} # 执行器 AppName - logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 + logpath: @log.path@/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 accessToken: default_token # 执行器通讯TOKEN --- #################### AI 相关配置 #################### diff --git a/iailab-module-ai/iailab-spring-boot-starter-ai/pom.xml b/iailab-module-ai/iailab-spring-boot-starter-ai/pom.xml index ac3bd3e..497658d 100644 --- a/iailab-module-ai/iailab-spring-boot-starter-ai/pom.xml +++ b/iailab-module-ai/iailab-spring-boot-starter-ai/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>com.iailab</groupId> <artifactId>iailab-module-ai</artifactId> - <version>${ai.revision}</version> + <version>${revision}</version> </parent> <build> <plugins> diff --git a/iailab-module-ai/pom.xml b/iailab-module-ai/pom.xml index 6972f1d..8bb5b06 100644 --- a/iailab-module-ai/pom.xml +++ b/iailab-module-ai/pom.xml @@ -10,7 +10,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.iailab</groupId> <artifactId>iailab-module-ai</artifactId> - <version>${ai.revision}</version> + <version>${revision}</version> <packaging>pom</packaging> <modules> @@ -44,7 +44,7 @@ <spring.cloud.version>2024.0.0</spring.cloud.version> <spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version> <!-- Web 相关 --> - <springdoc.version>2.7.0</springdoc.version> + <springdoc.version>2.8.3</springdoc.version> <knife4j.version>4.6.0</knife4j.version> <!-- 工具类相关 --> <bizlog-sdk.version>3.0.6</bizlog-sdk.version> diff --git a/iailab-module-data/iailab-module-data-biz/logs/log-debug.2024-11-06.log b/iailab-module-data/iailab-module-data-biz/logs/log-debug.2024-11-06.log new file mode 100644 index 0000000..16f2e6c --- /dev/null +++ b/iailab-module-data/iailab-module-data-biz/logs/log-debug.2024-11-06.log @@ -0,0 +1,262 @@ +[2024-11-06 09:06:36.026] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 55] Starting RabbitMQTest using Java 1.8.0_401 on Thinkpad-E14 with PID 5916 (started by houzh in D:\Work\Yingdashi\Project\iailab-plat\iailab-plat\iailab-module-data\iailab-module-data-biz) +[2024-11-06 09:06:36.028] | [main][DEBUG] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 56] Running with Spring Boot v2.7.18, Spring v5.3.31 +[2024-11-06 09:06:36.029] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStartupProfileInfo,line : 638] The following 1 profile is active: "dev" +[2024-11-06 09:06:36.030] | [main][DEBUG] | [o.s.b.SpringApplication.load,line : 665] Loading source class com.iailab.DataWebApplication +[2024-11-06 09:06:36.094] | [main][WARN ] | [c.a.c.n.c.NacosConfigDataLoader.logTo,line : 258] [Nacos Config] config[dataId=data-server-dev.yaml, group=DEFAULT_GROUP] is empty +[2024-11-06 09:06:36.096] | [main][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.prepareRefresh,line : 637] Refreshing org.springframework.web.context.support.GenericWebApplicationContext@89caf47 +[2024-11-06 09:06:41.325] | [main][INFO ] | [o.s.c.c.s.GenericScope.setSerializationId,line : 283] BeanFactory id=3cae36f0-6484-3ade-8207-23df73e70f40 +[2024-11-06 09:06:42.336] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration' of type [com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration$$EnhancerBySpringCGLIB$$d78165de] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.361] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration' of type [org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.369] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.373] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'loadBalancerClientsDefaultsMappingsProvider' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration$$Lambda$810/1156038763] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.382] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'defaultsBindHandlerAdvisor' of type [org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.391] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'mzt.log.record-com.mzt.logapi.starter.configuration.LogRecordProperties' of type [com.mzt.logapi.starter.configuration.LogRecordProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.418] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'logRecordPerformanceMonitor' of type [com.mzt.logapi.service.impl.DefaultLogRecordPerformanceMonitor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.958] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration' of type [com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:42.984] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dataPermissionAnnotationAdvisor' of type [com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:43.153] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.tenant.config.IailabTenantAutoConfiguration' of type [com.iailab.framework.tenant.config.IailabTenantAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:43.262] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dsProcessor' of type [com.iailab.framework.tenant.core.db.dynamic.TenantDsProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:06:44.667] | [main][INFO ] | [c.a.d.p.DruidDataSource.init,line : 1002] {dataSource-1,master} inited +[2024-11-06 09:06:44.668] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.addDataSource,line : 158] dynamic-datasource - add a datasource named [master] success +[2024-11-06 09:06:44.670] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.afterPropertiesSet,line : 241] dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +[2024-11-06 09:06:49.393] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:06:49.568] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:06:51.980] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1220] Using default implementation for ThreadExecutor +[2024-11-06 09:06:52.058] | [main][INFO ] | [o.q.c.SchedulerSignalerImpl.<init>,line : 61] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl +[2024-11-06 09:06:52.058] | [main][INFO ] | [o.q.c.QuartzScheduler.<init>,line : 229] Quartz Scheduler v.2.3.2 created. +[2024-11-06 09:06:52.093] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 672] Using db table-based data access locking (synchronization). +[2024-11-06 09:06:52.099] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 145] JobStoreCMT initialized. +[2024-11-06 09:06:52.101] | [main][INFO ] | [o.q.c.QuartzScheduler.initialize,line : 294] Scheduler meta-data: Quartz Scheduler (v2.3.2) 'IailabDataScheduler' with instanceId 'Thinkpad-E141730855212013' + Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. + NOT STARTED. + Currently in standby mode. + Number of jobs executed: 0 + Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 20 threads. + Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered. + +[2024-11-06 09:06:52.101] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1374] Quartz scheduler 'IailabDataScheduler' initialized from an externally provided properties instance. +[2024-11-06 09:06:52.102] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1378] Quartz scheduler version: 2.3.2 +[2024-11-06 09:06:52.107] | [main][INFO ] | [o.q.c.QuartzScheduler.setJobFactory,line : 2293] JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@26aecf31 +[2024-11-06 09:06:54.172] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:06:54.397] | [main][INFO ] | [o.r.Reflections.scan,line : 219] Reflections took 99 ms to scan 1 urls, producing 38 keys and 321 values +[2024-11-06 09:06:55.214] | [main][DEBUG] | [o.s.b.a.AutoConfigurationPackages.get,line : 196] @EnableAutoConfiguration was declared on a class in the package 'com.iailab'. Automatic @Repository and @Entity scanning is enabled. +[2024-11-06 09:06:55.698] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerAdapter.initControllerAdviceCache,line : 625] ControllerAdvice beans: 1 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 3 ResponseBodyAdvice +[2024-11-06 09:06:56.060] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerMapping.handlerMethodsInitialized,line : 367] 149 mappings in 'requestMappingHandlerMapping' +[2024-11-06 09:06:56.340] | [main][DEBUG] | [o.s.w.s.h.SimpleUrlHandlerMapping.logMappings,line : 188] Patterns [/webjars/**, /**, /swagger-ui*/*swagger-initializer.js, /swagger-ui*/**] in 'resourceHandlerMapping' +[2024-11-06 09:06:56.423] | [main][DEBUG] | [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache,line : 307] ControllerAdvice beans: 2 @ExceptionHandler, 3 ResponseBodyAdvice +[2024-11-06 09:06:56.674] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:06:56.721] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:06:58.761] | [main][INFO ] | [org.redisson.Version.logVersion,line : 41] Redisson 3.18.0 +[2024-11-06 09:07:00.360] | [redisson-netty-2-7][INFO ] | [o.r.c.p.MasterPubSubConnectionPool.lambda$createConnection$0,line : 162] 1 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:07:00.457] | [redisson-netty-2-19][INFO ] | [o.r.c.p.MasterConnectionPool.lambda$createConnection$0,line : 162] 24 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:07:00.651] | [main][INFO ] | [o.s.b.a.e.w.EndpointLinksResolver.<init>,line : 58] Exposing 1 endpoint(s) beneath base path '/actuator' +[2024-11-06 09:07:00.742] | [main][INFO ] | [o.s.s.w.DefaultSecurityFilterChain.<init>,line : 55] Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@73852c7c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4b6fc615, org.springframework.security.web.context.SecurityContextPersistenceFilter@47609e3d, org.springframework.security.web.header.HeaderWriterFilter@28f307ca, org.springframework.web.filter.CorsFilter@70661538, org.springframework.security.web.authentication.logout.LogoutFilter@144d064a, com.iailab.framework.security.core.filter.TokenAuthenticationFilter@575b9b92, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2a7c82e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@22128b73, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@de7abc9, org.springframework.security.web.session.SessionManagementFilter@71103416, org.springframework.security.web.access.ExceptionTranslationFilter@1ab64f66, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3e11cc3a] +[2024-11-06 09:07:04.051] | [main][INFO ] | [c.f.c.s.SpringContextUtil.setApplicationContext,line : 38] ------SpringContextUtil setApplicationContext------- +[2024-11-06 09:07:04.371] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:07:04.462] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:07:04.478] | [main][INFO ] | [c.i.f.d.c.DictFrameworkUtils.init,line : 73] [init][初始化 DictFrameworkUtils 成功] +[2024-11-06 09:07:04.507] | [main][INFO ] | [c.i.f.j.c.IailabJacksonAutoConfiguration.jsonUtils,line : 48] [init][初始化 JsonUtils 成功] +[2024-11-06 09:07:04.649] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:07:05.471] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:07:10.281] | [main][INFO ] | [o.s.s.q.SchedulerFactoryBean.startScheduler,line : 734] Will start Quartz Scheduler [IailabDataScheduler] in 30 seconds +[2024-11-06 09:07:10.301] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarted,line : 61] Started RabbitMQTest in 42.46 seconds (JVM running for 44.048) +[2024-11-06 09:07:10.311] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state LivenessState changed to CORRECT +[2024-11-06 09:07:10.579] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Preparing: SELECT id, bean_name, params, cron_expression, status, remark, updater, update_date, tenant_id, creator, create_date FROM schedule_job +[2024-11-06 09:07:10.612] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Parameters: +[2024-11-06 09:07:10.643] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] <== Total: 1 +[2024-11-06 09:07:10.836] | [main][INFO ] | [c.a.c.n.r.NacosContextRefresher.registerNacosListener,line : 141] [Nacos Config] Listening config: dataId=data-server-dev.yaml, group=DEFAULT_GROUP +[2024-11-06 09:07:10.976] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state ReadinessState changed to ACCEPTING_TRAFFIC +[2024-11-06 09:07:11.801] | [pool-13-thread-1][INFO ] | [c.i.f.b.c.BannerApplicationRunner.lambda$run$0,line : 22] +---------------------------------------------------------- + 项目启动成功! + ---------------------------------------------------------- +[2024-11-06 09:07:11.849] | [main][INFO ] | [o.s.a.r.c.CachingConnectionFactory.connectAddresses,line : 639] Attempting to connect to: [172.16.8.200:15672] +[2024-11-06 09:07:16.914] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 136] [NotifyCenter] Start destroying Publisher +[2024-11-06 09:07:16.915] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 153] [NotifyCenter] Destruction of the end +[2024-11-06 09:07:16.915] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 102] [HttpClientBeanHolder] Start destroying common HttpClient +[2024-11-06 09:07:16.915] | [SpringApplicationShutdownHook][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.doClose,line : 1060] Closing org.springframework.web.context.support.GenericWebApplicationContext@89caf47, started on Wed Nov 06 09:06:36 CST 2024 +[2024-11-06 09:07:16.916] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 111] [HttpClientBeanHolder] Destruction of the end +[2024-11-06 09:07:16.966] | [SpringApplicationShutdownHook][INFO ] | [o.s.s.q.SchedulerFactoryBean.destroy,line : 847] Shutting down Quartz Scheduler +[2024-11-06 09:07:16.966] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 666] Scheduler IailabDataScheduler_$_Thinkpad-E141730855212013 shutting down. +[2024-11-06 09:07:16.966] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.standby,line : 585] Scheduler IailabDataScheduler_$_Thinkpad-E141730855212013 paused. +[2024-11-06 09:07:16.966] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 740] Scheduler IailabDataScheduler_$_Thinkpad-E141730855212013 shutdown complete. +[2024-11-06 09:07:16.971] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 215] dynamic-datasource start closing .... +[2024-11-06 09:07:16.974] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2204] {dataSource-1} closing ... +[2024-11-06 09:07:17.013] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2277] {dataSource-1} closed +[2024-11-06 09:07:17.013] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.d.DefaultDataSourceDestroyer.destroy,line : 98] dynamic-datasource close the datasource named [master] success, +[2024-11-06 09:07:17.013] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 219] dynamic-datasource all closed success,bye +[2024-11-06 09:08:13.680] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 55] Starting RabbitMQTest using Java 1.8.0_401 on Thinkpad-E14 with PID 25204 (started by houzh in D:\Work\Yingdashi\Project\iailab-plat\iailab-plat\iailab-module-data\iailab-module-data-biz) +[2024-11-06 09:08:13.683] | [main][DEBUG] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 56] Running with Spring Boot v2.7.18, Spring v5.3.31 +[2024-11-06 09:08:13.684] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStartupProfileInfo,line : 638] The following 1 profile is active: "dev" +[2024-11-06 09:08:13.685] | [main][DEBUG] | [o.s.b.SpringApplication.load,line : 665] Loading source class com.iailab.DataWebApplication +[2024-11-06 09:08:13.805] | [main][WARN ] | [c.a.c.n.c.NacosConfigDataLoader.logTo,line : 258] [Nacos Config] config[dataId=data-server-dev.yaml, group=DEFAULT_GROUP] is empty +[2024-11-06 09:08:13.815] | [main][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.prepareRefresh,line : 637] Refreshing org.springframework.web.context.support.GenericWebApplicationContext@586495f1 +[2024-11-06 09:08:19.665] | [main][INFO ] | [o.s.c.c.s.GenericScope.setSerializationId,line : 283] BeanFactory id=3cae36f0-6484-3ade-8207-23df73e70f40 +[2024-11-06 09:08:20.707] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration' of type [com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration$$EnhancerBySpringCGLIB$$30a6dd7c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.743] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration' of type [org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.752] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.759] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'loadBalancerClientsDefaultsMappingsProvider' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration$$Lambda$810/1161998217] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.771] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'defaultsBindHandlerAdvisor' of type [org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.784] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'mzt.log.record-com.mzt.logapi.starter.configuration.LogRecordProperties' of type [com.mzt.logapi.starter.configuration.LogRecordProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:20.826] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'logRecordPerformanceMonitor' of type [com.mzt.logapi.service.impl.DefaultLogRecordPerformanceMonitor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:21.401] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration' of type [com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:21.418] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dataPermissionAnnotationAdvisor' of type [com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:21.561] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.tenant.config.IailabTenantAutoConfiguration' of type [com.iailab.framework.tenant.config.IailabTenantAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:21.678] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dsProcessor' of type [com.iailab.framework.tenant.core.db.dynamic.TenantDsProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:08:23.240] | [main][INFO ] | [c.a.d.p.DruidDataSource.init,line : 1002] {dataSource-1,master} inited +[2024-11-06 09:08:23.242] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.addDataSource,line : 158] dynamic-datasource - add a datasource named [master] success +[2024-11-06 09:08:23.244] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.afterPropertiesSet,line : 241] dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +[2024-11-06 09:08:28.721] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:28.928] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:31.564] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1220] Using default implementation for ThreadExecutor +[2024-11-06 09:08:31.595] | [main][INFO ] | [o.q.c.SchedulerSignalerImpl.<init>,line : 61] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl +[2024-11-06 09:08:31.596] | [main][INFO ] | [o.q.c.QuartzScheduler.<init>,line : 229] Quartz Scheduler v.2.3.2 created. +[2024-11-06 09:08:31.621] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 672] Using db table-based data access locking (synchronization). +[2024-11-06 09:08:31.626] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 145] JobStoreCMT initialized. +[2024-11-06 09:08:31.627] | [main][INFO ] | [o.q.c.QuartzScheduler.initialize,line : 294] Scheduler meta-data: Quartz Scheduler (v2.3.2) 'IailabDataScheduler' with instanceId 'Thinkpad-E141730855311568' + Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. + NOT STARTED. + Currently in standby mode. + Number of jobs executed: 0 + Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 20 threads. + Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered. + +[2024-11-06 09:08:31.627] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1374] Quartz scheduler 'IailabDataScheduler' initialized from an externally provided properties instance. +[2024-11-06 09:08:31.628] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1378] Quartz scheduler version: 2.3.2 +[2024-11-06 09:08:31.631] | [main][INFO ] | [o.q.c.QuartzScheduler.setJobFactory,line : 2293] JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@3c51dec5 +[2024-11-06 09:08:33.431] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:33.588] | [main][INFO ] | [o.r.Reflections.scan,line : 219] Reflections took 86 ms to scan 1 urls, producing 38 keys and 321 values +[2024-11-06 09:08:34.350] | [main][DEBUG] | [o.s.b.a.AutoConfigurationPackages.get,line : 196] @EnableAutoConfiguration was declared on a class in the package 'com.iailab'. Automatic @Repository and @Entity scanning is enabled. +[2024-11-06 09:08:34.876] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerAdapter.initControllerAdviceCache,line : 625] ControllerAdvice beans: 1 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 3 ResponseBodyAdvice +[2024-11-06 09:08:35.264] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerMapping.handlerMethodsInitialized,line : 367] 149 mappings in 'requestMappingHandlerMapping' +[2024-11-06 09:08:35.523] | [main][DEBUG] | [o.s.w.s.h.SimpleUrlHandlerMapping.logMappings,line : 188] Patterns [/webjars/**, /**, /swagger-ui*/*swagger-initializer.js, /swagger-ui*/**] in 'resourceHandlerMapping' +[2024-11-06 09:08:35.577] | [main][DEBUG] | [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache,line : 307] ControllerAdvice beans: 2 @ExceptionHandler, 3 ResponseBodyAdvice +[2024-11-06 09:08:35.726] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:35.760] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:37.017] | [main][INFO ] | [org.redisson.Version.logVersion,line : 41] Redisson 3.18.0 +[2024-11-06 09:08:38.096] | [redisson-netty-2-7][INFO ] | [o.r.c.p.MasterPubSubConnectionPool.lambda$createConnection$0,line : 162] 1 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:08:38.188] | [redisson-netty-2-19][INFO ] | [o.r.c.p.MasterConnectionPool.lambda$createConnection$0,line : 162] 24 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:08:38.394] | [main][INFO ] | [o.s.b.a.e.w.EndpointLinksResolver.<init>,line : 58] Exposing 1 endpoint(s) beneath base path '/actuator' +[2024-11-06 09:08:38.482] | [main][INFO ] | [o.s.s.w.DefaultSecurityFilterChain.<init>,line : 55] Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@650fb50f, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@748321c5, org.springframework.security.web.context.SecurityContextPersistenceFilter@4b7feb38, org.springframework.security.web.header.HeaderWriterFilter@5f967ad3, org.springframework.web.filter.CorsFilter@e0eecbe, org.springframework.security.web.authentication.logout.LogoutFilter@46ae1e6b, com.iailab.framework.security.core.filter.TokenAuthenticationFilter@1fa51751, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@44264fb6, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@90efbba, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@71a7e67, org.springframework.security.web.session.SessionManagementFilter@31829b82, org.springframework.security.web.access.ExceptionTranslationFilter@4bbb00a4, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@721d3a03] +[2024-11-06 09:08:42.301] | [main][INFO ] | [c.f.c.s.SpringContextUtil.setApplicationContext,line : 38] ------SpringContextUtil setApplicationContext------- +[2024-11-06 09:08:42.585] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:42.694] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:42.710] | [main][INFO ] | [c.i.f.d.c.DictFrameworkUtils.init,line : 73] [init][初始化 DictFrameworkUtils 成功] +[2024-11-06 09:08:42.733] | [main][INFO ] | [c.i.f.j.c.IailabJacksonAutoConfiguration.jsonUtils,line : 48] [init][初始化 JsonUtils 成功] +[2024-11-06 09:08:42.811] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:43.238] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:08:45.990] | [main][INFO ] | [o.s.s.q.SchedulerFactoryBean.startScheduler,line : 734] Will start Quartz Scheduler [IailabDataScheduler] in 30 seconds +[2024-11-06 09:08:46.009] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarted,line : 61] Started RabbitMQTest in 40.921 seconds (JVM running for 43.575) +[2024-11-06 09:08:46.015] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state LivenessState changed to CORRECT +[2024-11-06 09:08:46.200] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Preparing: SELECT id, bean_name, params, cron_expression, status, remark, updater, update_date, tenant_id, creator, create_date FROM schedule_job +[2024-11-06 09:08:46.226] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Parameters: +[2024-11-06 09:08:46.249] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] <== Total: 1 +[2024-11-06 09:08:46.367] | [main][INFO ] | [c.a.c.n.r.NacosContextRefresher.registerNacosListener,line : 141] [Nacos Config] Listening config: dataId=data-server-dev.yaml, group=DEFAULT_GROUP +[2024-11-06 09:08:46.503] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state ReadinessState changed to ACCEPTING_TRAFFIC +[2024-11-06 09:08:47.242] | [main][INFO ] | [o.s.a.r.c.CachingConnectionFactory.connectAddresses,line : 639] Attempting to connect to: [127.0.0.1:15672] +[2024-11-06 09:08:47.343] | [pool-13-thread-1][INFO ] | [c.i.f.b.c.BannerApplicationRunner.lambda$run$0,line : 22] +---------------------------------------------------------- + 项目启动成功! + ---------------------------------------------------------- +[2024-11-06 09:08:52.294] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 136] [NotifyCenter] Start destroying Publisher +[2024-11-06 09:08:52.295] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 102] [HttpClientBeanHolder] Start destroying common HttpClient +[2024-11-06 09:08:52.295] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 153] [NotifyCenter] Destruction of the end +[2024-11-06 09:08:52.296] | [SpringApplicationShutdownHook][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.doClose,line : 1060] Closing org.springframework.web.context.support.GenericWebApplicationContext@586495f1, started on Wed Nov 06 09:08:13 CST 2024 +[2024-11-06 09:08:52.296] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 111] [HttpClientBeanHolder] Destruction of the end +[2024-11-06 09:08:52.355] | [SpringApplicationShutdownHook][INFO ] | [o.s.s.q.SchedulerFactoryBean.destroy,line : 847] Shutting down Quartz Scheduler +[2024-11-06 09:08:52.355] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 666] Scheduler IailabDataScheduler_$_Thinkpad-E141730855311568 shutting down. +[2024-11-06 09:08:52.355] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.standby,line : 585] Scheduler IailabDataScheduler_$_Thinkpad-E141730855311568 paused. +[2024-11-06 09:08:52.355] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 740] Scheduler IailabDataScheduler_$_Thinkpad-E141730855311568 shutdown complete. +[2024-11-06 09:08:52.359] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 215] dynamic-datasource start closing .... +[2024-11-06 09:08:52.363] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2204] {dataSource-1} closing ... +[2024-11-06 09:08:52.370] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2277] {dataSource-1} closed +[2024-11-06 09:08:52.371] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.d.DefaultDataSourceDestroyer.destroy,line : 98] dynamic-datasource close the datasource named [master] success, +[2024-11-06 09:08:52.371] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 219] dynamic-datasource all closed success,bye +[2024-11-06 09:11:44.044] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 55] Starting RabbitMQTest using Java 1.8.0_401 on Thinkpad-E14 with PID 19404 (started by houzh in D:\Work\Yingdashi\Project\iailab-plat\iailab-plat\iailab-module-data\iailab-module-data-biz) +[2024-11-06 09:11:44.047] | [main][DEBUG] | [c.i.m.d.c.RabbitMQTest.logStarting,line : 56] Running with Spring Boot v2.7.18, Spring v5.3.31 +[2024-11-06 09:11:44.047] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStartupProfileInfo,line : 638] The following 1 profile is active: "dev" +[2024-11-06 09:11:44.048] | [main][DEBUG] | [o.s.b.SpringApplication.load,line : 665] Loading source class com.iailab.DataWebApplication +[2024-11-06 09:11:44.095] | [main][WARN ] | [c.a.c.n.c.NacosConfigDataLoader.logTo,line : 258] [Nacos Config] config[dataId=data-server-dev.yaml, group=DEFAULT_GROUP] is empty +[2024-11-06 09:11:44.099] | [main][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.prepareRefresh,line : 637] Refreshing org.springframework.web.context.support.GenericWebApplicationContext@5b29ab61 +[2024-11-06 09:11:48.038] | [main][INFO ] | [o.s.c.c.s.GenericScope.setSerializationId,line : 283] BeanFactory id=3cae36f0-6484-3ade-8207-23df73e70f40 +[2024-11-06 09:11:48.793] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration' of type [com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration$$EnhancerBySpringCGLIB$$a1f2c9f4] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.814] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration' of type [org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.819] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.822] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'loadBalancerClientsDefaultsMappingsProvider' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration$$Lambda$810/1079430578] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.830] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'defaultsBindHandlerAdvisor' of type [org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.838] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'mzt.log.record-com.mzt.logapi.starter.configuration.LogRecordProperties' of type [com.mzt.logapi.starter.configuration.LogRecordProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:48.862] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'logRecordPerformanceMonitor' of type [com.mzt.logapi.service.impl.DefaultLogRecordPerformanceMonitor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:49.304] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration' of type [com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:49.318] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dataPermissionAnnotationAdvisor' of type [com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:49.421] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'com.iailab.framework.tenant.config.IailabTenantAutoConfiguration' of type [com.iailab.framework.tenant.config.IailabTenantAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:49.484] | [main][INFO ] | [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization,line : 376] Bean 'dsProcessor' of type [com.iailab.framework.tenant.core.db.dynamic.TenantDsProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +[2024-11-06 09:11:50.714] | [main][INFO ] | [c.a.d.p.DruidDataSource.init,line : 1002] {dataSource-1,master} inited +[2024-11-06 09:11:50.715] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.addDataSource,line : 158] dynamic-datasource - add a datasource named [master] success +[2024-11-06 09:11:50.718] | [main][INFO ] | [c.b.d.d.DynamicRoutingDataSource.afterPropertiesSet,line : 241] dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +[2024-11-06 09:11:55.346] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:11:55.551] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:11:57.524] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1220] Using default implementation for ThreadExecutor +[2024-11-06 09:11:57.556] | [main][INFO ] | [o.q.c.SchedulerSignalerImpl.<init>,line : 61] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl +[2024-11-06 09:11:57.556] | [main][INFO ] | [o.q.c.QuartzScheduler.<init>,line : 229] Quartz Scheduler v.2.3.2 created. +[2024-11-06 09:11:57.580] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 672] Using db table-based data access locking (synchronization). +[2024-11-06 09:11:57.584] | [main][INFO ] | [o.s.s.q.LocalDataSourceJobStore.initialize,line : 145] JobStoreCMT initialized. +[2024-11-06 09:11:57.586] | [main][INFO ] | [o.q.c.QuartzScheduler.initialize,line : 294] Scheduler meta-data: Quartz Scheduler (v2.3.2) 'IailabDataScheduler' with instanceId 'Thinkpad-E141730855517527' + Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. + NOT STARTED. + Currently in standby mode. + Number of jobs executed: 0 + Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 20 threads. + Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered. + +[2024-11-06 09:11:57.586] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1374] Quartz scheduler 'IailabDataScheduler' initialized from an externally provided properties instance. +[2024-11-06 09:11:57.587] | [main][INFO ] | [o.q.i.StdSchedulerFactory.instantiate,line : 1378] Quartz scheduler version: 2.3.2 +[2024-11-06 09:11:57.589] | [main][INFO ] | [o.q.c.QuartzScheduler.setJobFactory,line : 2293] JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@6b989889 +[2024-11-06 09:11:59.615] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:11:59.767] | [main][INFO ] | [o.r.Reflections.scan,line : 219] Reflections took 86 ms to scan 1 urls, producing 38 keys and 321 values +[2024-11-06 09:12:00.450] | [main][DEBUG] | [o.s.b.a.AutoConfigurationPackages.get,line : 196] @EnableAutoConfiguration was declared on a class in the package 'com.iailab'. Automatic @Repository and @Entity scanning is enabled. +[2024-11-06 09:12:00.848] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerAdapter.initControllerAdviceCache,line : 625] ControllerAdvice beans: 1 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 3 ResponseBodyAdvice +[2024-11-06 09:12:01.253] | [main][DEBUG] | [o.s.w.s.m.m.a.RequestMappingHandlerMapping.handlerMethodsInitialized,line : 367] 149 mappings in 'requestMappingHandlerMapping' +[2024-11-06 09:12:01.527] | [main][DEBUG] | [o.s.w.s.h.SimpleUrlHandlerMapping.logMappings,line : 188] Patterns [/webjars/**, /**, /swagger-ui*/*swagger-initializer.js, /swagger-ui*/**] in 'resourceHandlerMapping' +[2024-11-06 09:12:01.604] | [main][DEBUG] | [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache,line : 307] ControllerAdvice beans: 2 @ExceptionHandler, 3 ResponseBodyAdvice +[2024-11-06 09:12:01.785] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:01.812] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:03.041] | [main][INFO ] | [org.redisson.Version.logVersion,line : 41] Redisson 3.18.0 +[2024-11-06 09:12:04.080] | [redisson-netty-2-7][INFO ] | [o.r.c.p.MasterPubSubConnectionPool.lambda$createConnection$0,line : 162] 1 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:12:04.196] | [redisson-netty-2-19][INFO ] | [o.r.c.p.MasterConnectionPool.lambda$createConnection$0,line : 162] 24 connections initialized for 172.16.8.100/172.16.8.100:6379 +[2024-11-06 09:12:04.452] | [main][INFO ] | [o.s.b.a.e.w.EndpointLinksResolver.<init>,line : 58] Exposing 1 endpoint(s) beneath base path '/actuator' +[2024-11-06 09:12:04.571] | [main][INFO ] | [o.s.s.w.DefaultSecurityFilterChain.<init>,line : 55] Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@503f5382, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5710fca8, org.springframework.security.web.context.SecurityContextPersistenceFilter@50df710a, org.springframework.security.web.header.HeaderWriterFilter@23038621, org.springframework.web.filter.CorsFilter@7e2e1179, org.springframework.security.web.authentication.logout.LogoutFilter@6b4b6cd6, com.iailab.framework.security.core.filter.TokenAuthenticationFilter@19e7aa5b, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3e64cf62, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@7768ffae, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@336e59a6, org.springframework.security.web.session.SessionManagementFilter@71b253b, org.springframework.security.web.access.ExceptionTranslationFilter@1cd25514, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4d682552] +[2024-11-06 09:12:07.460] | [main][INFO ] | [c.f.c.s.SpringContextUtil.setApplicationContext,line : 38] ------SpringContextUtil setApplicationContext------- +[2024-11-06 09:12:07.753] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:07.809] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:07.824] | [main][INFO ] | [c.i.f.d.c.DictFrameworkUtils.init,line : 73] [init][初始化 DictFrameworkUtils 成功] +[2024-11-06 09:12:07.859] | [main][INFO ] | [c.i.f.j.c.IailabJacksonAutoConfiguration.jsonUtils,line : 48] [init][初始化 JsonUtils 成功] +[2024-11-06 09:12:07.917] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:08.316] | [main][INFO ] | [o.s.c.o.FeignClientFactoryBean.getTarget,line : 418] For 'system-server' URL not provided. Will try picking an instance via load-balancing. +[2024-11-06 09:12:12.183] | [main][INFO ] | [o.s.s.q.SchedulerFactoryBean.startScheduler,line : 734] Will start Quartz Scheduler [IailabDataScheduler] in 30 seconds +[2024-11-06 09:12:12.200] | [main][INFO ] | [c.i.m.d.c.RabbitMQTest.logStarted,line : 61] Started RabbitMQTest in 34.676 seconds (JVM running for 36.159) +[2024-11-06 09:12:12.208] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state LivenessState changed to CORRECT +[2024-11-06 09:12:12.403] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Preparing: SELECT id, bean_name, params, cron_expression, status, remark, updater, update_date, tenant_id, creator, create_date FROM schedule_job +[2024-11-06 09:12:12.433] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] ==> Parameters: +[2024-11-06 09:12:12.473] | [main][DEBUG] | [c.i.m.d.j.d.S.selectList.debug,line : 135] <== Total: 1 +[2024-11-06 09:12:12.611] | [main][INFO ] | [c.a.c.n.r.NacosContextRefresher.registerNacosListener,line : 141] [Nacos Config] Listening config: dataId=data-server-dev.yaml, group=DEFAULT_GROUP +[2024-11-06 09:12:12.703] | [main][DEBUG] | [o.s.b.a.ApplicationAvailabilityBean.onApplicationEvent,line : 77] Application availability state ReadinessState changed to ACCEPTING_TRAFFIC +[2024-11-06 09:12:13.427] | [main][INFO ] | [o.s.a.r.c.CachingConnectionFactory.connectAddresses,line : 639] Attempting to connect to: [127.0.0.1:5672] +[2024-11-06 09:12:13.584] | [pool-13-thread-1][INFO ] | [c.i.f.b.c.BannerApplicationRunner.lambda$run$0,line : 22] +---------------------------------------------------------- + 项目启动成功! + ---------------------------------------------------------- +[2024-11-06 09:12:13.589] | [main][INFO ] | [o.s.a.r.c.CachingConnectionFactory.createBareConnection,line : 590] Created new connection: rabbitConnectionFactory#3e37c38f:0/SimpleConnection@3023a901 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 60360] +[2024-11-06 09:12:13.767] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 102] [HttpClientBeanHolder] Start destroying common HttpClient +[2024-11-06 09:12:13.767] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 136] [NotifyCenter] Start destroying Publisher +[2024-11-06 09:12:13.768] | [Thread-7][WARN ] | [c.a.n.c.n.NotifyCenter.shutdown,line : 153] [NotifyCenter] Destruction of the end +[2024-11-06 09:12:13.768] | [SpringApplicationShutdownHook][DEBUG] | [o.s.w.c.s.GenericWebApplicationContext.doClose,line : 1060] Closing org.springframework.web.context.support.GenericWebApplicationContext@5b29ab61, started on Wed Nov 06 09:11:44 CST 2024 +[2024-11-06 09:12:13.769] | [Thread-2][WARN ] | [c.a.n.c.h.HttpClientBeanHolder.shutdown,line : 111] [HttpClientBeanHolder] Destruction of the end +[2024-11-06 09:12:13.850] | [SpringApplicationShutdownHook][INFO ] | [o.s.s.q.SchedulerFactoryBean.destroy,line : 847] Shutting down Quartz Scheduler +[2024-11-06 09:12:13.851] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 666] Scheduler IailabDataScheduler_$_Thinkpad-E141730855517527 shutting down. +[2024-11-06 09:12:13.851] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.standby,line : 585] Scheduler IailabDataScheduler_$_Thinkpad-E141730855517527 paused. +[2024-11-06 09:12:13.852] | [SpringApplicationShutdownHook][INFO ] | [o.q.c.QuartzScheduler.shutdown,line : 740] Scheduler IailabDataScheduler_$_Thinkpad-E141730855517527 shutdown complete. +[2024-11-06 09:12:13.858] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 215] dynamic-datasource start closing .... +[2024-11-06 09:12:13.864] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2204] {dataSource-1} closing ... +[2024-11-06 09:12:13.876] | [SpringApplicationShutdownHook][INFO ] | [c.a.d.p.DruidDataSource.close,line : 2277] {dataSource-1} closed +[2024-11-06 09:12:13.876] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.d.DefaultDataSourceDestroyer.destroy,line : 98] dynamic-datasource close the datasource named [master] success, +[2024-11-06 09:12:13.876] | [SpringApplicationShutdownHook][INFO ] | [c.b.d.d.DynamicRoutingDataSource.destroy,line : 219] dynamic-datasource all closed success,bye diff --git a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-prod.yaml b/iailab-module-data/iailab-module-data-biz/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..da39151 --- /dev/null +++ b/iailab-module-data/iailab-module-data-biz/src/main/resources/application-prod.yaml @@ -0,0 +1,127 @@ +spring: + autoconfigure: + exclude: + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration + datasource: + druid: + web-stat-filter: + enabled: true + stat-view-servlet: + enabled: true + allow: + url-pattern: /druid/* + login-username: + login-password: + filter: + stat: + enabled: true + log-slow-sql: true + slow-sql-millis: 100 + merge-sql: true + wall: + config: + multi-statement-allow: true + dynamic: + druid: + initial-size: 1 + min-idle: 1 + max-active: 20 + max-wait: 600000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + max-evictable-idle-time-millis: 900000 + validation-query: select version() + test-while-idle: true + test-on-borrow: false + test-on-return: false + primary: master + datasource: + master: + url: jdbc:mysql://localhost:3306/iailab_expert_master?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + username: root + password: 123456 + + redis: + host: 127.0.0.1 + port: 6379 + database: 0 + password: 123456 + + rabbitmq: + host: 172.16.1.221 + port: 5672 + username: admin + password: admin123 + + boot: + admin: + client: + instance: + service-host-type: IP + +rocketmq: + name-server: 172.16.8.100:9876 # RocketMQ Namesrv + +xxl: + job: + enabled: true + admin: + addresses: http://172.16.8.100:9090/xxl-job-admin + +lock4j: + acquire-timeout: 3000 + expire: 30000 + +management: + endpoints: + web: + base-path: /actuator + exposure: + include: '*' + +logging: + level: + com.iailab.module.system.dal.mysql: debug + com.iailab.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO + com.iailab.module.system.dal.mysql.sms.SmsChannelMapper: INFO + +iailab: + env: + tag: ${HOSTNAME} + captcha: + enable: false + security: + mock-enable: true + xss: + enable: false + exclude-urls: + - ${spring.boot.admin.context-path}/** + - ${management.endpoints.web.base-path}/** + access-log: + enable: false + demo: false + +influx-db: + org: iailab + token: _338h4Kbu2KQaes5QwAyOz9pTUueXoSF9XmPi8N9oTS1SrhTZVj4J9JfSraUyWA0PfWMZOlf9QWax-USkJQR_A== + url: http://172.16.1.221:8086 + username: iailab + password: iailab2019 + +iems: + upload-dir: D:/DLUT/upload/ + +video: + capture-dir: D:/iailab + dahua: + path: + capture-path: /Dahua/Capture/ + model-path: /Dahua/Model/ + hikvision: + path: + capture-path: /Hikvision/Capture/ + model-path: /Hikvision/Model/ + pic-size: 2 # size of picture 0=CIF, 1=QCIF, 2=D1 3=UXGA(1600x1200), 4=SVGA(800x600), 5=HD720p(1280x720),6=VGA + pic-quality: 0 # quality of picture 0-best 1-better 2-normal + diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiAccessLogApi.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiAccessLogApi.java index 599cc76..f7e510a 100644 --- a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiAccessLogApi.java +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiAccessLogApi.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -21,4 +22,13 @@ @Operation(summary = "创建 API 访问日志") CommonResult<Boolean> createApiAccessLog(@Valid @RequestBody ApiAccessLogCreateReqDTO createDTO); + /** + * 【异步】创建 API 访问日志 + * + * @param createDTO 访问日志 DTO + */ + @Async + default void createApiAccessLogAsync(ApiAccessLogCreateReqDTO createDTO) { + createApiAccessLog(createDTO).checkError(); + } } diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiErrorLogApi.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiErrorLogApi.java index c4db73d..0b961fc 100644 --- a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiErrorLogApi.java +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/logger/ApiErrorLogApi.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -21,4 +22,14 @@ @Operation(summary = "创建 API 异常日志") CommonResult<Boolean> createApiErrorLog(@Valid @RequestBody ApiErrorLogCreateReqDTO createDTO); + /** + * 【异步】创建 API 异常日志 + * + * @param createDTO 异常日志 DTO + */ + @Async + default void createApiErrorLogAsync(ApiErrorLogCreateReqDTO createDTO) { + createApiErrorLog(createDTO).checkError(); + } + } diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/MonitorApi.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/MonitorApi.java new file mode 100644 index 0000000..f39fd52 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/MonitorApi.java @@ -0,0 +1,42 @@ +package com.iailab.module.infra.api.monitor; + +import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.module.infra.api.monitor.dto.MonitorDiskDTO; +import com.iailab.module.infra.api.monitor.dto.MonitorMemDTO; +import com.iailab.module.infra.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.validation.Valid; +import java.util.List; + +@FeignClient(name = ApiConstants.NAME) +@Tag(name = "RPC 服务 - 磁盘监控") +public interface MonitorApi { + + String PREFIX = ApiConstants.PREFIX + "/monitor"; + + /** + * 保存内存信息日志 + * + * @param reportMemReqDTO 内存日志对象 + * @return 文件路径 + */ + @PostMapping(PREFIX + "/reportMemInfo") + @Operation(summary = "保存内存日志对象") + CommonResult<Long> reportMemInfo(@Valid @RequestBody MonitorMemDTO reportMemReqDTO); + + /** + * 保存磁盘信息日志 + * + * @param reportMemReqDTOS 磁盘日志对象 + * @return 文件路径 + */ + @PostMapping(PREFIX + "/reportDiskInfo") + @Operation(summary = "保存磁盘日志对象") + CommonResult reportDiskInfo(@Valid @RequestBody List<MonitorDiskDTO> reportMemReqDTOS); + +} diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorDiskDTO.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorDiskDTO.java new file mode 100644 index 0000000..6f42a20 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorDiskDTO.java @@ -0,0 +1,55 @@ +package com.iailab.module.infra.api.monitor.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.math.BigDecimal; + +/** + * 磁盘监控日志 DTO + * + * @author 超级管理员 + */ +@Schema(description = "RPC 服务 - 服务监控-磁盘监控 Request DTO") +@Data +public class MonitorDiskDTO { + + /** + * 主机名称 + */ + private String hostName; + /** + * 服务器ip + */ + private String hostIp; + /** + * 盘符 + */ + private String disk; + /** + * 磁盘名 + */ + private String diskName; + /** + * 总空间 + */ + private BigDecimal spaceTotal; + /** + * 已用空间 + */ + private BigDecimal spaceUsed; + /** + * 可用空间 + */ + private BigDecimal spaceUsable; + /** + * 空间使用比例 + */ + private BigDecimal spaceRatio; + + /** + * 租户Id + */ + private Integer tenantId; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorMemDTO.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorMemDTO.java new file mode 100644 index 0000000..cfb1ca0 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/api/monitor/dto/MonitorMemDTO.java @@ -0,0 +1,79 @@ +package com.iailab.module.infra.api.monitor.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.math.BigDecimal; + +/** + * 内存监控日志 DO + * + * @author 超级管理员 + */ +@Schema(description = "RPC 服务 - 服务监控-内存监控 Request DTO") +@Data +public class MonitorMemDTO { + + /** + * 主机名称 + */ + private String hostName; + /** + * 服务器ip + */ + private String hostIp; + /** + * 服务名 + */ + private String serverName; + /** + * 总物理内存 + */ + private BigDecimal physicalTotal; + /** + * 已用物理内存 + */ + private BigDecimal physicalUsed; + /** + * 剩余物理内存 + */ + private BigDecimal physicalFree; + /** + * 物理内存使用率 + */ + private BigDecimal physicalUsage; + /** + * jvm运行总内存 + */ + private BigDecimal runtimeTotal; + /** + * jvm最大内存 + */ + private BigDecimal runtimeMax; + /** + * jvm已用内存 + */ + private BigDecimal runtimeUsed; + /** + * jvm空闲内存 + */ + private BigDecimal runtimeFree; + /** + * jvm内存使用率 + */ + private BigDecimal runtimeUsage; + /** + * 系统cpu利用率 + */ + private BigDecimal systemCpuLoad; + /** + * 进程cpu利用率 + */ + private BigDecimal processCpuLoad; + + /** + * 租户Id + */ + private Integer tenantId; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/util/ServerInfoCollector.java b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/util/ServerInfoCollector.java new file mode 100644 index 0000000..b0a4638 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-api/src/main/java/com/iailab/module/infra/util/ServerInfoCollector.java @@ -0,0 +1,198 @@ +package com.iailab.module.infra.util; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.iailab.module.infra.api.monitor.dto.MonitorDiskDTO; +import com.iailab.module.infra.api.monitor.dto.MonitorMemDTO; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.math.BigDecimal; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.util.ArrayList; +import java.util.List; + +public class ServerInfoCollector { + + private static BigDecimal UNIT = new BigDecimal(1024 * 1024); + + private static BigDecimal PERCENT_UNIT = new BigDecimal(100); + + private static String hostName; + + private static String hostIp; + + public static void initServerInfo() throws UnknownHostException { + // 获取本地主机对象 + InetAddress localHost = InetAddress.getLocalHost(); + // 获取主机名 + hostName = localHost.getHostName(); +// // 获取IP地址 + hostIp = localHost.getHostAddress(); +// try { +// Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); +// while (interfaces.hasMoreElements()) { +// NetworkInterface networkInterface = interfaces.nextElement(); +// // 过滤掉loopback接口 +// if (networkInterface.isLoopback() || !networkInterface.isUp()) { +// continue; +// } +// Enumeration<InetAddress> addresses = networkInterface.getInetAddresses(); +// while (addresses.hasMoreElements()) { +// InetAddress addr = addresses.nextElement(); +// // 过滤掉IPv6地址和回环地址 +// if (!addr.isLoopbackAddress() && addr.getHostAddress().contains(".")) { // 确保是IPv4地址 +// System.out.println("局域网IP地址: " + addr.getHostAddress()); +// hostIp = addr.getHostAddress(); +// } +// } +// } +// } catch (SocketException e) { +// e.printStackTrace(); +// } + } + + /** + * 内存信息处理 + */ + public static MonitorMemDTO collectMonitorMem(String serverName) throws UnknownHostException { + initServerInfo(); + OperatingSystemMXBean operatingSystemBean = ManagementFactory.getOperatingSystemMXBean(); + JSONObject operatingSystemJson = JSON.parseObject(JSON.toJSONString(operatingSystemBean)); + BigDecimal totalPhysicalMemory = operatingSystemJson.getBigDecimal("totalPhysicalMemorySize"); + BigDecimal freePhysicalMemory = operatingSystemJson.getBigDecimal("freePhysicalMemorySize"); + BigDecimal usedPhysicalMemory = totalPhysicalMemory.subtract(freePhysicalMemory); + BigDecimal systemCpuLoad = operatingSystemJson.getBigDecimal("systemCpuLoad"); + BigDecimal processCpuLoad = operatingSystemJson.getBigDecimal("processCpuLoad"); + Runtime runtime = Runtime.getRuntime(); + MonitorMemDTO monitorMemDTO = new MonitorMemDTO(); + monitorMemDTO.setHostName(hostName) + .setHostIp(hostIp) + .setServerName(serverName) + .setPhysicalTotal(totalPhysicalMemory.divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setPhysicalUsed(usedPhysicalMemory.divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setPhysicalFree(freePhysicalMemory.divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setPhysicalUsage(NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setRuntimeTotal(new BigDecimal(runtime.totalMemory()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setRuntimeFree(new BigDecimal(runtime.freeMemory()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setRuntimeMax(new BigDecimal(runtime.maxMemory()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setRuntimeUsed(new BigDecimal(runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setRuntimeUsage(new BigDecimal(NumberUtil.div(runtime.totalMemory()/1f - runtime.freeMemory(), runtime.totalMemory())).setScale(2, BigDecimal.ROUND_HALF_UP)) + .setSystemCpuLoad(systemCpuLoad.multiply(PERCENT_UNIT)) + .setProcessCpuLoad(processCpuLoad.multiply(PERCENT_UNIT)); + return monitorMemDTO; + } + + /** + * 磁盘信息处理 + */ + public static List<MonitorDiskDTO> collectMonitorDisk() throws IOException { + List<MonitorDiskDTO> monitorDiskSaveReqVOS = new ArrayList<>(); + String os = System.getProperty("os.name").toLowerCase(); + System.out.println(os); + if (os.contains("win")) { + getWindowsDiskUsage(monitorDiskSaveReqVOS); + } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) { + try { + getLinuxDiskUsage(monitorDiskSaveReqVOS); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } else { + System.out.println("不支持的服务器系统!"); + } + return monitorDiskSaveReqVOS; + } + + private static void getWindowsDiskUsage(List<MonitorDiskDTO> monitorDiskSaveReqVOS) throws IOException { + initServerInfo(); + // 获取默认文件系统的所有存储设备 + Iterable<FileStore> fileStores = FileSystems.getDefault().getFileStores(); + for (FileStore store : fileStores) { + MonitorDiskDTO monitorDiskSaveReqVO = new MonitorDiskDTO(); + // 获取磁盘的总空间、已用空间和可用空间 + BigDecimal totalSpace = new BigDecimal(store.getTotalSpace()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP); // 总空间 + BigDecimal usableSpace = new BigDecimal(store.getUsableSpace()).divide(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP); // 可用空间 + BigDecimal usedSpace = totalSpace.subtract(usableSpace).setScale(2, BigDecimal.ROUND_HALF_UP); // 计算已用空间 + monitorDiskSaveReqVO.setHostName(hostName) + .setHostIp(hostIp) + .setDisk(store.toString()) + .setDiskName(ObjectUtils.isNotEmpty(store.name()) ? store.name(): "/") + .setSpaceTotal(totalSpace) + .setSpaceUsable(usableSpace) + .setSpaceUsed(usedSpace) + .setSpaceRatio(usedSpace.divide(totalSpace, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP)); + monitorDiskSaveReqVOS.add(monitorDiskSaveReqVO); + } + } + + /** + * 获取 Linux 系统的磁盘使用情况 + */ + private static void getLinuxDiskUsage(List<MonitorDiskDTO> monitorDiskSaveReqVOS) throws IOException, InterruptedException { + Process process = Runtime.getRuntime().exec("df -h"); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + boolean isHeader = true; + while ((line = reader.readLine()) != null) { + if (isHeader) { + isHeader = false; + continue; + } + String[] parts = line.trim().split("\\s+"); + System.out.println(parts); + if (parts.length >= 6) { + MonitorDiskDTO monitorDiskSaveReqVO = new MonitorDiskDTO(); + String filesystem = parts[0]; + String size = parts[1]; + String used = parts[2]; + String available = parts[3]; + String mountedOn = parts[5]; + BigDecimal totalSpace = formatSize(size); + BigDecimal usableSpace = formatSize(available); + BigDecimal usedSpace = formatSize(used); + monitorDiskSaveReqVO.setHostName(hostName) + .setHostIp(hostIp) + .setDisk(filesystem + "(" + mountedOn + ")") + .setDiskName(mountedOn) + .setSpaceTotal(totalSpace) + .setSpaceUsable(usableSpace) + .setSpaceUsed(usedSpace) + .setSpaceRatio(usedSpace.divide(totalSpace, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP)); + monitorDiskSaveReqVOS.add(monitorDiskSaveReqVO); + } + } + int exitCode = process.waitFor(); + if (exitCode != 0) { + System.err.println("Command execution failed with exit code: " + exitCode); + } + reader.close(); + } + + /** + * 将字节大小转换为可读的格式 + * @param size 字节数 + * @return 人类可读的大小(MB) + */ + private static BigDecimal formatSize(String size) { + if(size.contains("T")){ + return new BigDecimal(Float.parseFloat(size.replace("T",""))).multiply(UNIT).setScale(2, BigDecimal.ROUND_HALF_UP); + } else if (size.contains("G")){ + return new BigDecimal(Float.parseFloat(size.replace("G","")) * 1024).setScale(2, BigDecimal.ROUND_HALF_UP); + } else if (size.contains("M")){ + return new BigDecimal(Float.parseFloat(size.replace("M",""))).setScale(2, BigDecimal.ROUND_HALF_UP); + } else if (size.contains("K")){ + return new BigDecimal(Float.parseFloat(size.replace("K","")) / 1024).setScale(2, BigDecimal.ROUND_HALF_UP); + } else { + return new BigDecimal(0); + } + } +} diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/api/monitor/MonitorApiImpl.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/api/monitor/MonitorApiImpl.java new file mode 100644 index 0000000..ec8fccc --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/api/monitor/MonitorApiImpl.java @@ -0,0 +1,40 @@ +package com.iailab.module.infra.api.monitor; + +import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.framework.common.util.object.BeanUtils; +import com.iailab.module.infra.api.monitor.dto.MonitorDiskDTO; +import com.iailab.module.infra.api.monitor.dto.MonitorMemDTO; +import com.iailab.module.infra.controller.admin.monitordisk.vo.MonitorDiskSaveReqVO; +import com.iailab.module.infra.controller.admin.monitormem.vo.MonitorMemSaveReqVO; +import com.iailab.module.infra.service.monitordisk.MonitorDiskService; +import com.iailab.module.infra.service.monitormem.MonitorMemService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + + +@RestController // 提供 RESTful API 接口,给 Feign 调用 +@Validated +public class MonitorApiImpl implements MonitorApi { + + @Resource + private MonitorMemService monitorMemService; + + @Resource + private MonitorDiskService monitorDiskService; + + @Override + public CommonResult<Long> reportMemInfo(MonitorMemDTO reportMemReqDTO) { + MonitorMemSaveReqVO bean = BeanUtils.toBean(reportMemReqDTO, MonitorMemSaveReqVO.class); + return CommonResult.success(monitorMemService.createMonitorMem(bean)); + } + + @Override + public CommonResult reportDiskInfo(List<MonitorDiskDTO> reportDiskReqDTOS) { + List<MonitorDiskSaveReqVO> bean = BeanUtils.toBean(reportDiskReqDTOS, MonitorDiskSaveReqVO.class); + monitorDiskService.createMonitorDiskBatch(bean); + return CommonResult.success(); + } +} diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/MonitorDiskController.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/MonitorDiskController.java new file mode 100644 index 0000000..31d08e7 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/MonitorDiskController.java @@ -0,0 +1,126 @@ +package com.iailab.module.infra.controller.admin.monitordisk; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import com.iailab.framework.common.pojo.PageParam; +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.framework.common.util.object.BeanUtils; +import static com.iailab.framework.common.pojo.CommonResult.success; + +import com.iailab.framework.excel.core.util.ExcelUtils; + +import com.iailab.framework.apilog.core.annotation.ApiAccessLog; +import static com.iailab.framework.apilog.core.enums.OperateTypeEnum.*; + +import com.iailab.module.infra.controller.admin.monitordisk.vo.*; +import com.iailab.module.infra.dal.dataobject.monitordisk.MonitorDiskDO; +import com.iailab.module.infra.service.monitordisk.MonitorDiskService; + +@Tag(name = "管理后台 - 磁盘监控日志") +@RestController +@RequestMapping("/infra/monitor-disk") +@Validated +public class MonitorDiskController { + + @Resource + private MonitorDiskService monitorDiskService; + + @PostMapping("/create") + @Operation(summary = "创建磁盘监控日志") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:create')") + public CommonResult<Long> createMonitorDisk(@Valid @RequestBody MonitorDiskSaveReqVO createReqVO) { + return success(monitorDiskService.createMonitorDisk(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新磁盘监控日志") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:update')") + public CommonResult<Boolean> updateMonitorDisk(@Valid @RequestBody MonitorDiskSaveReqVO updateReqVO) { + monitorDiskService.updateMonitorDisk(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除磁盘监控日志") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:delete')") + public CommonResult<Boolean> deleteMonitorDisk(@RequestParam("id") Long id) { + monitorDiskService.deleteMonitorDisk(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得磁盘监控日志") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<MonitorDiskRespVO> getMonitorDisk(@RequestParam("id") Long id) { + MonitorDiskDO monitorDisk = monitorDiskService.getMonitorDisk(id); + return success(BeanUtils.toBean(monitorDisk, MonitorDiskRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得磁盘监控日志分页") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<PageResult<MonitorDiskRespVO>> getMonitorDiskPage(@Valid MonitorDiskPageReqVO pageReqVO) { + PageResult<MonitorDiskDO> pageResult = monitorDiskService.getMonitorDiskPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, MonitorDiskRespVO.class)); + } + + @GetMapping("/getMonitorDiskList") + @Operation(summary = "获得磁盘监控日志列表") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<List<Map<String, List<Map<String, Object>>>>> getMonitorMemList(@Valid MonitorDiskReqVO reqVO) { + List<Map<String, List<Map<String, Object>>>> result = monitorDiskService.getMonitorDiskList(reqVO); + return success(result); + } + + @GetMapping("/getAllHost") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<List<String>> getAllHost() { + List<String> hosts = monitorDiskService.getAllHost(); + return success(hosts); + } + + @GetMapping("/getAllIp") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<List<String>> getAllIp() { + List<String> ips = monitorDiskService.getAllIp(); + return success(ips); + } + + @GetMapping("/getMonitorDiskInfo") + @Operation(summary = "获得磁盘监控日志列表") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:query')") + public CommonResult<List<Map<String, Object>>> getMonitorDiskInfo(@Valid MonitorDiskReqVO reqVO) { + List<Map<String, Object>> result = monitorDiskService.getMonitorDiskInfo(reqVO); + return success(result); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出磁盘监控日志 Excel") + @PreAuthorize("@ss.hasPermission('infra:monitor-disk:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportMonitorDiskExcel(@Valid MonitorDiskPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List<MonitorDiskDO> list = monitorDiskService.getMonitorDiskPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "磁盘监控日志.xls", "数据", MonitorDiskRespVO.class, + BeanUtils.toBean(list, MonitorDiskRespVO.class)); + } + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskPageReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskPageReqVO.java new file mode 100644 index 0000000..d23e29f --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskPageReqVO.java @@ -0,0 +1,47 @@ +package com.iailab.module.infra.controller.admin.monitordisk.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import com.iailab.framework.common.pojo.PageParam; +import java.math.BigDecimal; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 磁盘监控日志分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MonitorDiskPageReqVO extends PageParam { + + @Schema(description = "主机名称", example = "iailab") + private String hostName; + + @Schema(description = "服务器ip") + private String hostIp; + + @Schema(description = "盘符") + private String disk; + + @Schema(description = "磁盘名", example = "王五") + private String diskName; + + @Schema(description = "总空间") + private BigDecimal spaceTotal; + + @Schema(description = "已用空间") + private BigDecimal spaceUsed; + + @Schema(description = "可用空间") + private BigDecimal spaceUsable; + + @Schema(description = "空间使用比例") + private BigDecimal spaceRatio; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskReqVO.java new file mode 100644 index 0000000..0532b2b --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskReqVO.java @@ -0,0 +1,49 @@ +package com.iailab.module.infra.controller.admin.monitordisk.vo; + +import com.iailab.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 磁盘监控日志 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MonitorDiskReqVO extends PageParam { + + @Schema(description = "主机名称", example = "iailab") + private String hostName; + + @Schema(description = "服务器ip") + private String hostIp; + + @Schema(description = "盘符") + private String disk; + + @Schema(description = "磁盘名", example = "王五") + private String diskName; + + @Schema(description = "总空间") + private BigDecimal spaceTotal; + + @Schema(description = "已用空间") + private BigDecimal spaceUsed; + + @Schema(description = "可用空间") + private BigDecimal spaceUsable; + + @Schema(description = "空间使用比例") + private BigDecimal spaceRatio; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskRespVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskRespVO.java new file mode 100644 index 0000000..94b8efe --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskRespVO.java @@ -0,0 +1,57 @@ +package com.iailab.module.infra.controller.admin.monitordisk.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import java.math.BigDecimal; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 磁盘监控日志 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MonitorDiskRespVO { + + @Schema(description = "访问ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "528") + @ExcelProperty("访问ID") + private Long id; + + @Schema(description = "主机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "iailab") + @ExcelProperty("主机名称") + private String hostName; + + @Schema(description = "服务器ip", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("服务器ip") + private String hostIp; + + @Schema(description = "盘符") + @ExcelProperty("盘符") + private String disk; + + @Schema(description = "磁盘名", example = "王五") + @ExcelProperty("磁盘名") + private String diskName; + + @Schema(description = "总空间") + @ExcelProperty("总空间") + private BigDecimal spaceTotal; + + @Schema(description = "已用空间") + @ExcelProperty("已用空间") + private BigDecimal spaceUsed; + + @Schema(description = "可用空间") + @ExcelProperty("可用空间") + private BigDecimal spaceUsable; + + @Schema(description = "空间使用比例") + @ExcelProperty("空间使用比例") + private BigDecimal spaceRatio; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskSaveReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskSaveReqVO.java new file mode 100644 index 0000000..303ef59 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitordisk/vo/MonitorDiskSaveReqVO.java @@ -0,0 +1,41 @@ +package com.iailab.module.infra.controller.admin.monitordisk.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 磁盘监控日志新增/修改 Request VO") +@Data +public class MonitorDiskSaveReqVO { + + @Schema(description = "访问ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "528") + private Long id; + + @Schema(description = "主机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "iailab") + @NotEmpty(message = "主机名称不能为空") + private String hostName; + + @Schema(description = "服务器ip", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "服务器ip不能为空") + private String hostIp; + + @Schema(description = "盘符") + private String disk; + + @Schema(description = "磁盘名", example = "王五") + private String diskName; + + @Schema(description = "总空间") + private BigDecimal spaceTotal; + + @Schema(description = "已用空间") + private BigDecimal spaceUsed; + + @Schema(description = "可用空间") + private BigDecimal spaceUsable; + + @Schema(description = "空间使用比例") + private BigDecimal spaceRatio; +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/MonitorMemController.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/MonitorMemController.java new file mode 100644 index 0000000..6681062 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/MonitorMemController.java @@ -0,0 +1,126 @@ +package com.iailab.module.infra.controller.admin.monitormem; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import com.iailab.framework.common.pojo.PageParam; +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.framework.common.util.object.BeanUtils; +import static com.iailab.framework.common.pojo.CommonResult.success; + +import com.iailab.framework.excel.core.util.ExcelUtils; + +import com.iailab.framework.apilog.core.annotation.ApiAccessLog; +import static com.iailab.framework.apilog.core.enums.OperateTypeEnum.*; + +import com.iailab.module.infra.controller.admin.monitormem.vo.*; +import com.iailab.module.infra.dal.dataobject.monitormem.MonitorMemDO; +import com.iailab.module.infra.service.monitormem.MonitorMemService; + +@Tag(name = "管理后台 - 内存监控日志") +@RestController +@RequestMapping("/infra/monitor-mem") +@Validated +public class MonitorMemController { + + @Resource + private MonitorMemService monitorMemService; + + @PostMapping("/create") + @Operation(summary = "创建内存监控日志") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:create')") + public CommonResult<Long> createMonitorMem(@Valid @RequestBody MonitorMemSaveReqVO createReqVO) { + return success(monitorMemService.createMonitorMem(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新内存监控日志") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:update')") + public CommonResult<Boolean> updateMonitorMem(@Valid @RequestBody MonitorMemSaveReqVO updateReqVO) { + monitorMemService.updateMonitorMem(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除内存监控日志") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:delete')") + public CommonResult<Boolean> deleteMonitorMem(@RequestParam("id") Long id) { + monitorMemService.deleteMonitorMem(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得内存监控日志") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<MonitorMemRespVO> getMonitorMem(@RequestParam("id") Long id) { + MonitorMemDO monitorMem = monitorMemService.getMonitorMem(id); + return success(BeanUtils.toBean(monitorMem, MonitorMemRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得内存监控日志分页") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<PageResult<MonitorMemRespVO>> getMonitorMemPage(@Valid MonitorMemPageReqVO pageReqVO) { + PageResult<MonitorMemDO> pageResult = monitorMemService.getMonitorMemPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, MonitorMemRespVO.class)); + } + + @GetMapping("/getMonitorMemList") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<List<MonitorMemDO>> getMonitorMemList(@Valid MonitorMemReqVO reqVO) { + List<MonitorMemDO> result = monitorMemService.getMonitorMemList(reqVO); + return success(result); + } + + @GetMapping("/getAllHost") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<List<String>> getAllHost() { + List<String> hosts = monitorMemService.getAllHost(); + return success(hosts); + } + + @GetMapping("/getAllServer") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<List<String>> getAllServer() { + List<String> servers = monitorMemService.getAllServer(); + return success(servers); + } + + @GetMapping("/getAllIp") + @Operation(summary = "获得内存监控日志统计") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:query')") + public CommonResult<List<String>> getAllIp() { + List<String> ips = monitorMemService.getAllIp(); + return success(ips); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出内存监控日志 Excel") + @PreAuthorize("@ss.hasPermission('infra:monitor-mem:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportMonitorMemExcel(@Valid MonitorMemPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List<MonitorMemDO> list = monitorMemService.getMonitorMemPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "内存监控日志.xls", "数据", MonitorMemRespVO.class, + BeanUtils.toBean(list, MonitorMemRespVO.class)); + } + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemPageReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemPageReqVO.java new file mode 100644 index 0000000..5e341d0 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemPageReqVO.java @@ -0,0 +1,59 @@ +package com.iailab.module.infra.controller.admin.monitormem.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import com.iailab.framework.common.pojo.PageParam; +import java.math.BigDecimal; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 内存监控日志分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MonitorMemPageReqVO extends PageParam { + + @Schema(description = "主机名称", example = "张三") + private String hostName; + + @Schema(description = "服务器ip") + private String hostIp; + + @Schema(description = "服务名", example = "王五") + private String serverName; + + @Schema(description = "总物理内存") + private BigDecimal physicalTotal; + + @Schema(description = "已用物理内存") + private BigDecimal physicalUsed; + + @Schema(description = "剩余物理内存") + private BigDecimal physicalFree; + + @Schema(description = "物理内存使用率") + private BigDecimal physicalUsage; + + @Schema(description = "jvm运行总内存") + private BigDecimal runtimeTotal; + + @Schema(description = "jvm最大内存") + private BigDecimal runtimeMax; + + @Schema(description = "jvm已用内存") + private BigDecimal runtimeUsed; + + @Schema(description = "jvm空闲内存") + private BigDecimal runtimeFree; + + @Schema(description = "jvm内存使用率") + private BigDecimal runtimeUsage; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemReqVO.java new file mode 100644 index 0000000..de75baa --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemReqVO.java @@ -0,0 +1,58 @@ +package com.iailab.module.infra.controller.admin.monitormem.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 查询内存监控日志 Request VO") +@Data +@ToString(callSuper = true) +public class MonitorMemReqVO { + + @Schema(description = "主机名称", example = "张三") + private String hostName; + + @Schema(description = "服务器ip") + private String hostIp; + + @Schema(description = "服务名", example = "王五") + private String serverName; + + @Schema(description = "总物理内存") + private BigDecimal physicalTotal; + + @Schema(description = "已用物理内存") + private BigDecimal physicalUsed; + + @Schema(description = "剩余物理内存") + private BigDecimal physicalFree; + + @Schema(description = "物理内存使用率") + private BigDecimal physicalUsage; + + @Schema(description = "jvm运行总内存") + private BigDecimal runtimeTotal; + + @Schema(description = "jvm最大内存") + private BigDecimal runtimeMax; + + @Schema(description = "jvm已用内存") + private BigDecimal runtimeUsed; + + @Schema(description = "jvm空闲内存") + private BigDecimal runtimeFree; + + @Schema(description = "jvm内存使用率") + private BigDecimal runtimeUsage; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemRespVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemRespVO.java new file mode 100644 index 0000000..66fe20c --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemRespVO.java @@ -0,0 +1,81 @@ +package com.iailab.module.infra.controller.admin.monitormem.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import java.math.BigDecimal; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 内存监控日志 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MonitorMemRespVO { + + @Schema(description = "访问ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8051") + @ExcelProperty("访问ID") + private Long id; + + @Schema(description = "主机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") + @ExcelProperty("主机名称") + private String hostName; + + @Schema(description = "服务器ip", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("服务器ip") + private String hostIp; + + @Schema(description = "服务名", example = "王五") + @ExcelProperty("服务名") + private String serverName; + + @Schema(description = "总物理内存") + @ExcelProperty("总物理内存") + private BigDecimal physicalTotal; + + @Schema(description = "已用物理内存") + @ExcelProperty("已用物理内存") + private BigDecimal physicalUsed; + + @Schema(description = "剩余物理内存") + @ExcelProperty("剩余物理内存") + private BigDecimal physicalFree; + + @Schema(description = "物理内存使用率") + @ExcelProperty("物理内存使用率") + private BigDecimal physicalUsage; + + @Schema(description = "jvm运行总内存") + @ExcelProperty("jvm运行总内存") + private BigDecimal runtimeTotal; + + @Schema(description = "jvm最大内存") + @ExcelProperty("jvm最大内存") + private BigDecimal runtimeMax; + + @Schema(description = "jvm已用内存") + @ExcelProperty("jvm已用内存") + private BigDecimal runtimeUsed; + + @Schema(description = "jvm空闲内存") + @ExcelProperty("jvm空闲内存") + private BigDecimal runtimeFree; + + @Schema(description = "jvm内存使用率") + @ExcelProperty("jvm内存使用率") + private BigDecimal runtimeUsage; + + @Schema(description = "系统cpu利用率") + @ExcelProperty("系统cpu利用率") + private BigDecimal systemCpuLoad; + + @Schema(description = "进程cpu利用率") + @ExcelProperty("进程cpu利用率") + private BigDecimal processCpuLoad; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemSaveReqVO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemSaveReqVO.java new file mode 100644 index 0000000..b08f583 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/controller/admin/monitormem/vo/MonitorMemSaveReqVO.java @@ -0,0 +1,60 @@ +package com.iailab.module.infra.controller.admin.monitormem.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 内存监控日志新增/修改 Request VO") +@Data +public class MonitorMemSaveReqVO { + + @Schema(description = "访问ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8051") + private Long id; + + @Schema(description = "主机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") + @NotEmpty(message = "主机名称不能为空") + private String hostName; + + @Schema(description = "服务器ip", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "服务器ip不能为空") + private String hostIp; + + @Schema(description = "服务名", example = "王五") + private String serverName; + + @Schema(description = "总物理内存") + private BigDecimal physicalTotal; + + @Schema(description = "已用物理内存") + private BigDecimal physicalUsed; + + @Schema(description = "剩余物理内存") + private BigDecimal physicalFree; + + @Schema(description = "物理内存使用率") + private BigDecimal physicalUsage; + + @Schema(description = "jvm运行总内存") + private BigDecimal runtimeTotal; + + @Schema(description = "jvm最大内存") + private BigDecimal runtimeMax; + + @Schema(description = "jvm已用内存") + private BigDecimal runtimeUsed; + + @Schema(description = "jvm空闲内存") + private BigDecimal runtimeFree; + + @Schema(description = "jvm内存使用率") + private BigDecimal runtimeUsage; + + @Schema(description = "系统cpu利用率") + private BigDecimal systemCpuLoad; + + @Schema(description = "进程cpu利用率") + private BigDecimal processCpuLoad; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitordisk/MonitorDiskDO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitordisk/MonitorDiskDO.java new file mode 100644 index 0000000..0321f55 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitordisk/MonitorDiskDO.java @@ -0,0 +1,72 @@ +package com.iailab.module.infra.dal.dataobject.monitordisk; + +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import com.iailab.framework.mybatis.core.dataobject.BaseDO; + +/** + * 磁盘监控日志 DO + * + * @author 超级管理员 + */ +@TableName("system_monitor_disk") +@KeySequence("system_monitor_disk_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MonitorDiskDO extends BaseDO { + + /** + * 访问ID + */ + @TableId + private Long id; + /** + * 主机名称 + */ + private String hostName; + /** + * 服务器ip + */ + private String hostIp; + /** + * 盘符 + */ + private String disk; + /** + * 磁盘名 + */ + private String diskName; + /** + * 总空间 + */ + private BigDecimal spaceTotal; + /** + * 已用空间 + */ + private BigDecimal spaceUsed; + /** + * 可用空间 + */ + private BigDecimal spaceUsable; + /** + * 空间使用比例 + */ + private BigDecimal spaceRatio; + + /** + * 租户Id + */ + private Integer tenantId; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitormem/MonitorMemDO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitormem/MonitorMemDO.java new file mode 100644 index 0000000..e2369d6 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/monitormem/MonitorMemDO.java @@ -0,0 +1,103 @@ +package com.iailab.module.infra.dal.dataobject.monitormem; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import com.iailab.framework.mybatis.core.dataobject.BaseDO; + +/** + * 内存监控日志 DO + * + * @author 超级管理员 + */ +@TableName("system_monitor_mem") +@KeySequence("system_monitor_mem_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MonitorMemDO extends BaseDO { + + /** + * 访问ID + */ + @TableId + private Long id; + /** + * 主机名称 + */ + private String hostName; + /** + * 服务器ip + */ + private String hostIp; + /** + * 服务名 + */ + private String serverName; + /** + * 总物理内存 + */ + private BigDecimal physicalTotal; + /** + * 已用物理内存 + */ + private BigDecimal physicalUsed; + /** + * 剩余物理内存 + */ + private BigDecimal physicalFree; + /** + * 物理内存使用率 + */ + private BigDecimal physicalUsage; + /** + * jvm运行总内存 + */ + private BigDecimal runtimeTotal; + /** + * jvm最大内存 + */ + private BigDecimal runtimeMax; + /** + * jvm已用内存 + */ + private BigDecimal runtimeUsed; + /** + * jvm空闲内存 + */ + private BigDecimal runtimeFree; + /** + * jvm内存使用率 + */ + private BigDecimal runtimeUsage; + /** + * 系统cpu利用率 + */ + private BigDecimal systemCpuLoad; + /** + * 进程cpu利用率 + */ + private BigDecimal processCpuLoad; + + /** + * 租户Id + */ + private Integer tenantId; + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitordisk/MonitorDiskMapper.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitordisk/MonitorDiskMapper.java new file mode 100644 index 0000000..5cb6ef6 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitordisk/MonitorDiskMapper.java @@ -0,0 +1,46 @@ +package com.iailab.module.infra.dal.mysql.monitordisk; + +import java.util.*; + +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.iailab.framework.mybatis.core.mapper.BaseMapperX; +import com.iailab.module.infra.dal.dataobject.monitordisk.MonitorDiskDO; +import org.apache.ibatis.annotations.Mapper; +import com.iailab.module.infra.controller.admin.monitordisk.vo.*; +import org.apache.ibatis.annotations.Param; + +/** + * 磁盘监控日志 Mapper + * + * @author 超级管理员 + */ +@Mapper +public interface MonitorDiskMapper extends BaseMapperX<MonitorDiskDO> { + + default PageResult<MonitorDiskDO> selectPage(MonitorDiskPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDiskDO>() + .likeIfPresent(MonitorDiskDO::getHostName, reqVO.getHostName()) + .eqIfPresent(MonitorDiskDO::getHostIp, reqVO.getHostIp()) + .eqIfPresent(MonitorDiskDO::getDisk, reqVO.getDisk()) + .likeIfPresent(MonitorDiskDO::getDiskName, reqVO.getDiskName()) + .eqIfPresent(MonitorDiskDO::getSpaceTotal, reqVO.getSpaceTotal()) + .eqIfPresent(MonitorDiskDO::getSpaceUsed, reqVO.getSpaceUsed()) + .eqIfPresent(MonitorDiskDO::getSpaceUsable, reqVO.getSpaceUsable()) + .eqIfPresent(MonitorDiskDO::getSpaceRatio, reqVO.getSpaceRatio()) + .betweenIfPresent(MonitorDiskDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(MonitorDiskDO::getId)); + } + + default List<MonitorDiskDO> getMonitorDiskList(MonitorDiskReqVO reqVO) { + return selectList(new LambdaQueryWrapperX<MonitorDiskDO>() + .likeIfPresent(MonitorDiskDO::getHostName, reqVO.getHostName()) + .eqIfPresent(MonitorDiskDO::getHostIp, reqVO.getHostIp()) + .eqIfPresent(MonitorDiskDO::getDisk, reqVO.getDisk()) + .likeIfPresent(MonitorDiskDO::getDiskName, reqVO.getDiskName()) + .betweenIfPresent(MonitorDiskDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(MonitorDiskDO::getCreateTime)); + } + + List<MonitorDiskDO> getMonitorDiskInfo(@Param("params") MonitorDiskReqVO reqVO); +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitormem/MonitorMemMapper.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitormem/MonitorMemMapper.java new file mode 100644 index 0000000..905ddef --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/mysql/monitormem/MonitorMemMapper.java @@ -0,0 +1,47 @@ +package com.iailab.module.infra.dal.mysql.monitormem; + +import java.util.*; + +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.iailab.framework.mybatis.core.mapper.BaseMapperX; +import com.iailab.module.infra.dal.dataobject.monitormem.MonitorMemDO; +import org.apache.ibatis.annotations.Mapper; +import com.iailab.module.infra.controller.admin.monitormem.vo.*; + +/** + * 内存监控日志 Mapper + * + * @author 超级管理员 + */ +@Mapper +public interface MonitorMemMapper extends BaseMapperX<MonitorMemDO> { + + default PageResult<MonitorMemDO> selectPage(MonitorMemPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX<MonitorMemDO>() + .likeIfPresent(MonitorMemDO::getHostName, reqVO.getHostName()) + .eqIfPresent(MonitorMemDO::getHostIp, reqVO.getHostIp()) + .likeIfPresent(MonitorMemDO::getServerName, reqVO.getServerName()) + .eqIfPresent(MonitorMemDO::getPhysicalTotal, reqVO.getPhysicalTotal()) + .eqIfPresent(MonitorMemDO::getPhysicalUsed, reqVO.getPhysicalUsed()) + .eqIfPresent(MonitorMemDO::getPhysicalFree, reqVO.getPhysicalFree()) + .eqIfPresent(MonitorMemDO::getPhysicalUsage, reqVO.getPhysicalUsage()) + .eqIfPresent(MonitorMemDO::getRuntimeTotal, reqVO.getRuntimeTotal()) + .eqIfPresent(MonitorMemDO::getRuntimeMax, reqVO.getRuntimeMax()) + .eqIfPresent(MonitorMemDO::getRuntimeUsed, reqVO.getRuntimeUsed()) + .eqIfPresent(MonitorMemDO::getRuntimeFree, reqVO.getRuntimeFree()) + .eqIfPresent(MonitorMemDO::getRuntimeUsage, reqVO.getRuntimeUsage()) + .betweenIfPresent(MonitorMemDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(MonitorMemDO::getId)); + } + + default List<MonitorMemDO> getMonitorMemList(MonitorMemReqVO reqVO) { + return selectList(new LambdaQueryWrapperX<MonitorMemDO>() + .likeIfPresent(MonitorMemDO::getHostName, reqVO.getHostName()) + .eqIfPresent(MonitorMemDO::getHostIp, reqVO.getHostIp()) + .likeIfPresent(MonitorMemDO::getServerName, reqVO.getServerName()) + .betweenIfPresent(MonitorMemDO::getCreateTime, reqVO.getCreateTime()) + .orderByAsc(MonitorMemDO::getCreateTime)); + } + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorDiskJob.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorDiskJob.java new file mode 100644 index 0000000..b679851 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorDiskJob.java @@ -0,0 +1,47 @@ +//package com.iailab.module.infra.job.monitor; +// +//import com.iailab.framework.tenant.core.aop.TenantIgnore; +//import com.iailab.module.infra.api.monitor.MonitorApi; +//import com.iailab.module.infra.api.monitor.dto.MonitorDiskDTO; +//import com.iailab.module.infra.util.ServerInfoCollector; +//import com.xxl.job.core.handler.annotation.XxlJob; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.io.IOException; +//import java.util.Date; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicInteger; +// +//@Component +//public class MonitorDiskJob { +// +// private Logger logger = LoggerFactory.getLogger(getClass()); +// +// private final AtomicInteger counts = new AtomicInteger(); +// +// private static final Object lock = new Object(); +// +// private final MonitorApi monitorApi; +// +// +// public MonitorDiskJob(MonitorApi monitorApi) { +// this.monitorApi = monitorApi; +// } +// +// @XxlJob("monitorDiskJob") +// @TenantIgnore +// @Transactional +// public void execute() throws IOException { +// synchronized (lock) { +// logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); +// System.out.println(new Date() + ": 我是基础设施-服务器磁盘监控日志存储定时任务"); +// List<MonitorDiskDTO> monitorDiskDTOS = ServerInfoCollector.collectMonitorDisk(); +// monitorApi.reportDiskInfo(monitorDiskDTOS); +// } +// } +// +//} diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorMemJob.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorMemJob.java new file mode 100644 index 0000000..30b77f4 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/monitor/MonitorMemJob.java @@ -0,0 +1,50 @@ +//package com.iailab.module.infra.job.monitor; +// +//import com.iailab.framework.tenant.core.aop.TenantIgnore; +//import com.iailab.module.infra.api.monitor.MonitorApi; +//import com.iailab.module.infra.api.monitor.dto.MonitorMemDTO; +//import com.iailab.module.infra.util.ServerInfoCollector; +//import com.xxl.job.core.handler.annotation.XxlJob; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.io.IOException; +//import java.util.Date; +//import java.util.concurrent.atomic.AtomicInteger; +// +//@Component +//public class MonitorMemJob { +// +// private Logger logger = LoggerFactory.getLogger(getClass()); +// +// private final AtomicInteger counts = new AtomicInteger(); +// +// private static final Object lock = new Object(); +// +// private final MonitorApi monitorApi; +// +// @Value("${spring.application.name}") +// public String serverName; +// +// public MonitorMemJob(MonitorApi monitorApi) { +// this.monitorApi = monitorApi; +// } +// +// @XxlJob("monitorMemJob") +// @TenantIgnore +// @Transactional +// public void execute() throws IOException { +// synchronized (lock) { +// logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); +// System.out.println(new Date() + ": 我是基础设施-服务器内存监控日志存储定时任务"); +// MonitorMemDTO monitorMemDTO = ServerInfoCollector.collectMonitorMem(serverName); +// monitorApi.reportMemInfo(monitorMemDTO); +// } +// } +// +// +// +//} diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskService.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskService.java new file mode 100644 index 0000000..48d1e5f --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskService.java @@ -0,0 +1,94 @@ +package com.iailab.module.infra.service.monitordisk; + +import java.time.LocalDateTime; +import java.util.*; +import javax.validation.*; +import com.iailab.module.infra.controller.admin.monitordisk.vo.*; +import com.iailab.module.infra.dal.dataobject.monitordisk.MonitorDiskDO; +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.common.pojo.PageParam; + +/** + * 磁盘监控日志 Service 接口 + * + * @author 超级管理员 + */ +public interface MonitorDiskService { + + /** + * 创建磁盘监控日志 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMonitorDisk(@Valid MonitorDiskSaveReqVO createReqVO); + + /** + * 批量创建磁盘监控日志 + * + * @param createReqVOS 创建信息 + * @return 编号 + */ + void createMonitorDiskBatch(List<MonitorDiskSaveReqVO> createReqVOS); + + /** + * 更新磁盘监控日志 + * + * @param updateReqVO 更新信息 + */ + void updateMonitorDisk(@Valid MonitorDiskSaveReqVO updateReqVO); + + /** + * 删除磁盘监控日志 + * + * @param id 编号 + */ + void deleteMonitorDisk(Long id); + + /** + * 获得磁盘监控日志 + * + * @param id 编号 + * @return 磁盘监控日志 + */ + MonitorDiskDO getMonitorDisk(Long id); + + /** + * 获得磁盘监控日志分页 + * + * @param pageReqVO 分页查询 + * @return 磁盘监控日志分页 + */ + PageResult<MonitorDiskDO> getMonitorDiskPage(MonitorDiskPageReqVO pageReqVO); + + /** + * 获得磁盘监控日志列表 + * + * @param reqVO 查询 + * @return 磁盘监控日志列表 + */ + List<Map<String, List<Map<String, Object>>>> getMonitorDiskList(MonitorDiskReqVO reqVO); + + /** + * 获得磁盘监控日志信息 + * + * @param reqVO 查询 + * @return 磁盘监控日志信息 + */ + List<Map<String, Object>> getMonitorDiskInfo(MonitorDiskReqVO reqVO); + + /** + * 获取所有主机 + * + * @return 获取所有主机 + */ + List<String> getAllHost(); + + /** + * 获取所有ip + * + * @return 获取所有ip + */ + List<String> getAllIp(); + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskServiceImpl.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskServiceImpl.java new file mode 100644 index 0000000..a6e8a61 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitordisk/MonitorDiskServiceImpl.java @@ -0,0 +1,180 @@ +package com.iailab.module.infra.service.monitordisk; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.iailab.framework.tenant.core.aop.TenantIgnore; +import com.iailab.module.infra.dal.dataobject.monitormem.MonitorMemDO; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import com.iailab.module.infra.controller.admin.monitordisk.vo.*; +import com.iailab.module.infra.dal.dataobject.monitordisk.MonitorDiskDO; +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.common.util.object.BeanUtils; + +import com.iailab.module.infra.dal.mysql.monitordisk.MonitorDiskMapper; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.iailab.module.infra.enums.ErrorCodeConstants.*; + +/** + * 磁盘监控日志 Service 实现类 + * + * @author 超级管理员 + */ +@Service +@Validated +public class MonitorDiskServiceImpl implements MonitorDiskService { + + @Resource + private MonitorDiskMapper monitorDiskMapper; + + @Override + public Long createMonitorDisk(MonitorDiskSaveReqVO createReqVO) { + // 插入 + MonitorDiskDO monitorDisk = BeanUtils.toBean(createReqVO, MonitorDiskDO.class); + monitorDiskMapper.insert(monitorDisk); + // 返回 + return monitorDisk.getId(); + } + + @Override + public void createMonitorDiskBatch(List<MonitorDiskSaveReqVO> createReqVOS) { + // 插入 + List<MonitorDiskDO> monitorDiskDOS = BeanUtils.toBean(createReqVOS, MonitorDiskDO.class); + monitorDiskDOS.stream().forEach(monitorDiskDO -> { + monitorDiskDO.setTenantId(1); + monitorDiskDO.setCreator("iailab"); + }); + monitorDiskMapper.insertBatch(monitorDiskDOS); + } + + @Override + public void updateMonitorDisk(MonitorDiskSaveReqVO updateReqVO) { + // 校验存在 + validateMonitorDiskExists(updateReqVO.getId()); + // 更新 + MonitorDiskDO updateObj = BeanUtils.toBean(updateReqVO, MonitorDiskDO.class); + monitorDiskMapper.updateById(updateObj); + } + + @Override + public void deleteMonitorDisk(Long id) { + // 校验存在 + validateMonitorDiskExists(id); + // 删除 + monitorDiskMapper.deleteById(id); + } + + private void validateMonitorDiskExists(Long id) { + if (monitorDiskMapper.selectById(id) == null) { + throw exception(MONITOR_DISK_NOT_EXISTS); + } + } + + @Override + public MonitorDiskDO getMonitorDisk(Long id) { + return monitorDiskMapper.selectById(id); + } + + @Override + public PageResult<MonitorDiskDO> getMonitorDiskPage(MonitorDiskPageReqVO pageReqVO) { + return monitorDiskMapper.selectPage(pageReqVO); + } + + /** + * 折线图展示 + * @param reqVO 查询 + * @return + */ + @Override + public List<Map<String, List<Map<String, Object>>>> getMonitorDiskList(MonitorDiskReqVO reqVO) { + List<MonitorDiskDO> monitorDiskList = monitorDiskMapper.getMonitorDiskList(reqVO); + if(ObjectUtils.isNotEmpty(monitorDiskList)) { + // 根据 hostName 字段进行分组 + Map<String, List<MonitorDiskDO>> hostNameCollect = monitorDiskList.stream() + .collect(Collectors.groupingBy(MonitorDiskDO::getHostName)); + List<Map<String, List<Map<String, Object>>>> host = hostNameCollect.entrySet().stream().map(hostEntry -> { + List<MonitorDiskDO> hostValue = hostEntry.getValue(); + String key = hostEntry.getKey(); + Map<String, List<Map<String, Object>>> hostItem = new HashMap<>(); + // 根据 createTime 字段进行分组 + Map<LocalDateTime, List<MonitorDiskDO>> createTimeCollect = hostValue.stream() + .collect(Collectors.groupingBy(MonitorDiskDO::getCreateTime)); + List<Map<String, Object>> collect = createTimeCollect.entrySet().stream().map(entry -> { + List<MonitorDiskDO> value = entry.getValue(); + Map<String, Object> item = new HashMap<>(); + value.stream().forEach(monitorDiskDO -> { + item.put("createTime", monitorDiskDO.getCreateTime()); + item.put(monitorDiskDO.getDisk(), monitorDiskDO.getSpaceRatio().multiply(new BigDecimal(100))); + }); + return item; + }).collect(Collectors.toList()); + hostItem.put(key, collect); + return hostItem; + }).collect(Collectors.toList()); + return host; + } + return null; + } + + /** + * 饼图展示 + * @param reqVO 查询 + * @return + */ + @Override + @TenantIgnore + public List<Map<String, Object>> getMonitorDiskInfo(MonitorDiskReqVO reqVO) { + List<MonitorDiskDO> monitorDiskInfo = monitorDiskMapper.getMonitorDiskInfo(reqVO); + if(ObjectUtils.isNotEmpty(monitorDiskInfo)) { + // 根据 hostName 字段进行分组 + Map<String, List<MonitorDiskDO>> hostNameCollect = monitorDiskInfo.stream() + .collect(Collectors.groupingBy(MonitorDiskDO::getHostName)); + List<Map<String, Object>> collect = hostNameCollect.entrySet().stream().map(entry -> { + List<MonitorDiskDO> value = entry.getValue(); + Map<String, Object> item = new HashMap<>(); + List<Map<String, Object>> disks = new ArrayList<>(); + value.stream().forEach(monitorDiskDO -> { + Map<String, Object> diskMap = new HashMap<>(); + item.put("name", monitorDiskDO.getHostName()); + item.put("ip", monitorDiskDO.getHostIp()); + diskMap.put("disk", monitorDiskDO.getDisk()); + diskMap.put("total", monitorDiskDO.getSpaceTotal().divide(new BigDecimal(1024)).setScale(3, BigDecimal.ROUND_HALF_UP).toString()); + diskMap.put("used", monitorDiskDO.getSpaceUsed().divide(new BigDecimal(1024)).setScale(2, BigDecimal.ROUND_HALF_UP)); + disks.add(diskMap); + }); + item.put("disks", disks); + return item; + }).collect(Collectors.toList()); + return collect; + } + return null; + } + + @Override + public List<String> getAllHost() { + QueryWrapper<MonitorDiskDO> queryWrapper = new QueryWrapper<>(); + queryWrapper.select("DISTINCT host_name"); // 添加 DISTINCT 修饰 + List<String> hosts = monitorDiskMapper.selectObjs(queryWrapper); + return hosts; + } + + @Override + public List<String> getAllIp() { + QueryWrapper<MonitorDiskDO> queryWrapper = new QueryWrapper<>(); + queryWrapper.select("DISTINCT host_ip"); // 添加 DISTINCT 修饰 + List<String> ips = monitorDiskMapper.selectObjs(queryWrapper); + return ips; + } + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemService.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemService.java new file mode 100644 index 0000000..afc302c --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemService.java @@ -0,0 +1,83 @@ +package com.iailab.module.infra.service.monitormem; + +import java.util.*; +import javax.validation.*; +import com.iailab.module.infra.controller.admin.monitormem.vo.*; +import com.iailab.module.infra.dal.dataobject.monitormem.MonitorMemDO; +import com.iailab.framework.common.pojo.PageResult; + +/** + * 内存监控日志 Service 接口 + * + * @author 超级管理员 + */ +public interface MonitorMemService { + + /** + * 创建内存监控日志 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMonitorMem(@Valid MonitorMemSaveReqVO createReqVO); + + /** + * 更新内存监控日志 + * + * @param updateReqVO 更新信息 + */ + void updateMonitorMem(@Valid MonitorMemSaveReqVO updateReqVO); + + /** + * 删除内存监控日志 + * + * @param id 编号 + */ + void deleteMonitorMem(Long id); + + /** + * 获得内存监控日志 + * + * @param id 编号 + * @return 内存监控日志 + */ + MonitorMemDO getMonitorMem(Long id); + + /** + * 获得内存监控日志分页 + * + * @param pageReqVO 分页查询 + * @return 内存监控日志分页 + */ + PageResult<MonitorMemDO> getMonitorMemPage(MonitorMemPageReqVO pageReqVO); + + /** + * 获得内存监控日志 + * + * @param pageReqVO 查询 + * @return 内存监控日志 + */ + List<MonitorMemDO> getMonitorMemList(MonitorMemReqVO pageReqVO); + + /** + * 获取所有主机 + * + * @return 获取所有主机 + */ + List<String> getAllHost(); + + /** + * 获取所有服务 + * + * @return 获取所有服务 + */ + List<String> getAllServer(); + + /** + * 获取所有ip + * + * @return 获取所有ip + */ + List<String> getAllIp(); + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemServiceImpl.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemServiceImpl.java new file mode 100644 index 0000000..1314d49 --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/monitormem/MonitorMemServiceImpl.java @@ -0,0 +1,108 @@ +package com.iailab.module.infra.service.monitormem; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import com.iailab.module.infra.controller.admin.monitormem.vo.*; +import com.iailab.module.infra.dal.dataobject.monitormem.MonitorMemDO; +import com.iailab.framework.common.pojo.PageResult; +import com.iailab.framework.common.util.object.BeanUtils; + +import com.iailab.module.infra.dal.mysql.monitormem.MonitorMemMapper; + +import java.util.Collections; +import java.util.List; + +import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.iailab.module.infra.enums.ErrorCodeConstants.*; + +/** + * 内存监控日志 Service 实现类 + * + * @author 超级管理员 + */ +@Service +@Validated +public class MonitorMemServiceImpl implements MonitorMemService { + + @Resource + private MonitorMemMapper monitorMemMapper; + + @Override + public Long createMonitorMem(MonitorMemSaveReqVO createReqVO) { + // 插入 + MonitorMemDO monitorMem = BeanUtils.toBean(createReqVO, MonitorMemDO.class); + monitorMem.setCreator("iailab"); + monitorMem.setTenantId(1); + monitorMemMapper.insert(monitorMem); + // 返回 + return monitorMem.getId(); + } + + @Override + public void updateMonitorMem(MonitorMemSaveReqVO updateReqVO) { + // 校验存在 + validateMonitorMemExists(updateReqVO.getId()); + // 更新 + MonitorMemDO updateObj = BeanUtils.toBean(updateReqVO, MonitorMemDO.class); + updateObj.setUpdater("iailab"); + monitorMemMapper.updateById(updateObj); + } + + @Override + public void deleteMonitorMem(Long id) { + // 校验存在 + validateMonitorMemExists(id); + // 删除 + monitorMemMapper.deleteById(id); + } + + private void validateMonitorMemExists(Long id) { + if (monitorMemMapper.selectById(id) == null) { + throw exception(MONITOR_MEM_NOT_EXISTS); + } + } + + @Override + public MonitorMemDO getMonitorMem(Long id) { + return monitorMemMapper.selectById(id); + } + + @Override + public PageResult<MonitorMemDO> getMonitorMemPage(MonitorMemPageReqVO pageReqVO) { + return monitorMemMapper.selectPage(pageReqVO); + } + + @Override + public List<MonitorMemDO> getMonitorMemList(MonitorMemReqVO reqVO) { + return monitorMemMapper.getMonitorMemList(reqVO); + } + + @Override + public List<String> getAllHost() { + QueryWrapper<MonitorMemDO> queryWrapper = new QueryWrapper<>(); + queryWrapper.select("DISTINCT host_name"); // 添加 DISTINCT 修饰 + List<String> hosts = monitorMemMapper.selectObjs(queryWrapper); + return hosts; + } + + @Override + public List<String> getAllServer() { + QueryWrapper<MonitorMemDO> queryWrapper = new QueryWrapper<>(); + queryWrapper.select("DISTINCT server_name"); // 添加 DISTINCT 修饰 + List<String> servers = monitorMemMapper.selectObjs(queryWrapper); + return servers; + } + + @Override + public List<String> getAllIp() { + QueryWrapper<MonitorMemDO> queryWrapper = new QueryWrapper<>(); + queryWrapper.select("DISTINCT host_ip"); // 添加 DISTINCT 修饰 + List<String> ips = monitorMemMapper.selectObjs(queryWrapper); + return ips; + } + +} \ No newline at end of file diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-dev.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-dev.yaml index f00ba68..179b067 100644 --- a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-dev.yaml +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-dev.yaml @@ -64,7 +64,7 @@ # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: - host: 172.16.8.100 # 地址 + host: 127.0.0.1 # 地址 port: 6379 # 端口 database: 0 # 数据库索引 password: 123456 # 密码,建议生产环境开启 @@ -78,7 +78,7 @@ spring: # RabbitMQ 配置项,对应 RabbitProperties 配置类 rabbitmq: - host: 172.16.8.200 # RabbitMQ 服务的地址 + host: 172.16.1.221 # RabbitMQ 服务的地址 port: 5672 # RabbitMQ 服务的端口 username: admin # RabbitMQ 服务的账号 password: admin123 # RabbitMQ 服务的密码 diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-prod.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..b5085eb --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-prod.yaml @@ -0,0 +1,150 @@ +--- #################### 数据库相关配置 #################### +spring: + + # 数据源配置项 + autoconfigure: + exclude: + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 + # - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置 + # - de.codecentric.boot.admin.server.cloud.config.AdminServerDiscoveryAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置 + # - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置 + # - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置 + datasource: + druid: # Druid 【监控】相关的全局配置 + web-stat-filter: + enabled: true + stat-view-servlet: + enabled: true + allow: # 设置白名单,不填则允许所有访问 + url-pattern: /druid/* + login-username: # 控制台管理用户名和密码 + login-password: + filter: + stat: + enabled: true + log-slow-sql: true # 慢 SQL 记录 + slow-sql-millis: 100 + merge-sql: true + wall: + config: + multi-statement-allow: true + dynamic: # 多数据源配置 + druid: # Druid 【连接池】相关的全局配置 + initial-size: 1 # 初始连接数 + min-idle: 1 # 最小连接池数量 + max-active: 20 # 最大连接池数量 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 + test-while-idle: true + test-on-borrow: false + test-on-return: false + primary: master + datasource: + master: + url: jdbc:mysql://172.16.8.100:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + # url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例 + # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 + # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 + # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例 + # url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例 + username: root + password: 123456 + # username: sa # SQL Server 连接的示例 + # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例 + # username: SYSDBA # DM 连接的示例 + # password: SYSDBA # DM 连接的示例 + slave: # 模拟从库,可根据自己需要修改 + lazy: true # 开启懒加载,保证启动速度 + url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + username: root + password: 123456 + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 172.16.8.100 # 地址 + port: 6379 # 端口 + database: 0 # 数据库索引 + password: 123456 # 密码,建议生产环境开启 + +--- #################### MQ 消息队列相关配置 #################### + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 172.16.8.100:9876 # RocketMQ Namesrv + +spring: + # RabbitMQ 配置项,对应 RabbitProperties 配置类 + rabbitmq: + host: 172.16.1.221 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: admin # RabbitMQ 服务的账号 + password: admin123 # RabbitMQ 服务的密码 + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 172.16.8.100:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +--- #################### 定时任务相关配置 #################### +xxl: + job: + enabled: true # 是否开启调度中心,默认为 true 开启 + admin: + addresses: http://172.16.216.133:9090/xxl-job-admin # 调度中心部署跟地址 + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项 +lock4j: + acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒 + expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒 + +--- #################### 监控相关配置 #################### + +# Actuator 监控端点的配置项 +management: + endpoints: + web: + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +# Spring Boot Admin 配置项 +spring: + boot: + admin: + # Spring Boot Admin Client 客户端的相关配置 + client: + instance: + service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME] + # Spring Boot Admin Server 服务端的相关配置 + context-path: /admin # 配置 Spring + +# 日志文件配置 +logging: + level: + # 配置自己写的 MyBatis Mapper 打印日志 + com.iailab.module.infra.dal.mysql: debug + com.iailab.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 配置 ApiErrorLogMapper 的日志级别为 info,避免和 GlobalExceptionHandler 重复打印 + com.iailab.module.infra.dal.mysql.file.FileConfigMapper: INFO # 配置 FileConfigMapper 的日志级别为 info + +--- #################### 定时任务相关配置 #################### + +xxl: + job: + executor: + appname: ${spring.application.name} # 执行器 AppName + logpath: D:/DLUT/IailabPlat/webapp/infra/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 + accessToken: default_token # 执行器通讯TOKEN + +--- #################### 平台相关配置 #################### + +# 平台配置项,设置当前项目所有自定义的配置 +iailab: + env: # 多环境的配置项 + tag: ${HOSTNAME} + security: + mock-enable: true + access-log: # 访问日志的配置项 + enable: true diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml index 9ea8ff9..d2c7436 100644 --- a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml @@ -81,8 +81,8 @@ map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 global-config: db-config: - id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。 - # id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库 + #id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。 + id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库 # id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库 # id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解 logic-delete-value: 1 # 逻辑已删除值(默认为 1) diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/mapper/monitordisk/MonitorDiskMapper.xml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/mapper/monitordisk/MonitorDiskMapper.xml new file mode 100644 index 0000000..a6cf1ad --- /dev/null +++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/mapper/monitordisk/MonitorDiskMapper.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + +<mapper namespace="com.iailab.module.infra.dal.mysql.monitordisk.MonitorDiskMapper"> + + <select id="getMonitorDiskInfo" resultType="com.iailab.module.infra.dal.dataobject.monitordisk.MonitorDiskDO"> + WITH RankedData AS ( + SELECT + host_name, + host_ip, + disk, + disk_name, + space_total, + space_used, + create_time, + ROW_NUMBER() OVER (PARTITION BY host_name, disk, disk_name ORDER BY create_time DESC) AS rn + FROM + system_monitor_disk + ) + SELECT + host_name, + host_ip, + disk, + disk_name, + space_total, + space_used + FROM + RankedData + WHERE + rn = 1 + <if test="params.hostName != null and params.hostName != ''"> + and host_name = #{params.hostName} + </if> + <if test="params.hostIp != null and params.hostIp != ''"> + and host_ip = #{params.hostIp} + </if> + <if test="params.createTime != null and params.createTime != ''"> + and create_time between #{params.createTime[0]} and #{params.createTime[1]} + </if> + </select> + +</mapper> \ No newline at end of file diff --git a/iailab-module-model/iailab-module-model-biz/src/main/resources/application-prod.yaml b/iailab-module-model/iailab-module-model-biz/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..442b277 --- /dev/null +++ b/iailab-module-model/iailab-module-model-biz/src/main/resources/application-prod.yaml @@ -0,0 +1,106 @@ +--- #################### db configuration #################### +spring: + autoconfigure: + exclude: + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration + boot: + admin: + client: + instance: + service-host-type: IP + datasource: + druid: + web-stat-filter: + enabled: true + stat-view-servlet: + enabled: true + allow: + url-pattern: /druid/* + login-username: + login-password: + filter: + stat: + enabled: true + log-slow-sql: true + slow-sql-millis: 100 + merge-sql: true + wall: + config: + multi-statement-allow: true + dynamic: + druid: + initial-size: 1 + min-idle: 1 + max-active: 20 + max-wait: 600000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + max-evictable-idle-time-millis: 900000 + validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + primary: master + datasource: + master: + url: jdbc:mysql://172.16.8.100:3306/iailab_expert_master?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + username: root + password: 123456 + redis: + host: 172.16.8.100 + port: 6379 + database: 0 + password: 123456 + +xxl: + job: + enabled: true + admin: + addresses: http://172.16.8.100:9090/xxl-job-admin + +lock4j: + acquire-timeout: 3000 + expire: 30000 + +management: + endpoints: + web: + base-path: /actuator + exposure: + include: '*' + +logging: + level: + com.iailab.module.system.dal.mysql: debug + com.iailab.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO + com.iailab.module.system.dal.mysql.sms.SmsChannelMapper: INFO +iailab: + env: + tag: ${HOSTNAME} + captcha: + enable: false + security: + mock-enable: true + xss: + enable: false + exclude-urls: + - ${spring.boot.admin.context-path}/** + - ${management.endpoints.web.base-path}/** + access-log: + enable: false + demo: false +influx-db: + org: iailab + token: _338h4Kbu2KQaes5QwAyOz9pTUueXoSF9XmPi8N9oTS1SrhTZVj4J9JfSraUyWA0PfWMZOlf9QWax-USkJQR_A== + url: http://172.16.1.221:8086 + username: iailab + password: iailab2019 +iems: + upload-dir: D:/DLUT/upload/ +mpk: + bak-file-path: D:\DLUT\mpkBakFile + bak-resources: D:\DLUT\mpkResources + model-file-path: D:\DLUT\MDK\Model\miail\ +`mablab: + bak-file-path: D:\DLUT\matlabBakFile` \ No newline at end of file diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/permission/DataScopeEnum.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/permission/DataScopeEnum.java index 869265f..25c9747 100644 --- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/permission/DataScopeEnum.java +++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/permission/DataScopeEnum.java @@ -1,6 +1,6 @@ package com.iailab.module.system.enums.permission; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,7 +15,7 @@ */ @Getter @AllArgsConstructor -public enum DataScopeEnum implements IntArrayValuable { +public enum DataScopeEnum implements ArrayValuable { ALL(1), // 全部数据权限 @@ -30,10 +30,10 @@ */ private final Integer scope; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DataScopeEnum::getScope).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(DataScopeEnum::getScope).toArray(Integer[]::new); @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/sms/SmsSceneEnum.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/sms/SmsSceneEnum.java index c2892e9..9eb52db 100644 --- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/sms/SmsSceneEnum.java +++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/sms/SmsSceneEnum.java @@ -1,7 +1,7 @@ package com.iailab.module.system.enums.sms; import cn.hutool.core.util.ArrayUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,7 +14,7 @@ */ @Getter @AllArgsConstructor -public enum SmsSceneEnum implements IntArrayValuable { +public enum SmsSceneEnum implements ArrayValuable { MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"), MEMBER_UPDATE_MOBILE(2, "user-update-mobile", "会员用户 - 修改手机"), @@ -23,7 +23,7 @@ ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"); - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(SmsSceneEnum::getScene).toArray(Integer[]::new); /** * 验证场景的编号 @@ -39,7 +39,7 @@ private final String description; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/social/SocialTypeEnum.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/social/SocialTypeEnum.java index b309fb9..1905e6d 100644 --- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/social/SocialTypeEnum.java +++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/social/SocialTypeEnum.java @@ -1,7 +1,7 @@ package com.iailab.module.system.enums.social; import cn.hutool.core.util.ArrayUtil; -import com.iailab.framework.common.core.IntArrayValuable; +import com.iailab.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,7 +14,7 @@ */ @Getter @AllArgsConstructor -public enum SocialTypeEnum implements IntArrayValuable { +public enum SocialTypeEnum implements ArrayValuable { /** * Gitee @@ -55,7 +55,7 @@ WECHAT_MINI_APP(34, "WECHAT_MINI_APP"), ; - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SocialTypeEnum::getType).toArray(); + public static final Integer[] ARRAYS = Arrays.stream(values()).map(SocialTypeEnum::getType).toArray(Integer[]::new); /** * 类型 @@ -67,7 +67,7 @@ private final String source; @Override - public int[] array() { + public Integer[] array() { return ARRAYS; } diff --git a/iailab-module-system/iailab-module-system-biz/proguard.cfg b/iailab-module-system/iailab-module-system-biz/proguard.cfg new file mode 100644 index 0000000..da2c034 --- /dev/null +++ b/iailab-module-system/iailab-module-system-biz/proguard.cfg @@ -0,0 +1,132 @@ +#指定Java的版本 +-target 1.8 +#proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等 +-dontshrink +#是否关闭字节码级别的优化,如果不开启则设置如下配置 +-dontoptimize +#混淆时不生成大小写混合的类名,默认是可以大小写混合 +-dontusemixedcaseclassnames +# 对于类成员的命名的混淆采取唯一策略 +-useuniqueclassmembernames +#混淆时不生成大小写混合的类名,默认是可以大小写混合 +-dontusemixedcaseclassnames +#混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代 +-adaptclassstrings + +-verbose +-printmapping proguard-mapping.txt # 生成混淆映射表(用于调试) + +#对异常、注解信息予以保留 +-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod +# 此选项将保存接口中的所有原始名称(不混淆)--> +-keepnames interface ** { *; } +# 此选项将保存所有软件包中的所有原始接口文件(不进行混淆) +#-keep interface * extends * { *; } +#保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数 +-keepparameternames +# 保留枚举成员及方法 +-keepclassmembers enum * { *; } +# 不混淆所有类,保存原始定义的注释- +-keepclassmembers class * { + @org.springframework.context.annotation.Bean *; + @org.springframework.beans.factory.annotation.Autowired *; + @org.springframework.beans.factory.annotation.Value *; + @org.springframework.stereotype.Service *; + @org.springframework.stereotype.Component *; + } + +#忽略warn消息 +-ignorewarnings +#忽略note消息 +-dontnote +#打印配置信息 +-printconfiguration +-keep public class com.iailab.module.system.SystemServerApplication { + public static void main(java.lang.String[]); + } + # 保留Feign客户端接口 + -keep @org.springframework.cloud.openfeign.FeignClient class * { + *; + } + # 业务包保留 + -keep class com.iailab.module.system.api.** { *; } + + # 日志与反射 + -keepclassmembers class * { + org.slf4j.Logger *; + } + -keepattributes RuntimeVisibleAnnotations, Signature +# 保留common模块的公共类 +-keep class com.iailab.framework.** { *; } + +# 保留mybatis-plus相关类 +-keep class com.baomidou.mybatisplus.** { *; } +-keep @com.baomidou.mybatisplus.annotation.TableName class * { *; } + +# 保留数据权限注解 +-keep @com.iailab.framework.datapermission.core.** class * + + # 保留Spring Cloud配置类 + -keep class org.springframework.cloud.** { *; } + + # 保留domain实体类 + -keep class com.iailab.module.*.dal.dataobject.** { *; } + + # 保留DTO和VO + -keep class com.iailab.module.*.controller.**.vo.** { *; } + -keep class com.iailab.module.*.service.**.dto.** { *; } + + # 保留JSON注解 + -keep @com.fasterxml.jackson.annotation.JsonInclude class * + -keepclassmembers class * { + @com.fasterxml.jackson.annotation.JsonIgnore *; + @com.fasterxml.jackson.annotation.JsonProperty *; + } + -keep @io.swagger.v3.oas.annotations.Operation class * + # 保留路由断言工厂类 + -keep class org.springframework.cloud.gateway.handler.predicate.** { *; } + + # 保留若依自定义过滤器 + -keep class com.iailab.gateway.filters.** { *; } + + # 保留所有Spring组件类的原始名称 + -keepnames @org.springframework.stereotype.Component class * + -keepnames @org.springframework.stereotype.Service class * + -keepnames @org.springframework.stereotype.Repository class * + + # 保留@Bean方法的名称 + -keepclassmembernames class * { + @org.springframework.context.annotation.Bean *; + } + + # 保留所有 Spring 注解及组件 + -keep @org.springframework.stereotype.Component class * { *; } + -keep @org.springframework.context.annotation.Configuration class * { *; } + + # 保留配置类及字段 + -keep @org.springframework.boot.context.properties.ConfigurationProperties class * { *; } + -keepclassmembers @org.springframework.boot.context.properties.ConfigurationProperties class * { *; } + + # 保留关键业务模块 + -keep class com.iailab.module.system.framework.sms.** { *; } + -keepclassmembers class com.iailab.module.system.framework.sms.** { *; } + + -keep class com.iailab.module.system.convert.**.** { *; } + -keepclassmembers class com.iailab.module.system.convert.**.** { *; } + + # 保留 Setter 和资源文件 + -keepclassmembers class * { void set*(***); } + + # ========== SPI 相关保留 ========== + -keep interface com.xingyuv.captcha.service.** { *; } + -keep class * implements com.xingyuv.captcha.service.** { *; } + + # ========== Spring 自动配置类 ========== + -keep @org.springframework.boot.autoconfigure.AutoConfiguration class * { *; } + -keep class com.xingyuv.captcha.config.** { *; } + + # ========== 明确保留报错类 ========== + -keep class com.iailab.module.system.framework.captcha.core.RedisCaptchaServiceImpl { + public <init>(); + public *; + } \ No newline at end of file diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java index 2f8e230..103d57c 100644 --- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java +++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java @@ -22,6 +22,7 @@ default List<MenuDO> selectList(MenuListReqVO reqVO) { return selectList(new LambdaQueryWrapperX<MenuDO>() + .eq(MenuDO::getStatus, reqVO.getStatus()) .likeIfPresent(MenuDO::getName, reqVO.getName())); } diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorDiskJob.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorDiskJob.java new file mode 100644 index 0000000..7542143 --- /dev/null +++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorDiskJob.java @@ -0,0 +1,49 @@ +//package com.iailab.module.system.job.monitor; +// +//import com.iailab.framework.tenant.core.aop.TenantIgnore; +//import com.iailab.module.infra.api.monitor.MonitorApi; +//import com.iailab.module.infra.api.monitor.dto.MonitorDiskDTO; +//import com.iailab.module.infra.util.ServerInfoCollector; +//import com.xxl.job.core.handler.annotation.XxlJob; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.io.IOException; +//import java.util.Date; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicInteger; +// +//@Component +//public class MonitorDiskJob { +// +// private Logger logger = LoggerFactory.getLogger(getClass()); +// +// private final AtomicInteger counts = new AtomicInteger(); +// +// private static final Object lock = new Object(); +// +// private final MonitorApi monitorApi; +// +// @Value("${spring.application.name}") +// public String serverName; +// +// public MonitorDiskJob(MonitorApi monitorApi) { +// this.monitorApi = monitorApi; +// } +// +// @XxlJob("monitorDiskJob") +// @TenantIgnore +// @Transactional +// public void execute() throws IOException { +// synchronized (lock) { +// logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); +// System.out.println(new Date() + ": 我是系统服务system-server-服务器磁盘监控日志存储定时任务"); +// List<MonitorDiskDTO> monitorDiskDTOS = ServerInfoCollector.collectMonitorDisk(); +// monitorApi.reportDiskInfo(monitorDiskDTOS); +// } +// } +// +//} diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorMemJob.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorMemJob.java new file mode 100644 index 0000000..91aeb9f --- /dev/null +++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/monitor/MonitorMemJob.java @@ -0,0 +1,48 @@ +//package com.iailab.module.system.job.monitor; +// +//import com.iailab.framework.tenant.core.aop.TenantIgnore; +//import com.iailab.module.infra.api.monitor.MonitorApi; +//import com.iailab.module.infra.api.monitor.dto.MonitorMemDTO; +//import com.iailab.module.infra.util.ServerInfoCollector; +//import com.xxl.job.core.handler.annotation.XxlJob; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.io.IOException; +//import java.util.Date; +//import java.util.concurrent.atomic.AtomicInteger; +// +//@Component +//public class MonitorMemJob { +// +// private Logger logger = LoggerFactory.getLogger(getClass()); +// +// private final AtomicInteger counts = new AtomicInteger(); +// +// private static final Object lock = new Object(); +// +// private final MonitorApi monitorApi; +// +// @Value("${spring.application.name}") +// public String serverName; +// +// public MonitorMemJob(MonitorApi monitorApi) { +// this.monitorApi = monitorApi; +// } +// +// @XxlJob("monitorMemJob") +// @TenantIgnore +// @Transactional +// public void execute() throws IOException { +// synchronized (lock) { +// logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet()); +// System.out.println(new Date() + ": 我是系统服务system-server-服务器内存监控日志存储定时任务"); +// MonitorMemDTO monitorMemDTO = ServerInfoCollector.collectMonitorMem(serverName); +// monitorApi.reportMemInfo(monitorMemDTO); +// } +// } +// +//} diff --git a/iailab-module-system/iailab-module-system-biz/src/main/resources/application-prod.yaml b/iailab-module-system/iailab-module-system-biz/src/main/resources/application-prod.yaml new file mode 100644 index 0000000..ad88744 --- /dev/null +++ b/iailab-module-system/iailab-module-system-biz/src/main/resources/application-prod.yaml @@ -0,0 +1,116 @@ +--- #################### 数据库相关配置 #################### +spring: + # 数据源配置项 + autoconfigure: + exclude: + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 + datasource: + druid: # Druid 【监控】相关的全局配置 + web-stat-filter: + enabled: true + stat-view-servlet: + enabled: true + allow: # 设置白名单,不填则允许所有访问 + url-pattern: /druid/* + login-username: # 控制台管理用户名和密码 + login-password: + filter: + stat: + enabled: true + log-slow-sql: true # 慢 SQL 记录 + slow-sql-millis: 100 + merge-sql: true + wall: + config: + multi-statement-allow: true + dynamic: # 多数据源配置 + druid: # Druid 【连接池】相关的全局配置 + initial-size: 5 # 初始连接数 + min-idle: 10 # 最小连接池数量 + max-active: 20 # 最大连接池数量 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 + test-while-idle: true + test-on-borrow: false + test-on-return: false + primary: master + datasource: + master: + url: jdbc:mysql://172.16.8.100:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + username: root + password: 123456 + slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改 + lazy: true # 开启懒加载,保证启动速度 + url: jdbc:mysql://127.0.0.1:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + username: root + password: 123456 + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 6379 # 端口 + database: 1 # 数据库索引 + password: 123456 # 密码,建议生产环境开启 + +--- #################### MQ 消息队列相关配置 #################### + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv + +spring: + # RabbitMQ 配置项,对应 RabbitProperties 配置类 + rabbitmq: + host: 172.16.1.221 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: admin # RabbitMQ 服务的账号 + password: admin123 # RabbitMQ 服务的密码 + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +--- #################### 定时任务相关配置 #################### +xxl: + job: + enabled: true # 是否开启调度中心,默认为 true 开启 + admin: + addresses: http://172.16.216.133:9090/xxl-job-admin # 调度中心部署跟地址 + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项 +lock4j: + acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒 + expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒 + +--- #################### 监控相关配置 #################### + +# Actuator 监控端点的配置项 +management: + endpoints: + web: + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +--- #################### 平台相关配置 #################### + +# 平台配置项,设置当前项目所有自定义的配置 +iailab: + env: # 多环境的配置项 + tag: ${HOSTNAME} + security: + mock-enable: true + access-log: # 访问日志的配置项 + enable: false + xss: + enable: false + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 + demo: false # 开启演示模式 + captcha: + enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试 diff --git a/iailab-system/log/system-server.log b/iailab-system/log/system-server.log new file mode 100644 index 0000000..400714f --- /dev/null +++ b/iailab-system/log/system-server.log @@ -0,0 +1,188 @@ +2025-06-05 15:13:24.253 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.i.m.system.SystemServerApplication [0;39m | Starting SystemServerApplication using Java 17.0.11 on Thinkpad-E14 with PID 51220 (D:\Work\Yingdashi\Project\iailab-plat\iailab-plat\iailab-module-system\iailab-module-system-biz\target\classes started by houzh in D:\Work\Yingdashi\Project\iailab-plat\iailab-plat) +2025-06-05 15:13:24.258 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.i.m.system.SystemServerApplication [0;39m | The following 1 profile is active: "test" +2025-06-05 15:13:26.733 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.a.c.n.c.NacosConfigDataLoader [0;39m | [Nacos Config] Load config[dataId=system-server-test.yaml, group=DEFAULT_GROUP] success +2025-06-05 15:13:42.105 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.cloud.context.scope.GenericScope [0;39m | BeanFactory id=c0d8b71f-8806-3bf3-ab6e-9e72d53a8b49 +2025-06-05 15:13:43.819 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration' of type [com.mzt.logapi.starter.configuration.LogRecordProxyAutoConfiguration$$EnhancerBySpringCGLIB$$e92f3e7e] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:43.910 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration' of type [org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:43.932 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:43.944 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'loadBalancerClientsDefaultsMappingsProvider' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration$$Lambda$658/0x000002ad116ff088] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:43.983 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'defaultsBindHandlerAdvisor' of type [org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:44.025 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'mzt.log.record-com.mzt.logapi.starter.configuration.LogRecordProperties' of type [com.mzt.logapi.starter.configuration.LogRecordProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:44.092 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'logRecordPerformanceMonitor' of type [com.mzt.logapi.service.impl.DefaultLogRecordPerformanceMonitor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:45.717 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration' of type [com.iailab.framework.datapermission.config.IailabDataPermissionAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:45.774 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'dataPermissionAnnotationAdvisor' of type [com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:45.996 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'com.iailab.framework.tenant.config.IailabTenantAutoConfiguration' of type [com.iailab.framework.tenant.config.IailabTenantAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.156 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'dsProcessor' of type [com.iailab.framework.tenant.core.db.dynamic.TenantDsProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.382 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'org.apache.rocketmq.spring.autoconfigure.ListenerContainerConfiguration' of type [org.apache.rocketmq.spring.autoconfigure.ListenerContainerConfiguration$$EnhancerBySpringCGLIB$$408f94c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.397 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration' of type [org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration$$EnhancerBySpringCGLIB$$accf02b0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.686 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'createRocketMQMessageConverter' of type [org.apache.rocketmq.spring.support.RocketMQMessageConverter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.725 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'rocketmq-org.apache.rocketmq.spring.autoconfigure.RocketMQProperties' of type [org.apache.rocketmq.spring.autoconfigure.RocketMQProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:46.756 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mtrationDelegate$BeanPostProcessorChecker[0;39m | Bean 'rocketMQMessageListenerContainerRegistrar' of type [org.apache.rocketmq.spring.support.RocketMQMessageListenerContainerRegistrar] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) +2025-06-05 15:13:49.329 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.b.w.embedded.tomcat.TomcatWebServer [0;39m | Tomcat initialized with port(s): 48081 (http) +2025-06-05 15:13:49.334 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.a.catalina.core.AprLifecycleListener [0;39m | Loaded Apache Tomcat Native library [1.3.0] using APR version [1.7.4]. +2025-06-05 15:13:49.337 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.a.catalina.core.AprLifecycleListener [0;39m | APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true]. +2025-06-05 15:13:49.338 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.a.catalina.core.AprLifecycleListener [0;39m | APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] +2025-06-05 15:13:49.425 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.a.catalina.core.AprLifecycleListener [0;39m | OpenSSL successfully initialized [OpenSSL 3.0.13 30 Jan 2024] +2025-06-05 15:13:49.523 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.apache.catalina.core.StandardService [0;39m | Starting service [Tomcat] +2025-06-05 15:13:49.523 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32morg.apache.catalina.core.StandardEngine [0;39m | Starting Servlet engine: [Apache Tomcat/9.0.83] +2025-06-05 15:13:50.780 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.a.c.c.C.[Tomcat].[localhost].[/] [0;39m | Initializing Spring embedded WebApplicationContext +2025-06-05 15:13:50.781 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mw.s.c.ServletWebServerApplicationContext[0;39m | Root WebApplicationContext: initialization completed in 24017 ms +2025-06-05 15:13:52.077 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:13:52.546 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'system-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:13:55.197 | [31m WARN 51220[0;39m | [1;33mThread-6 [TID: N/A][0;39m [1;32mc.a.nacos.common.notify.NotifyCenter [0;39m | [NotifyCenter] Start destroying Publisher +2025-06-05 15:13:55.200 | [31m WARN 51220[0;39m | [1;33mThread-6 [TID: N/A][0;39m [1;32mc.a.nacos.common.notify.NotifyCenter [0;39m | [NotifyCenter] Destruction of the end +2025-06-05 15:13:55.196 | [31m WARN 51220[0;39m | [1;33mThread-1 [TID: N/A][0;39m [1;32mc.a.n.common.http.HttpClientBeanHolder [0;39m | [HttpClientBeanHolder] Start destroying common HttpClient +2025-06-05 15:13:55.212 | [31m WARN 51220[0;39m | [1;33mThread-1 [TID: N/A][0;39m [1;32mc.a.n.common.http.HttpClientBeanHolder [0;39m | [HttpClientBeanHolder] Destruction of the end +2025-06-05 15:13:56.095 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mcom.alibaba.druid.pool.DruidDataSource [0;39m | {dataSource-1,master} inited +2025-06-05 15:13:56.123 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.DynamicRoutingDataSource [0;39m | dynamic-datasource - add a datasource named [slave] success +2025-06-05 15:13:56.133 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.DynamicRoutingDataSource [0;39m | dynamic-datasource - add a datasource named [master] success +2025-06-05 15:13:56.134 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.DynamicRoutingDataSource [0;39m | dynamic-datasource initial loaded [2] datasource,primary datasource named [master] +2025-06-05 15:13:57.222 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'system-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:14:02.825 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:14:02.836 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:14:05.089 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32morg.redisson.Version [0;39m | Redisson 3.18.0 +2025-06-05 15:14:06.237 | [34m INFO 51220[0;39m | [1;33mredisson-netty-2-9 [TID: N/A][0;39m [1;32mo.r.c.pool.MasterPubSubConnectionPool [0;39m | 1 connections initialized for 172.16.8.100/172.16.8.100:6379 +2025-06-05 15:14:06.391 | [34m INFO 51220[0;39m | [1;33mredisson-netty-2-19 [TID: N/A][0;39m [1;32mo.r.c.pool.MasterConnectionPool [0;39m | 24 connections initialized for 172.16.8.100/172.16.8.100:6379 +2025-06-05 15:14:06.967 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mo.s.c.openfeign.FeignClientFactoryBean [0;39m | For 'infra-server' URL not provided. Will try picking an instance via load-balancing. +2025-06-05 15:14:07.268 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.x.c.s.i.BlockPuzzleCaptchaServiceImpl [0;39m | --->>>xingyuv captcha-plus 初始化验证码底图<<<---blockPuzzle +2025-06-05 15:14:07.595 | [1;31mERROR 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.x.c.s.i.BlockPuzzleCaptchaServiceImpl [0;39m | load font error:{} + +java.io.IOException: Problem reading font data. + at java.desktop/java.awt.Font.createFont0(Font.java:1208) ~[na:na] + at java.desktop/java.awt.Font.createFont(Font.java:1076) ~[na:na] + at com.xingyuv.captcha.service.impl.AbstractCaptchaService.loadWaterMarkFont(AbstractCaptchaService.java:210) ~[captcha-plus-1.0.8.jar:na] + at com.xingyuv.captcha.service.impl.AbstractCaptchaService.init(AbstractCaptchaService.java:100) ~[captcha-plus-1.0.8.jar:na] + at com.xingyuv.captcha.service.impl.BlockPuzzleCaptchaServiceImpl.init(BlockPuzzleCaptchaServiceImpl.java:34) ~[captcha-plus-1.0.8.jar:na] + at com.xingyuv.captcha.service.impl.CaptchaServiceFactory.getInstance(CaptchaServiceFactory.java:36) ~[captcha-plus-1.0.8.jar:na] + at com.xingyuv.captcha.config.AjCaptchaServiceAutoConfiguration.captchaService(AjCaptchaServiceAutoConfiguration.java:63) ~[spring-boot-starter-captcha-plus-1.0.8.jar:1.0.8] + at com.xingyuv.captcha.config.AjCaptchaServiceAutoConfiguration$$EnhancerBySpringCGLIB$$efe47e61.CGLIB$captchaService$0(<generated>) ~[spring-boot-starter-captcha-plus-1.0.8.jar:1.0.8] + at com.xingyuv.captcha.config.AjCaptchaServiceAutoConfiguration$$EnhancerBySpringCGLIB$$efe47e61$$FastClassBySpringCGLIB$$2b9e829c.invoke(<generated>) ~[spring-boot-starter-captcha-plus-1.0.8.jar:1.0.8] + at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.39.jar:5.3.39] + at com.xingyuv.captcha.config.AjCaptchaServiceAutoConfiguration$$EnhancerBySpringCGLIB$$efe47e61.captchaService(<generated>) ~[spring-boot-starter-captcha-plus-1.0.8.jar:1.0.8] + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] + at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] + at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:641) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:626) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:214) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:479) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:554) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:524) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:677) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:228) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:329) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:209) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:548) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:524) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:677) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:228) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:329) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:209) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) ~[spring-boot-2.7.18.jar:2.7.18] + at com.iailab.module.system.SystemServerApplication.main(SystemServerApplication.java:17) ~[classes/:na] + +2025-06-05 15:14:07.604 | [31m WARN 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mConfigServletWebServerApplicationContext[0;39m | Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminAuthServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'captchaService' defined in class path resource [com/xingyuv/captcha/config/AjCaptchaServiceAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.xingyuv.captcha.service.CaptchaService]: Factory method 'captchaService' threw exception; nested exception is java.lang.IllegalStateException: Shutdown in progress +2025-06-05 15:14:07.657 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.DynamicRoutingDataSource [0;39m | dynamic-datasource start closing .... +2025-06-05 15:14:07.663 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mcom.alibaba.druid.pool.DruidDataSource [0;39m | {dataSource-0} closing ... +2025-06-05 15:14:07.663 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.d.DefaultDataSourceDestroyer [0;39m | dynamic-datasource close the datasource named [slave] success, +2025-06-05 15:14:07.663 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mcom.alibaba.druid.pool.DruidDataSource [0;39m | {dataSource-1} closing ... +2025-06-05 15:14:07.674 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mcom.alibaba.druid.pool.DruidDataSource [0;39m | {dataSource-1} closed +2025-06-05 15:14:07.675 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.d.DefaultDataSourceDestroyer [0;39m | dynamic-datasource close the datasource named [master] success, +2025-06-05 15:14:07.675 | [34m INFO 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32mc.b.d.d.DynamicRoutingDataSource [0;39m | dynamic-datasource all closed success,bye +2025-06-05 15:14:07.677 | [31m WARN 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32ms.c.a.AnnotationConfigApplicationContext[0;39m | Exception thrown from ApplicationListener handling ContextClosedEvent + +org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'rabbitConnectionFactory': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:220) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:214) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:264) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:221) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:140) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:430) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:436) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:387) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1072) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1035) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:99) ~[spring-cloud-context-3.1.8.jar:3.1.8] + at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:213) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:587) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:559) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1163) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:520) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1156) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1123) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:604) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) ~[spring-boot-2.7.18.jar:2.7.18] + at com.iailab.module.system.SystemServerApplication.main(SystemServerApplication.java:17) ~[classes/:na] + +2025-06-05 15:14:07.679 | [31m WARN 51220[0;39m | [1;33mmain [TID: N/A][0;39m [1;32ms.c.a.AnnotationConfigApplicationContext[0;39m | Exception thrown from ApplicationListener handling ContextClosedEvent + +org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'rabbitConnectionFactory': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:220) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:214) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:264) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:221) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:140) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:430) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:436) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:387) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1072) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1035) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:99) ~[spring-cloud-context-3.1.8.jar:3.1.8] + at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:213) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:587) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:559) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1163) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:520) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1156) ~[spring-beans-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1123) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:604) ~[spring-context-5.3.39.jar:5.3.39] + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.7.18.jar:2.7.18] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) ~[spring-boot-2.7.18.jar:2.7.18] + at com.iailab.module.system.SystemServerApplication.main(SystemServerApplication.java:17) ~[classes/:na] + diff --git a/pom.xml b/pom.xml index 87aa10e..e28eda3 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ <name>${project.artifactId}</name> <description>平台项目基础脚手架</description> - <url>http://172.16.8.100:8888/summary/iailab-plat.git</url> + <url>http://172.16.8.100:8888/summary/iailab-plat-v2.0.git</url> <properties> <revision>1.0.0</revision> diff --git "a/\345\267\245\344\270\232\344\272\222\350\201\224\347\275\221\345\271\263\345\217\260\351\211\264\346\235\203\345\212\237\350\203\275.md" "b/\345\267\245\344\270\232\344\272\222\350\201\224\347\275\221\345\271\263\345\217\260\351\211\264\346\235\203\345\212\237\350\203\275.md" new file mode 100644 index 0000000..ee54152 --- /dev/null +++ "b/\345\267\245\344\270\232\344\272\222\350\201\224\347\275\221\345\271\263\345\217\260\351\211\264\346\235\203\345\212\237\350\203\275.md" @@ -0,0 +1,269 @@ +## 工业互联网平台鉴权功能 ## +1. 登录功能 + 登录接口: http://0.0.0.0/admin-api/system/auth/login + +① 参数说明 + + { + "tenantName": "tenant1", //租户名称(必传),需事先在平台配置 + "username": "admin", //用户名(必传),平台事先维护好用户 + "password": "123", //密码(必传) + "captchaVerification": "PfcH6mgr==" //验证码(非必传),若开启的话需要前后台同时开启 + } + +其中租户名称在登录逻辑中用不到,用到的是租户对应的ID,接口请求的时候需要将Tenant-Id封装到请求头中,登录逻辑会从请求头中获取并使用,如下截图 +特别注意:平台其它接口也都需要封装此租户ID + + +② 主要代码 +1、控制层接口 + + `@PostMapping("/login") + @PermitAll + @Operation(summary = "使用账号密码登录") + public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) { + return success(authService.login(reqVO)); + }` + +2、参数对象 AuthLoginReqVO + +@Schema(description = "管理后台 - 账号密码登录 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AuthLoginReqVO { + + @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "iailabyuanma") + @NotEmpty(message = "登录账号不能为空") + @Length(min = 4, max = 16, message = "账号长度为 4-16 位") + @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母") + private String username; + + @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao") + @NotEmpty(message = "密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String password; + + // ========== 图片验证码相关 ========== + + @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED, + example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==") + @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class) + private String captchaVerification; +} +3、登录实现类 + + @Override + public AuthLoginRespVO login(AuthLoginReqVO reqVO) { + // 校验验证码 + validateCaptcha(reqVO); + + // 使用账号密码,进行登录 + AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword()); + + + // 创建 Token 令牌,记录登录日志 + return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME); + } +4、验证用户名密码 + + @Override + public AdminUserDO authenticate(String username, String password) { + final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME; + // 校验账号是否存在 + AdminUserDO user = userService.getUserByUsername(username); + if (user == null) { + createLoginLog(null, username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS); + throw exception(AUTH_LOGIN_BAD_CREDENTIALS); + } + if (!userService.isPasswordMatch(password, user.getPassword())) { + createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS); + throw exception(AUTH_LOGIN_BAD_CREDENTIALS); + } + // 校验是否禁用 + if (CommonStatusEnum.isDisable(user.getStatus())) { + createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.USER_DISABLED); + throw exception(AUTH_LOGIN_USER_DISABLED); + } + return user; + } +用户名密码校验不通过常量如下图 + + + +5、创建令牌 + + private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) { + // 插入登陆日志 + createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS); + // 创建访问令牌 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(), + OAuth2ClientConstants.CLIENT_ID_DEFAULT, null); + // 构建返回结果 + return AuthConvert.INSTANCE.convert(accessTokenDO); + } +其中“OAuth2ClientConstants.CLIENT_ID_DEFAULT”是在平台配置好的默认客户端,主要包括授权类型、刷新token有效期、访问token有效期等 + + +6、创建访问令牌和刷新令牌 + + @Override + @Transactional + public OAuth2AccessTokenDO createAccessToken(Long userId, Integer userType, String clientId, List<String> scopes) { + OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId); + // 创建刷新令牌 + OAuth2RefreshTokenDO refreshTokenDO = createOAuth2RefreshToken(userId, userType, clientDO, scopes); + // 创建访问令牌 + return createOAuth2AccessToken(refreshTokenDO, clientDO); + } + private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, OAuth2ClientDO clientDO) { + OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken()) + .setUserId(refreshTokenDO.getUserId()).setUserType(refreshTokenDO.getUserType()) + .setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType())) + .setClientId(clientDO.getClientId()).setScopes(refreshTokenDO.getScopes()) + .setRefreshToken(refreshTokenDO.getRefreshToken()) + .setExpiresTime(LocalDateTime.now().plusSeconds(clientDO.getAccessTokenValiditySeconds())); + accessTokenDO.setTenantId(TenantContextHolder.getTenantId()); // 手动设置租户编号,避免缓存到 Redis 的时候,无对应的租户编号 + oauth2AccessTokenMapper.insert(accessTokenDO); + // 记录到 Redis 中 + oauth2AccessTokenRedisDAO.set(accessTokenDO); + return accessTokenDO; + } + private OAuth2RefreshTokenDO createOAuth2RefreshToken(Long userId, Integer userType, OAuth2ClientDO clientDO, List<String> scopes) { + OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setRefreshToken(generateRefreshToken()) + .setUserId(userId).setUserType(userType) + .setClientId(clientDO.getClientId()).setScopes(scopes) + .setExpiresTime(LocalDateTime.now().plusSeconds(clientDO.getRefreshTokenValiditySeconds())); + oauth2RefreshTokenMapper.insert(refreshToken); + return refreshToken; + } +注意:访问令牌是请求后端接口的通行证,所有需要鉴权的后端api都需要携带访问令牌,访问令牌过期后会请求刷新令牌接口,重新获取访问令牌。 当刷新令牌过期后,就需要重新登录获取授权了! +7、刷新令牌 + + @PostMapping("/refresh-token") + @PermitAll + @Operation(summary = "刷新令牌") + @Parameter(name = "refreshToken", description = "刷新令牌", required = true) + public CommonResult<AuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) { + return success(authService.refreshToken(refreshToken)); + } + @Override + public AuthLoginRespVO refreshToken(String refreshToken) { + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); + return AuthConvert.INSTANCE.convert(accessTokenDO); + } + @Override + public OAuth2AccessTokenDO refreshAccessToken(String refreshToken, String clientId) { + // 查询访问令牌 + OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectByRefreshToken(refreshToken); + if (refreshTokenDO == null) { + throw exception0(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "无效的刷新令牌"); + } + + // 校验 Client 匹配 + OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId); + if (ObjectUtil.notEqual(clientId, refreshTokenDO.getClientId())) { + throw exception0(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "刷新令牌的客户端编号不正确"); + } + + // 移除相关的访问令牌 + List<OAuth2AccessTokenDO> accessTokenDOs = oauth2AccessTokenMapper.selectListByRefreshToken(refreshToken); + if (CollUtil.isNotEmpty(accessTokenDOs)) { + oauth2AccessTokenMapper.deleteBatchIds(convertSet(accessTokenDOs, OAuth2AccessTokenDO::getId)); + oauth2AccessTokenRedisDAO.deleteList(convertSet(accessTokenDOs, OAuth2AccessTokenDO::getAccessToken)); + } + + // 已过期的情况下,删除刷新令牌 + if (DateUtils.isExpired(refreshTokenDO.getExpiresTime())) { + oauth2RefreshTokenMapper.deleteById(refreshTokenDO.getId()); + throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "刷新令牌已过期"); + } + + // 创建访问令牌 + return createOAuth2AccessToken(refreshTokenDO, clientDO); + } +8、前端封装token和租户ID代码参考 + + // request拦截器 + service.interceptors.request.use( + (config: InternalAxiosRequestConfig) => { + // 是否需要设置 token + let isToken = (config!.headers || {}).isToken === false + whiteList.some((v) => { + if (config.url && config.url.indexOf(v) > -1) { + return (isToken = false) + } + }) + if (getAccessToken() && !isToken) { + config.headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token + } + // 设置租户 + if (tenantEnable && tenantEnable === 'true') { + const tenantId = getTenantId() + if (tenantId) config.headers['tenant-id'] = tenantId + } + const method = config.method?.toUpperCase() + // 防止 GET 请求缓存 + if (method === 'GET') { + config.headers['Cache-Control'] = 'no-cache' + config.headers['Pragma'] = 'no-cache' + } + // 自定义参数序列化函数 + else if (method === 'POST') { + const contentType = config.headers['Content-Type'] || config.headers['content-type'] + if (contentType === 'application/x-www-form-urlencoded') { + if (config.data && typeof config.data !== 'string') { + config.data = qs.stringify(config.data) + } + } + } + return config + }, + (error: AxiosError) => { + // Do something with request error + console.log(error) // for debug + return Promise.reject(error) + } + ) +2. 退出登录功能 + 登出接口: http://0.0.0.0/admin-api/system/auth/logout + + + +核心代码如下 + + @PostMapping("/logout") + @PermitAll + @Operation(summary = "登出系统") + public CommonResult<Boolean> logout(HttpServletRequest request) { + String token = SecurityFrameworkUtils.obtainAuthorization(request, + securityProperties.getTokenHeader(), securityProperties.getTokenParameter()); + if (StrUtil.isNotBlank(token)) { + authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType()); + } + return success(true); + } + @Override + public void logout(String token, Integer logType) { + // 删除访问令牌 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(token); + if (accessTokenDO == null) { + return; + } + // 删除成功,则记录登出日志 + createLogoutLog(accessTokenDO.getUserId(), accessTokenDO.getUserType(), logType); + } + @Override + public OAuth2AccessTokenDO removeAccessToken(String accessToken) { + // 删除访问令牌 + OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken); + if (accessTokenDO == null) { + return null; + } + oauth2AccessTokenMapper.deleteById(accessTokenDO.getId()); + oauth2AccessTokenRedisDAO.delete(accessToken); + // 删除刷新令牌 + oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken()); + return accessTokenDO; + } -- Gitblit v1.9.3