Commit c1620424 authored by 张耀's avatar 张耀

feat:

预警规则设置接口对接
parent 0629c24b
// 通知方式
export const METHODS = {
1: '钉钉',
2: '短信'
dingtalk: '钉钉',
sms: '短信'
}
// 可以新增的数量
......
......@@ -3,7 +3,7 @@
:model="state.form"
ref="form_ref"
:rules="state.rules"
label-width="110px"
:label-width="labelWidth"
:disabled="disabled"
style="width: 100%">
<el-form-item :label="methodLabel || '通知方式'" prop="method">
......@@ -97,6 +97,10 @@ const props = defineProps({
type: Object,
default: () => ({}),
},
labelWidth: {
type: String,
default: "110px",
},
});
const form_ref = ref(null);
// 表单数据
......
......@@ -129,13 +129,42 @@ const rule_label = [
],
];
const rule_data = ref({});
const ruleTypeOptions = {
empty: "",
1: "百分比范围",
2: "毫秒范围",
3: "秒范围",
4: "个范围",
5: "温度范围",
const ruleTypeOptions = ref({});
const getRuleTypeOptions = () => {
let arr = [
{
id: "empty",
label: "",
},
{
id: "1",
label: "百分比范围",
unit: "%",
},
{
id: "2",
label: "毫秒范围",
unit: "ms",
},
{
id: "3",
label: "秒范围",
unit: "s",
},
{
id: "4",
label: "个范围",
unit: "",
},
{
id: "5",
label: "温度范围",
unit: "",
},
];
arr.forEach((e) => {
ruleTypeOptions.value[e.id] = e.label;
});
};
const advanced_label = [
[
......@@ -225,6 +254,7 @@ const getInfoData = () => {
});
};
onBeforeMount(() => {
getRuleTypeOptions();
getInfoData();
});
</script>
......
......@@ -211,8 +211,7 @@ const selectable = (row, index) => {
};
const getTableRows = () => {
let params = { ...state.filter, class_id: node.value.data.class_id };
// axios.get("/v1/api/metric_config/list", { params }).then((res) => {
axios.get("/v1/api/metric_config/list").then((res) => {
axios.get("/v1/api/metric_config/list", { params }).then((res) => {
if (res.data.code == 200) {
state.tableRows =
res.data.data?.list?.map((e) => {
......
......@@ -70,14 +70,40 @@ const props = defineProps({
// 预警规则类型下拉
const ruleTypeOptions = ref({});
const getRuleTypeOptions = () => {
ruleTypeOptions.value = {
empty: "",
1: "百分比范围",
2: "毫秒范围",
3: "秒范围",
4: "个范围",
5: "温度范围",
};
let arr = [
{
id: "empty",
label: "",
},
{
id: "1",
label: "百分比范围",
unit: "%",
},
{
id: "2",
label: "毫秒范围",
unit: "ms",
},
{
id: "3",
label: "秒范围",
unit: "s",
},
{
id: "4",
label: "个范围",
unit: "",
},
{
id: "5",
label: "温度范围",
unit: "",
},
];
arr.forEach((e) => {
ruleTypeOptions.value[e.id] = e.label;
});
};
// 当前是否是编辑
const isEdit = computed(() => !!props.row);
......
......@@ -7,7 +7,7 @@
</div>
<div class="add-btns">
<el-button size="default" @click="Cancle">取消</el-button>
<el-button type="primary" size="default" @click="Save">保存</el-button>
<el-button type="primary" size="default" @click="SaveSubmit">保存</el-button>
</div>
</div>
</div>
......@@ -18,15 +18,20 @@ import { ref } from "vue";
import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import addForm from "../modules/add-form.vue";
import { ElMessage } from "element-plus";
import { Save } from "../modules/interface.js";
const router = useRouter();
const Cancle = () => {
router.go(-1);
};
const add_form = ref(null);
const Save = async () => {
const SaveSubmit = async () => {
let res = await add_form.value.Submit();
if (!res) return;
console.log("res: ", res);
Save(res, {}, () => {
Cancle();
});
};
</script>
......
......@@ -13,9 +13,17 @@
</template>
</Info>
</div>
<gap-title :hasLine="true" title="预警范围"></gap-title>
<div class="info">
<Info :labelData="warning_scope_label" :valueData="watning_scope_data"> </Info>
<div class="warn-scope" v-if="detection_type == 1">
<gap-title :hasLine="true" title="预警范围"></gap-title>
<div class="info">
<Info :labelData="warning_scope_label" :valueData="watning_scope_data"> </Info>
</div>
</div>
<div class="warn-scope" v-else>
<gap-title :hasLine="true" title="指标表达式"></gap-title>
<div class="indicator-expression">
<bg-code-editor v-model="indicator_expression" :disabled="true"></bg-code-editor>
</div>
</div>
<gap-title :hasLine="true" title="预警规则"></gap-title>
<div class="info">
......@@ -29,7 +37,7 @@
<div class="info">
<Info :labelData="ticket_push_label" :valueData="ticket_push_data">
<template #notification_method="{ valueData }">
<span>{{ valueData.notification_method.map((e) => METHODS[e]).join("") }}</span>
<span>{{ valueData.notification_method?.map((e) => METHODS[e]).join("") || "" }}</span>
</template>
</Info>
<div class="push-lists">
......@@ -42,13 +50,34 @@
</template>
<script setup>
import { ref, onBeforeMount, computed } from "vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { useRoute } from "vue-router";
import gapTitle from "@/components/gap-title.vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import Info from "@/components/warn-detail/info.vue";
import { METHODS } from "@/components/manual-distribution/env.js";
const STATUS_OBJ = {
enabled: "启用",
disabled: "禁用",
const route = useRoute();
const { id } = route.query;
const STATUS_OBJ = ["禁用", "启用"];
const ruleTypeOptions = ref({});
const selectRule = {
"=": "等于",
"!=": "不等于",
"=~": "正则匹配",
"!~": "正则不匹配",
};
const riskLevelOptions = {
4: "重大风险",
3: "较大风险",
2: "一般风险",
1: "低风险",
};
const unitOptions = {
s: "",
m: "分钟",
h: "小时",
};
const labelData = [
[
......@@ -92,34 +121,9 @@ const labelData = [
},
],
];
const info = {
warning_rule_name: "服务中断推送规则1",
status: "enabled",
warning_target: "容器云",
warning_type: "容器集群",
warning_index: "CPU使用率",
create_by: "admin",
create_time: "2020-01-01 00:00:00",
update_time: "2020-01-01 00:00:00",
};
const warning_scope_label = [
[
{
prop: "colony",
label: "集群",
},
],
[
{
prop: "core_com",
label: "核心组件",
},
],
];
const watning_scope_data = {
colony: "等于 default",
core_com: "等于 kube-apiserver/kube-apiserver2/kube-apiserver3",
};
const info = ref({});
const warning_scope_label = ref([]);
const watning_scope_data = ref({});
const advanced_label = [
[
{
......@@ -134,10 +138,7 @@ const advanced_label = [
},
],
];
const advanced_data = {
duration: "直接产生预警",
inspection_cycle: "1分钟",
};
const advanced_data = ref({});
const ticket_push_label = [
[
{
......@@ -158,51 +159,135 @@ const ticket_push_label = [
},
],
];
const ticket_push_data = {
notification_method: ["1", "2"],
push_num: "10次",
push_frequency: "60分钟",
};
const ruleHeaders = [
{
prop: "warning_threshold",
label: "预警阈值",
},
const ticket_push_data = ref({});
const ruleHeaders = ref([
{
prop: "risk_level",
label: "风险程度",
},
];
const ruleRows = [
{
warning_threshold: "12% - 50% ",
risk_level: "较大风险",
},
{
warning_threshold: "50% - 100% ",
risk_level: "重大风险",
},
];
]);
const ruleRows = ref([]);
const pushHeaders = [
{
prop: "warning_threshold",
label: "预警阈值",
},
{
prop: "risk_level",
label: "风险程度",
prop: "system_account",
label: "账号",
},
];
const pushRows = [
{
warning_threshold: "12% - 50% ",
risk_level: "较大风险",
prop: "user_name",
label: "姓名",
},
{
warning_threshold: "50% - 100% ",
risk_level: "重大风险",
prop: "phone",
label: "联系方式",
},
];
const pushRows = ref([]);
const detection_type = ref(1);
const indicator_expression = ref("");
const getInfoData = () => {
axios
.get("/v1/api/alert_rules", {
params: {
id: id,
},
})
.then((res) => {
if (res.data.code == 200) {
const { data } = res.data;
detection_type.value = data.detection_type;
indicator_expression.value = data.expr;
info.value = {
warning_rule_name: data.metric_name,
status: data.is_enabled,
warning_target: data.class_parent_name,
warning_type: data.class_name,
warning_index: data.metric_config_name,
create_by: data.created_by,
create_time: data.created_at,
update_time: data.updated_at,
};
data.alert_range.forEach((e) => {
warning_scope_label.value.push([
{
prop: e.name,
label: e.chinese_name || e.name,
},
]);
watning_scope_data.value[e.name] = e.value == ".*" ? "全部" : `${selectRule[e.compare]} ${e.value}`;
});
let isEmpty = !data.alert_rule_type || data.alert_rule_type == "empty";
if (!isEmpty) {
ruleHeaders.value = [
{
prop: "warning_threshold",
label: "预警阈值",
},
...ruleHeaders.value,
];
}
ruleRows.value = data.alert_condition.map((e) => {
return {
warning_threshold: `${e.thresholds_min}${ruleTypeOptions.value[data.alert_rule_type].unit} - ${
e.thresholds_max
}${ruleTypeOptions.value[data.alert_rule_type].unit}`,
risk_level: riskLevelOptions[e.risk_level],
};
});
advanced_data.value = {
duration: data.duration == 0 ? "直接产生预警" : data.duration + unitOptions[data.duration_unit],
inspection_cycle: data.check_period + "分钟",
};
ticket_push_data.value = {
notification_method: data.notify_method,
push_num: data.notify_push_count + "",
push_frequency: data.notify_push_frequency + "分钟",
};
pushRows.value = data.notify_recipients;
} else {
ElMessage.error(res.data.data);
}
});
};
const getRuleTypeOptions = () => {
let arr = [
{
id: "empty",
label: "",
},
{
id: "1",
label: "百分比范围",
unit: "%",
},
{
id: "2",
label: "毫秒范围",
unit: "ms",
},
{
id: "3",
label: "秒范围",
unit: "s",
},
{
id: "4",
label: "个范围",
unit: "",
},
{
id: "5",
label: "温度范围",
unit: "",
},
];
arr.forEach((e) => {
ruleTypeOptions.value[e.id] = e;
});
getInfoData();
};
onBeforeMount(() => {
getRuleTypeOptions();
});
</script>
<style lang="scss" scoped>
......@@ -221,6 +306,16 @@ const pushRows = [
:deep(.gap-title) {
margin-bottom: 16px;
}
.warn-scope {
margin-bottom: 24px;
.indicator-expression {
height: 300px;
width: 100%;
:deep(.vue-ace-editor) {
margin-top: 0;
}
}
}
.info {
max-width: 1072px;
width: 100%;
......@@ -241,8 +336,8 @@ const pushRows = [
border-radius: 50%;
margin-right: 8px;
$statusObj: (
enabled: #48ad97,
disabled: #9e9e9e,
1: #48ad97,
0: #9e9e9e,
);
@each $status, $color in $statusObj {
&-#{$status} {
......
......@@ -7,181 +7,155 @@
</div>
<div class="add-btns">
<el-button size="default" @click="Cancle">取消</el-button>
<el-button type="primary" size="default" @click="Save">保存</el-button>
<el-button type="primary" size="default" @click="SaveSubmit">保存</el-button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { ref, onBeforeMount } from "vue";
import { useRouter, useRoute } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import addForm from "../modules/add-form.vue";
// const infoData = ref({
// id: 1,
// name: "11",
// type_key: "static",
// duration: 1,
// time: 10,
// inspection_cycle: 1,
// push_num: 1,
// push_frequency: 60,
// enabled: true,
// type_com_ref: {
// warn_type: "colony",
// warn_indicator: "1",
// warn_target: "1",
// warn_type_com: {
// value1: "22",
// value1_select: "3",
// value2: "33",
// value2_select: "2",
// risk_level: 1,
// },
// },
// manual_distribution_form: {
// method: ["1", "2"],
// lists: [
// {
// user_id: 2,
// user_name: 22,
// phone: 13000000002,
// },
// {
// user_id: 3,
// user_name: 33,
// phone: 13000000003,
// },
// ],
// },
// });
const infoData = ref({
name: "11",
type_key: "static",
duration: 1,
time: 10,
inspection_cycle: 1,
push_num: 1,
push_frequency: 60,
enabled: true,
type_com_ref: {
warn_type: "gateway",
warn_indicator: "1",
warn_target: "1",
warn_type_com: {
ruleRows: [
{
from: "22",
to: "33",
risk_level: 1,
},
{
from: "44",
to: "55",
risk_level: 2,
},
],
},
},
manual_distribution_form: {
method: ["1"],
lists: [
{
user_id: 1,
user_name: 11,
phone: 13000000001,
},
],
},
});
// const infoData = ref({
// id: 1,
// name: "11",
// type_key: "static",
// duration: 1,
// time: 10,
// inspection_cycle: 1,
// push_num: 1,
// push_frequency: 60,
// enabled: true,
// type_com_ref: {
// warn_type: "colony",
// warn_indicator: "1",
// warn_target: "1",
// warn_type_com: {
// value1: "22",
// value1_select: "3",
// value2: "33",
// value2_select: "2",
// risk_level: 1,
// },
// },
// manual_distribution_form: {
// method: ["1", "2"],
// lists: [
// {
// user_id: 2,
// user_name: 22,
// phone: 13000000002,
// },
// {
// user_id: 3,
// user_name: 33,
// phone: 13000000003,
// },
// ],
// },
// });
// const infoData = ref({
// name: "11",
// type_key: "custom",
// duration: 1,
// time: 10,
// inspection_cycle: 1,
// push_num: 1,
// push_frequency: 60,
// enabled: true,
// type_com_ref: {
// warn_target: "22",
// warn_type: "33",
// warn_indicator: "44",
// indicator_expression: "55\n66\n77",
// rule_type: "1",
// ruleRows: [
// {
// from: "88",
// to: "99",
// risk_level: 1,
// },
// ],
// },
// manual_distribution_form: {
// method: ["1", "2"],
// lists: [
// {
// user_id: 1,
// user_name: 11,
// phone: 13000000001,
// },
// {
// user_id: 2,
// user_name: 22,
// phone: 13000000002,
// },
// ],
// },
// });
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
import { Save } from "../modules/interface.js";
const infoData = ref({});
const router = useRouter();
const route = useRoute();
const { id } = route.query;
const Cancle = () => {
router.go(-1);
};
const add_form = ref(null);
const Save = async () => {
const SaveSubmit = async () => {
let res = await add_form.value.Submit();
if (!res) return;
console.log("res: ", res);
Save(res, { id }, () => {
Cancle();
});
};
const staticTypeOptions = ref([]);
const findTypeBySecond = (id) => {
return staticTypeOptions.value.find((e) => {
return e.children.find((e_c) => e_c.class_id == id);
});
};
const getInfoData = () => {
axios
.get("/v1/api/alert_rules", {
params: {
id: id,
},
})
.then((res) => {
if (res.data.code == 200) {
const { data } = res.data;
console.log("data: ", data);
const isEmpty = !data.alert_rule_type || data.alert_rule_type == "empty";
let type_json = {
1: () => {
let obj = {
key: "static",
type_com_ref: {
warn_type: data.class_id,
warn_indicator: data.metric_config_id,
warn_target: findTypeBySecond(data.class_id)?.class_id || "",
rule_type: data.alert_rule_type,
},
};
// if (isEmpty) {
// obj.type_com_ref.risk_level = data.alert_condition[0].risk_level;
// } else {
obj.type_com_ref.warning_scpoe_form =
data.alert_range?.map((e) => {
return {
...e,
select: e.compare,
options: [],
};
}) || [];
obj.type_com_ref.ruleRows =
data.alert_condition?.map((e) => {
return {
from: e.thresholds_min,
to: e.thresholds_max,
risk_level: e.risk_level,
};
}) || [];
// }
return obj;
},
2: () => {
let obj = {
key: "custom",
type_com_ref: {
warn_target: data.class_parent_name,
warn_type: data.class_name,
warn_indicator: data.metric_config_name,
indicator_expression: data.expr,
rule_type: data.alert_rule_type,
},
};
if (isEmpty) {
obj.type_com_ref.risk_level = data.alert_condition[0].risk_level;
} else {
obj.type_com_ref.ruleRows =
data.alert_condition?.map((e) => {
return {
from: e.thresholds_min,
to: e.thresholds_max,
risk_level: e.risk_level,
};
}) || [];
}
return obj;
},
};
let d = type_json[`${data.detection_type}`]();
infoData.value = {
name: data.metric_name,
type_key: d.key,
unit: data.duration_unit,
time: data.duration,
inspection_cycle: data.check_period,
push_num: data.notify_push_count,
push_frequency: data.notify_push_frequency,
enabled: data.is_enabled ? 1 : 2,
type_com_ref: d.type_com_ref,
manual_distribution_form: {
method: data.notify_method,
lists:
data.notify_recipients?.map((e) => {
return {
user_id: e.system_account,
user_name: e.user_name,
phone: e.phone,
};
}) || [],
},
};
} else {
ElMessage.error(res.data.data);
}
});
};
const getStaticTypeOptions = () => {
axios.get("/v1/api/alert_class/tree").then(async (res) => {
if (res.data.code == 200) {
staticTypeOptions.value = res.data.data;
getInfoData();
} else {
ElMessage.error(res.data.msg);
}
});
};
onBeforeMount(() => {
getStaticTypeOptions();
});
</script>
<style lang="scss" scoped>
......
<template>
<div class="add-form">
<el-form :model="state.form" ref="form_ref" :rules="state.rules" label-width="110px">
<el-form :model="state.form" ref="form_ref" :rules="state.rules" label-width="120px">
<div class="add-form-item">
<el-form-item label="预警规则名称" prop="name">
<el-input v-model="state.form.name" :disabled="isEdit" placeholder="请输入预警规则名称"></el-input>
......@@ -70,6 +70,7 @@
<ManualDistributionForm
ref="manual_distribution_form"
class="manual-distribution-form"
labelWidth="120px"
:noElLabel="false"
methodLabel="预警通知方式"
:history="history" />
......
<template>
<div class="container-cluster-form">
<el-form :model="state.form" ref="form_ref" :rules="state.rules" label-width="110px">
<gap-title :hasLine="true" title="预警范围"></gap-title>
<div class="container-cluster-form-item warning-scope-form-item">
<el-form-item :label="typeToTextJson[props.type][0]" prop="value1">
<el-input v-model="state.form.value1" placeholder="请输入">
<template #prepend>
<el-select class="rule-select" v-model="state.form.value1_select" style="width: 114px">
<el-option v-for="(value, key) in selectRule" :key="key" :label="value" :value="key" />
</el-select>
</template>
</el-input>
</el-form-item>
<el-form-item :label="typeToTextJson[props.type][1]" prop="value2">
<el-input v-model="state.form.value2" placeholder="请输入">
<template #prepend>
<el-select class="rule-select" v-model="state.form.value2_select" style="width: 114px">
<el-option v-for="(value, key) in selectRule" :key="key" :label="value" :value="key" />
</el-select>
</template>
</el-input>
</el-form-item>
</div>
<gap-title :hasLine="true" title="预警规则"></gap-title>
<div class="container-cluster-form-item">
<el-form-item label="风险程度" prop="risk_level">
<el-select style="flex: 1" v-model="state.form.risk_level" placeholder="请选择" filterable>
<el-option v-for="item in riskLevelOptions" :key="item.id" :label="item.name" :value="item.id"> </el-option>
</el-select>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script setup>
import { reactive, ref, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
const props = defineProps({
type: {
type: String,
default: "",
},
form: {
type: Object,
default: null,
},
});
const typeToTextJson = {
colony: ["集群", "核心组件"],
node: ["集群", "节点"],
group: ["命名空间", "容器"],
};
const selectRule = ref({
1: "遍历",
2: "等于",
3: "不等于",
4: "正则匹配",
5: "正则不匹配",
});
const state = reactive({
form: {
value1: "",
value1_select: "1",
value2: "",
value2_select: "1",
risk_level: "",
},
rules: {
value1: [{ required: true, message: "请输入", trigger: "blur" }],
value2: [{ required: true, message: "请输入", trigger: "blur" }],
risk_level: [{ required: true, message: "请选择", trigger: "change" }],
},
});
const form_ref = ref(null);
watch(
() => props.type,
(n) => {
state.form.value1 = "";
state.form.value1_select = "1";
state.form.value2 = "";
state.form.value2_select = "1";
form_ref.value.clearValidate(["value1", "value2", "risk_level"]);
}
);
watch(
() => props.form,
(n) => {
if (!n) return;
state.form.value1 = n.value1;
state.form.value1_select = n.value1_select || "1";
state.form.value2 = n.value2;
state.form.value2_select = n.value2_select || "1";
state.form.risk_level = n.risk_level;
},
{
deep: true,
immediate: true,
}
);
const riskLevelOptions = ref([
{
id: 1,
name: "重大风险",
},
{
id: 2,
name: "较大风险",
},
{
id: 3,
name: "一般风险",
},
{
id: 4,
name: "低风险",
},
]);
const Submit = async () => {
let form_valid = await new Promise((resolve, reject) => {
form_ref.value.validate((res) => resolve(res));
});
return form_valid;
};
defineExpose({
Submit,
form: state.form,
form_ref,
});
</script>
<style lang="scss" scoped>
.container-cluster-form {
:deep(.gap-title) {
margin-bottom: 16px;
}
&-item {
max-width: 1080px;
width: 100%;
padding-left: 8px;
}
.warning-scope-form-item {
display: flex;
align-items: center;
:deep(.el-form-item) {
flex: 1;
.el-input-group__prepend {
border-radius: 4px !important;
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
overflow: hidden;
}
}
:deep(.el-input-group__prepend) {
background-color: #2b4695;
.el-input__wrapper {
box-shadow: 1px 0 0 0 #2b4695 !important;
&,
.el-input__inner {
color: #fff;
}
.el-input__wrapper {
color: #fff;
}
}
}
}
}
</style>
......@@ -24,7 +24,7 @@
@input="inputNum($index, 'from')"
@blur="changeWarningThresholdFrom($index)">
<template v-if="state.form.rule_type != 'empty'" #append>{{
ruleTypeOptions[props.rule_type].unit
ruleTypeOptions[rule_type]?.unit || ""
}}</template>
</el-input>
</el-form-item>
......@@ -38,7 +38,7 @@
@input="inputNum($index, 'to')"
@blur="changeWarningThresholdTo($index)">
<template v-if="state.form.rule_type != 'empty'" #append>{{
ruleTypeOptions[props.rule_type].unit
ruleTypeOptions[rule_type]?.unit || ""
}}</template>
</el-input>
</el-form-item>
......@@ -81,7 +81,7 @@
</template>
<script setup>
import { computed, reactive, ref, watch } from "vue";
import { computed, nextTick, reactive, ref, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
import { ElMessage } from "element-plus";
const props = defineProps({
......@@ -94,50 +94,64 @@ const props = defineProps({
default: "1",
},
});
const ruleTypeOptions = {
empty: {
label: "",
},
1: {
label: "百分比范围",
unit: "%",
limit: {
down: 0,
up: 100,
const ruleTypeOptions = ref({});
const getRuleTypeOptions = async (cb) => {
let arr = [
{
id: "empty",
label: "",
},
},
2: {
label: "毫秒范围",
unit: "ms",
limit: {
down: 0,
up: "",
{
id: "1",
label: "百分比范围",
unit: "%",
limit: {
down: 0,
up: 100,
},
},
},
3: {
label: "秒范围",
unit: "s",
limit: {
down: 0,
up: "",
{
id: "2",
label: "毫秒范围",
unit: "ms",
limit: {
down: 0,
up: "",
},
},
},
4: {
label: "个范围",
unit: "",
limit: {
down: 0,
up: "",
{
id: "3",
label: "秒范围",
unit: "s",
limit: {
down: 0,
up: "",
},
},
},
5: {
label: "温度范围",
unit: "",
limit: {
down: "",
up: "",
{
id: "4",
label: "个范围",
unit: "",
limit: {
down: 0,
up: "",
},
},
},
{
id: "5",
label: "温度范围",
unit: "",
limit: {
down: "",
up: "",
},
},
];
arr.forEach((e) => {
ruleTypeOptions.value[e.id] = e;
});
await nextTick();
cb && cb();
};
const state = reactive({
form: {
......@@ -158,19 +172,19 @@ const Submit = async () => {
};
const riskLevels = ref([
{
id: 1,
id: 4,
name: "重大风险",
},
{
id: 2,
id: 3,
name: "较大风险",
},
{
id: 3,
id: 2,
name: "一般风险",
},
{
id: 4,
id: 1,
name: "低风险",
},
]);
......@@ -215,9 +229,13 @@ const setLimits = (index) => {
}) || []
);
};
const rule_type = computed(() => {
// return props.rule_type
return "1";
});
const limit = computed(() => {
return (
ruleTypeOptions[props.rule_type].limit || {
ruleTypeOptions.value[rule_type.value].limit || {
down: "",
up: "",
}
......@@ -227,7 +245,7 @@ const changeWarningThresholdFrom = (index) => {
let { down, up } = limit.value;
if (down === "") return;
let { from, to } = state.form.ruleRows[index];
if (+from > +up || (index == 0 && +from < +down) || (to != "" && from > +to)) {
if ((up != "" && +from > +up) || (index == 0 && +from < +down) || (to != "" && from > +to)) {
if (+from < +down) {
ElMessage.error(`下限不能小于${down}`);
} else if (+from > +up) {
......@@ -242,7 +260,7 @@ const changeWarningThresholdFrom = (index) => {
if (rows.length == 0) return;
try {
rows.forEach((e) => {
if (+e.up >= +from > +e.down) {
if (e.up !== "" && e.down !== "" && +e.up >= +from > +e.down) {
throw "";
}
});
......@@ -252,13 +270,13 @@ const changeWarningThresholdFrom = (index) => {
}
};
const inputNum = (index, key) => {
state.form.ruleRows[index][key] = state.form.ruleRows[index][key].replace(/[^\d]/g, "");
state.form.ruleRows[index][key] = +`${state.form.ruleRows[index][key]}`.replace(/[^\d]/g, "");
};
const changeWarningThresholdTo = (index) => {
let { down, up } = limit.value;
if (up === "") return;
let { from, to } = state.form.ruleRows[index];
if ((index == 0 && +to > +up) || +to < +down || (from != "" && +from > +to)) {
if ((index == 0 && +to > +up) || (down != "" && +to < +down) || (from != "" && +from > +to)) {
if (+to > +up) {
ElMessage.error(`上限不能超过${up}`);
} else if (+to < +down) {
......@@ -273,7 +291,7 @@ const changeWarningThresholdTo = (index) => {
if (rows.length == 0) return;
try {
rows.forEach((e) => {
if (+e.up > +to > +e.down) {
if (e.up !== "" && e.down !== "" && +e.up > +to > +e.down) {
throw "";
}
});
......@@ -287,22 +305,25 @@ const removeRule = (index) => {
};
watch(
() => props.form,
(f) => {
if (!f?.ruleRows) {
(n) => {
if (!n || n?.length == 0) {
getRuleTypeOptions();
createRule();
return;
}
state.form.ruleRows =
f.ruleRows.map((e) => {
return {
from: e.from,
to: e.to,
risk_level: e.risk_level,
};
}) || [];
if (state.form.ruleRows.length == 0) {
createRule();
}
getRuleTypeOptions(() => {
state.form.ruleRows =
n?.map((e) => {
return {
from: e.from,
to: e.to,
risk_level: e.risk_level,
};
}) || [];
if (state.form.ruleRows.length == 0) {
createRule();
}
});
},
{
deep: true,
......@@ -325,7 +346,7 @@ defineExpose({
&-item {
max-width: 1080px;
width: 100%;
padding-left: 110px;
padding-left: 120px;
:deep(.el-table thead th) {
background-color: #f5f6f9;
}
......
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
// max(container_fs_usage_bytes{pod!=\"\", namespace!=\"arms-prom\",namespace!=\"monitoring\"}) by (pod_name, namespace, device)/max(container_fs_limit_bytes{pod!=\"\"}) by (pod_name,namespace, device) * 100
const setParams = (res, { id }) => {
console.log('res: ', res);
let isEmpty = res.type_com_ref.isEmpty
let params = {
// 预警规则名称
metric_name: res.name,
// 持续时间
duration: +res.time,
// 持续时间单位
duration_unit: res.unit,
// 检查周期
check_period: +res.inspection_cycle,
// 预警通知方式
notify_method: res.manual_distribution_form.method,
// 预警通知人员列表
notify_recipients: res.manual_distribution_form.lists.map(e => {
return {
system_account: `${e.user_id}`,
user_name: `${e.user_name}`,
phone: `${e.phone}`
}
}),
// 消息推送次数
notify_push_count: +res.push_num,
// 消息推送频率
notify_push_frequency: +res.push_frequency,
// 是否立即启用
is_enabled: res.enabled ? 1 : 2
}
let params_push = {
// 自定义传参
custom: () => {
return {
detection_type: 2,
// 预警分类
class_parent_name: res.type_com_ref.warn_target,
// 预警对象
class_name: res.type_com_ref.warn_type,
// 预警指标
metric_config_name: res.type_com_ref.warn_indicator,
// 指标表达式
expr: res.type_com_ref.indicator_expression || "",
// 预警规则(下拉)
alert_rule_type: res.type_com_ref.rule_type,
// 预警规则对象数组
alert_condition,
alert_range: []
}
},
// 静态阈值传参
static: () => {
return {
detection_type: 1,
// 预警对象
class_id: +res.type_com_ref.warn_type,
metric_config_id: res.type_com_ref.warn_indicator,
// 报警范围(指标)
alert_range: res.type_com_ref.warning_scpoe_form.map(e => {
return {
variable_name: e.variable_name,
metric_name: e.metric_name,
chinese_name: e.chinese_name,
metric_label: e.metric_label,
is_required: e.is_required,
is_linked: e.is_linked,
value: e.select == 'all' ? '.*' : e.value,
compare: e.select == 'all' ? '=~' : e.select
}
}),
// // 预警规则(下拉)
// alert_rule_type: res.module_data.alert_rule_type,
}
}
}
let alert_condition = []
// debugger;
if (isEmpty) {
alert_condition = [{
thresholds_max: 0,
thresholds_min: 0,
risk_level: +res.type_com_ref.risk_level
}]
} else {
alert_condition = res.type_com_ref.ruleRows.map(e => {
return {
thresholds_max: +e.to,
thresholds_min: +e.from,
risk_level: +e.risk_level
}
})
}
params = {
...params,
...params_push[res.type_key](),
// 预警规则对象数组
alert_condition,
}
if (id) {
params.id = id
}
return params;
}
export const Save = (res, p, cb) => {
let params = setParams(res, p);
console.log('params: ', params);
return;
axios[p.id ? 'put' : 'post']('/v1/api/alert_rules', params).then(res => {
if (res.data.code == 200) {
ElMessage.success(`${p.id ? '编辑' : '新增'}成功`)
cb && cb()
} else {
ElMessage.error(res.data.data)
}
})
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment