From 3fb9308f95e70be94ea3bb0babe9651eda689e08 Mon Sep 17 00:00:00 2001 From: lensfrex Date: Fri, 10 May 2024 14:22:50 +0800 Subject: [PATCH] =?UTF-8?q?impl:=20=E5=AE=8C=E6=88=90=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E7=9B=B8=E5=85=B3=E5=9F=BA=E6=9C=AC=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20ref:=20=E8=A1=A5=E5=85=85=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E5=BB=BA=E8=A1=A8sql=E6=96=87=E4=BB=B6=20ref?= =?UTF-8?q?:=20=E5=BE=AE=E8=B0=83=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=20ref:=20=E8=B0=83=E6=95=B4springboot3.2?= =?UTF-8?q?=E4=B8=8B=E6=8E=A5=E5=8F=A3404=E7=9A=84=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E5=A4=84=E7=90=86=20fix:=20=E4=BF=AE=E5=A4=8D=E7=89=B9?= =?UTF-8?q?=E5=AE=9A=E5=88=86=E9=92=9F=E7=B2=92=E5=BA=A6=E4=B8=8B=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9B=91=E6=B5=8B=E6=95=B0=E6=8D=AE=E7=9A=84sql?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rition.sql | 19 ++- .../aop/exception/GlobalExceptionHandler.java | 13 ++ .../interceptor/NotFoundPathInterceptor.java | 36 ++++++ .../api/v1/dto/response/AlertResponse.java | 7 +- .../api/v1/dto/response/ContractResponse.java | 2 +- .../api/v1/dto/response/RuleResponse.java | 4 +- .../api/v1/panel/AlertHistoryController.java | 17 ++- .../api/v1/panel/AlertRuleController.java | 4 +- .../api/v1/panel/ContractController.java | 2 +- .../backend/configure/WebMvcConfigure.java | 8 +- .../rition/common/data/dto/PagingData.java | 2 + .../common/data/entity/AlertEntity.java | 5 + .../resources/mapper/MetricRecordMapper.xml | 4 +- rition-panel/package.json | 1 + rition-panel/quasar.config.js | 2 +- rition-panel/src/boot/axios.js | 5 +- rition-panel/src/layouts/MainLayout.vue | 2 +- rition-panel/src/pages/AlertListPage.vue | 45 ++++++- rition-panel/src/pages/ContractPage.vue | 113 ++++++++++++++-- rition-panel/src/pages/MetricPage.vue | 18 +++ rition-panel/src/pages/RulePage.vue | 122 ++++++++++++++---- rition-panel/yarn.lock | 5 + 22 files changed, 371 insertions(+), 65 deletions(-) create mode 100644 rition-center/api/src/main/java/rition/backend/api/interceptor/NotFoundPathInterceptor.java diff --git a/docs/rition.sql b/docs/rition.sql index b664058..5e4d9f9 100644 --- a/docs/rition.sql +++ b/docs/rition.sql @@ -11,7 +11,7 @@ Target Server Version : 80027 (8.0.27) File Encoding : 65001 - Date: 08/05/2024 10:15:09 + Date: 10/05/2024 14:22:09 */ SET NAMES utf8mb4; @@ -25,6 +25,7 @@ CREATE TABLE `alert` ( `id` bigint NOT NULL, `instance_id` varchar(64) NOT NULL COMMENT '出现警告的实例id', `rule` bigint NOT NULL COMMENT '触发的规则', + `value` double NOT NULL COMMENT '警告时的数值', `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '警告出现的时间', `status` tinyint NOT NULL DEFAULT '0', PRIMARY KEY (`id`), @@ -38,15 +39,13 @@ CREATE TABLE `alert` ( DROP TABLE IF EXISTS `contract`; CREATE TABLE `contract` ( `id` bigint NOT NULL, - `instance_id` varchar(64) NOT NULL COMMENT '绑定的实例', `contract` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '联系方式', `type` tinyint NOT NULL COMMENT '联系方式类型', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `status` tinyint NOT NULL DEFAULT '0', PRIMARY KEY (`id`), - KEY `idx_id` (`id`), - KEY `idx_instance` (`instance_id`) + KEY `idx_id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- @@ -87,17 +86,15 @@ CREATE TABLE `record` ( DROP TABLE IF EXISTS `rule`; CREATE TABLE `rule` ( `id` bigint NOT NULL COMMENT '规则id', - `instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '规则对应的实例id', - `expression` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '需要计算的指标项或者表达式', - `condition` tinyint NOT NULL COMMENT '触发条件', + `expr` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '需要计算的指标项或者表达式', + `cond` tinyint NOT NULL COMMENT '触发条件', `threshold` varchar(32) NOT NULL COMMENT '阈值', - `trigger` tinyint NOT NULL COMMENT '触发方法,实时计算或定时计算', - `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '规则描述', + `trig` tinyint NOT NULL COMMENT '触发方法,实时计算或定时计算', + `comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '规则描述', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `status` tinyint NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `idx_instance` (`instance_id`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; SET FOREIGN_KEY_CHECKS = 1; diff --git a/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java b/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java index 95c0c6b..ea76196 100644 --- a/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java +++ b/rition-center/api/src/main/java/rition/backend/aop/exception/GlobalExceptionHandler.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.servlet.NoHandlerFoundException; +import org.springframework.web.servlet.resource.NoResourceFoundException; import rition.backend.api.v1.dto.response.Response; import rition.common.exception.ServiceException; import rition.common.exception.code.ServiceCode; @@ -44,6 +45,18 @@ public class GlobalExceptionHandler { return Response.error(ServiceCode.ApiNotImplement); } + /** + * 404 + * + * @param e 异常 + * @return 统一响应 + */ + @ResponseBody + @ExceptionHandler(NoResourceFoundException.class) + public Response baseException(NoResourceFoundException e) { + return Response.error(ServiceCode.ApiNotImplement); + } + /** * 处理参数不完整的请求异常 * diff --git a/rition-center/api/src/main/java/rition/backend/api/interceptor/NotFoundPathInterceptor.java b/rition-center/api/src/main/java/rition/backend/api/interceptor/NotFoundPathInterceptor.java new file mode 100644 index 0000000..3ee9807 --- /dev/null +++ b/rition-center/api/src/main/java/rition/backend/api/interceptor/NotFoundPathInterceptor.java @@ -0,0 +1,36 @@ +package rition.backend.api.interceptor; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Nonnull; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; +import rition.backend.api.v1.dto.response.Response; +import rition.common.exception.code.ServiceCode; + +@Component +public class NotFoundPathInterceptor implements HandlerInterceptor { + private final ObjectMapper objectMapper; + + public NotFoundPathInterceptor(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public void postHandle(@Nonnull HttpServletRequest request, + @Nonnull HttpServletResponse servletResponse, + @Nonnull Object handler, + ModelAndView modelAndView) throws Exception { + if (servletResponse.getStatus() == HttpStatus.NOT_FOUND.value()) { + var response = Response.error(ServiceCode.ApiNotImplement); + var json = objectMapper.writeValueAsString(response); + + servletResponse.setContentType("application/json"); + servletResponse.setCharacterEncoding("utf-8"); + servletResponse.getWriter().write(json); + } + } +} diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/AlertResponse.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/AlertResponse.java index b81ed09..1c6d655 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/AlertResponse.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/AlertResponse.java @@ -27,8 +27,13 @@ public class AlertResponse { */ private Long rule; + /** + * 触发时的数值 + */ + private Double value; + /** * 警告出现的时间 */ - private Instant time; + private Long time; } diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ContractResponse.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ContractResponse.java index 67a8d1c..620aada 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ContractResponse.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/ContractResponse.java @@ -30,5 +30,5 @@ public class ContractResponse { /** * create_time */ - private Instant createTime; + private Long createTime; } \ No newline at end of file diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/RuleResponse.java b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/RuleResponse.java index 7c6c681..7d9f7c6 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/RuleResponse.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/dto/response/RuleResponse.java @@ -45,10 +45,10 @@ public class RuleResponse { /** * create_time */ - private Instant createTime; + private Long createTime; /** * update_time */ - private Instant updateTime; + private Long updateTime; } diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertHistoryController.java b/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertHistoryController.java index 1141c58..9724f0f 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertHistoryController.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertHistoryController.java @@ -4,6 +4,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import rition.backend.api.v1.dto.response.AlertResponse; import rition.backend.api.v1.dto.response.Response; import rition.common.data.dto.PagingData; import rition.common.data.entity.AlertEntity; @@ -19,7 +20,7 @@ public class AlertHistoryController { } @GetMapping("/list") - public Response> getContractList( + public Response> getContractList( @RequestParam(value = "instance_id", required = false) String instanceId, @RequestParam(value = "page", required = false, defaultValue = "1") Integer page, @RequestParam(value = "page_size", required = false, defaultValue = "10") Integer pageSize @@ -28,6 +29,18 @@ public class AlertHistoryController { PagingData alertEntityPagingData = new PagingData<>(page, pageSize); var result = alertHistoryService.getAlertHistory(instanceId, alertEntityPagingData); - return Response.success(result); + PagingData alertResponsePagingData = PagingData.copyOnlyPagingValues(result); + for (AlertEntity entity : result.getData()) { + alertResponsePagingData.getData().add(AlertResponse.builder() + .id(entity.getId()) + .instanceId(entity.getInstanceId()) + .rule(entity.getRule()) + .value(entity.getValue()) + .time(entity.getTime().toEpochMilli()) + .build() + ); + } + + return Response.success(alertResponsePagingData); } } diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertRuleController.java b/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertRuleController.java index 00897f7..053146b 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertRuleController.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/panel/AlertRuleController.java @@ -32,8 +32,8 @@ public class AlertRuleController { response.setThreshold(ruleEntity.getThreshold()); response.setTrigger(ruleEntity.getTrig()); response.setDescription(ruleEntity.getComment()); - response.setCreateTime(ruleEntity.getCreateTime()); - response.setUpdateTime(ruleEntity.getUpdateTime()); + response.setCreateTime(ruleEntity.getCreateTime().toEpochMilli()); + response.setUpdateTime(ruleEntity.getUpdateTime().toEpochMilli()); ruleResponseList.add(response); } diff --git a/rition-center/api/src/main/java/rition/backend/api/v1/panel/ContractController.java b/rition-center/api/src/main/java/rition/backend/api/v1/panel/ContractController.java index e209810..748b803 100644 --- a/rition-center/api/src/main/java/rition/backend/api/v1/panel/ContractController.java +++ b/rition-center/api/src/main/java/rition/backend/api/v1/panel/ContractController.java @@ -29,7 +29,7 @@ public class ContractController { response.setId(contractEntity.getId()); response.setContract(contractEntity.getContract()); response.setType(contractEntity.getType()); - response.setCreateTime(contractEntity.getCreateTime()); + response.setCreateTime(contractEntity.getCreateTime().toEpochMilli()); responseList.add(response); } diff --git a/rition-center/api/src/main/java/rition/backend/configure/WebMvcConfigure.java b/rition-center/api/src/main/java/rition/backend/configure/WebMvcConfigure.java index abc4376..eca0528 100644 --- a/rition-center/api/src/main/java/rition/backend/configure/WebMvcConfigure.java +++ b/rition-center/api/src/main/java/rition/backend/configure/WebMvcConfigure.java @@ -6,6 +6,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import rition.backend.api.interceptor.NotFoundPathInterceptor; import rition.backend.api.interceptor.ResponseIdInterceptor; import rition.backend.api.resolver.RequestIdArgumentResolver; @@ -17,11 +18,13 @@ public class WebMvcConfigure implements WebMvcConfigurer { private final RequestIdArgumentResolver requestIdArgumentResolver; private final ResponseIdInterceptor requestIdInterceptor; + private final NotFoundPathInterceptor notFoundPathInterceptor; public WebMvcConfigure(RequestIdArgumentResolver requestIdArgumentResolver, - ResponseIdInterceptor requestIdInterceptor) { + ResponseIdInterceptor requestIdInterceptor, NotFoundPathInterceptor notFoundPathInterceptor) { this.requestIdArgumentResolver = requestIdArgumentResolver; this.requestIdInterceptor = requestIdInterceptor; + this.notFoundPathInterceptor = notFoundPathInterceptor; } @Override @@ -33,5 +36,8 @@ public class WebMvcConfigure implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(requestIdInterceptor) .addPathPatterns("/**"); + + registry.addInterceptor(notFoundPathInterceptor) + .addPathPatterns("/**"); } } diff --git a/rition-center/common/src/main/java/rition/common/data/dto/PagingData.java b/rition-center/common/src/main/java/rition/common/data/dto/PagingData.java index df4a11a..45e520f 100644 --- a/rition-center/common/src/main/java/rition/common/data/dto/PagingData.java +++ b/rition-center/common/src/main/java/rition/common/data/dto/PagingData.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.ArrayList; import java.util.Collection; @Data @@ -45,6 +46,7 @@ public class PagingData { pagingData.setPageSize(source.getPageSize()); pagingData.setTotalPage(source.getTotalPage()); pagingData.setTotalResult(source.getTotalResult()); + pagingData.setData(new ArrayList<>(source.data.size())); return pagingData; } diff --git a/rition-center/common/src/main/java/rition/common/data/entity/AlertEntity.java b/rition-center/common/src/main/java/rition/common/data/entity/AlertEntity.java index 656c8ff..02cfd46 100644 --- a/rition-center/common/src/main/java/rition/common/data/entity/AlertEntity.java +++ b/rition-center/common/src/main/java/rition/common/data/entity/AlertEntity.java @@ -29,6 +29,11 @@ public class AlertEntity { */ private Long rule; + /** + * 触发时的数值 + */ + private Double value; + /** * 警告出现的时间 */ diff --git a/rition-center/common/src/main/resources/mapper/MetricRecordMapper.xml b/rition-center/common/src/main/resources/mapper/MetricRecordMapper.xml index 6a7c115..d143288 100644 --- a/rition-center/common/src/main/resources/mapper/MetricRecordMapper.xml +++ b/rition-center/common/src/main/resources/mapper/MetricRecordMapper.xml @@ -68,8 +68,8 @@ avg(JSON_EXTRACT(metric_data, "$.${metricItem}")) as ${metricItem}, DATE_FORMAT( - concat( date( TimeStart ), ' ', HOUR ( TimeStart ), ':', floor( MINUTE ( TimeStart ) / #{minutes} ) * ${minutes} ), - '%Y-%m-%d %H:%i' + concat( date( `time` ), ' ', HOUR ( `time` ), ':', floor( MINUTE ( `time` ) / #{minutes} ) * ${minutes} ), + '%Y-%m-%d %H:%i:00' ) as t FROM record WHERE `time` BETWEEN #{startTime} and #{endTime} and `instance_id` = #{instanceId} GROUP BY t ORDER BY t diff --git a/rition-panel/package.json b/rition-panel/package.json index baf26e7..40e9e1f 100644 --- a/rition-panel/package.json +++ b/rition-panel/package.json @@ -17,6 +17,7 @@ "axios": "^1.2.1", "echarts": "^5.5.0", "element-plus": "^2.7.2", + "moment": "^2.30.1", "quasar": "^2.16.0", "tailwindcss": "^3.4.3", "vue": "^3.4.18", diff --git a/rition-panel/quasar.config.js b/rition-panel/quasar.config.js index 2a267b9..823429b 100644 --- a/rition-panel/quasar.config.js +++ b/rition-panel/quasar.config.js @@ -108,7 +108,7 @@ module.exports = configure(function (/* ctx */) { // directives: [], lang: 'zh-CN', // Quasar plugins - plugins: [] + plugins: ['Dialog', 'Loading'] }, // animations: 'all', // --- includes all animations diff --git a/rition-panel/src/boot/axios.js b/rition-panel/src/boot/axios.js index 2462db0..0fe0f63 100644 --- a/rition-panel/src/boot/axios.js +++ b/rition-panel/src/boot/axios.js @@ -7,7 +7,10 @@ import axios from 'axios' // good idea to move this instance creation inside of the // "export default () => {}" function below (which runs individually // for each client) -const api = axios.create({ baseURL: window.location.origin + "/api" }) +const api = axios.create({ + baseURL: window.location.origin + "/api", + timeout: 10 * 1000 +}) export default boot(({ app }) => { // for use inside Vue files (Options API) through this.$axios and this.$api diff --git a/rition-panel/src/layouts/MainLayout.vue b/rition-panel/src/layouts/MainLayout.vue index af1d46e..f3c7517 100644 --- a/rition-panel/src/layouts/MainLayout.vue +++ b/rition-panel/src/layouts/MainLayout.vue @@ -45,7 +45,7 @@ const linksList = [ link: '/' }, { - title: '通知信息', + title: '通知设置', icon: 'notifications', link: '/contract' }, diff --git a/rition-panel/src/pages/AlertListPage.vue b/rition-panel/src/pages/AlertListPage.vue index 40848b1..f10edea 100644 --- a/rition-panel/src/pages/AlertListPage.vue +++ b/rition-panel/src/pages/AlertListPage.vue @@ -1,17 +1,58 @@ diff --git a/rition-panel/yarn.lock b/rition-panel/yarn.lock index c6f26f3..821257b 100644 --- a/rition-panel/yarn.lock +++ b/rition-panel/yarn.lock @@ -2455,6 +2455,11 @@ minimist@^1.2.6: resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.0.tgz#b545f84af94e567386770159302ca113469c80b8" integrity sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig== +moment@^2.30.1: + version "2.30.1" + resolved "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"