Commit 632b7528 authored by 张耀's avatar 张耀

feat:

预警管理静态页面开发和部分接口对接
parent eeb30804
<template>
<div>指标配置详情</div>
<div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container bg-scroll">
<gap-title :hasLine="true" title="基本信息"></gap-title>
<div class="info">
<Info :labelData="labelData" :valueData="info">
<template #status="{ item, valueData }">
<span class="status-body">
<span class="status" :class="`status-${valueData.status}`"></span>
<span>{{ STATUS_OBJ[valueData[item.prop]] }}</span>
</span>
</template>
</Info>
</div>
<gap-title :hasLine="true" title="指标表达式"></gap-title>
<div class="info">
<div class="indicator-expression">
<bg-code-editor v-model="info.indicator_expression" disabled></bg-code-editor>
</div>
</div>
<gap-title :hasLine="true" title="预警范围"></gap-title>
<div class="info">
<bg-table border ref="ruletable" :headers="warningScopeHeaders" :rows="warningScopeRows" height="100%">
<template #metric="{ row }">
<span>{{ row.metric_name }}/{{ row.metric_label }}</span>
</template>
<template #is_required="{ row }">
<span>{{ row.is_required ? "" : "" }}</span>
</template>
<template #is_linked="{ row }">
<span>{{ row.is_linked ? "" : "" }}</span>
</template>
</bg-table>
</div>
<gap-title :hasLine="true" title="预警规则类型"></gap-title>
<div class="info">
<Info :labelData="rule_label" :valueData="rule_data">
<template #alert_rule_type="{ valueData }">
<span>
{{ ruleTypeOptions[valueData.alert_rule_type] }}
</span>
</template>
</Info>
</div>
<gap-title :hasLine="true" title="高级配置"> </gap-title>
<div class="info">
<Info :labelData="advanced_label" :valueData="advanced_data">
<template #inspection_cycle="{ valueData }">
<span>{{ valueData.inspection_cycle }}分钟</span>
</template>
</Info>
</div>
</div>
</div>
</template>
<script setup></script>
<script setup>
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 labelData = [
[
{
label: "预警分类",
prop: "warning_target",
},
{
label: "预警对象",
prop: "warning_type",
},
],
[
{
label: "预警指标",
prop: "warning_index",
},
{
label: "启用状态",
prop: "status",
},
],
[
{
label: "创建人",
prop: "create_by",
},
{
label: "创建时间",
prop: "create_time",
},
],
[
{
label: "更新时间",
prop: "update_time",
},
],
];
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",
indicator_expression: 'shttp_requests_total{method="GET",$pod$}',
};
const rule_label = [
[
{
prop: "alert_rule_type",
label: "预警规则类型",
},
],
];
const rule_data = {
alert_rule_type: "1",
};
const ruleTypeOptions = {
empty: "",
1: "百分比范围",
2: "毫秒范围",
3: "秒范围",
4: "个范围",
5: "温度范围",
};
const advanced_label = [
[
{
prop: "duration",
label: "持续时间",
},
],
[
{
prop: "inspection_cycle",
label: "检查周期",
},
],
];
const advanced_data = {
duration: "直接产生预警",
inspection_cycle: "1",
};
const ticket_push_label = [
[
{
prop: "notification_method",
label: "预警通知方式",
},
],
[
{
prop: "push_num",
label: "消息推送次数",
},
],
[
{
prop: "push_frequency",
label: "消息推送频率",
},
],
];
const ticket_push_data = {
notification_method: ["1", "2"],
push_num: "10次",
push_frequency: "60分钟",
};
const warningScopeHeaders = [
{
prop: "variable_name",
label: "变量名称",
},
{
prop: "metric",
label: "指标标签",
},
{
prop: "chinese_name",
label: "中文名称",
},
{
prop: "is_required",
label: "是否必填",
},
{
prop: "is_linked",
label: "是否联动",
},
];
const warningScopeRows = [
{
variable_name: "$pod$",
metric_name: "shttp_requests_total",
metric_label: "pod",
chinese_name: "demoString",
is_required: true,
is_linked: true,
},
{
variable_name: "$pod$",
metric_name: "shttp_requests_total",
metric_label: "pod",
chinese_name: "demoString",
is_required: true,
is_linked: true,
},
];
const pushHeaders = [
{
prop: "warning_threshold",
label: "预警阈值",
},
{
prop: "risk_level",
label: "风险程度",
},
];
const pushRows = [
{
warning_threshold: "12% - 50% ",
risk_level: "较大风险",
},
{
warning_threshold: "50% - 100% ",
risk_level: "重大风险",
},
];
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
height: 100%;
padding: 24px;
:deep(.gap-title) {
margin-bottom: 16px;
}
.info {
max-width: 1072px;
width: 100%;
padding: 0 8px 0;
&:not(:last-child) {
padding-bottom: 24px;
}
.push-lists {
margin-top: 16px;
}
.indicator-expression {
height: 300px;
width: 100%;
:deep(.vue-ace-editor) {
margin-top: 0;
}
}
}
}
}
.status {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 8px;
$statusObj: (
enabled: #48ad97,
disabled: #9e9e9e,
);
@each $status, $color in $statusObj {
&-#{$status} {
background-color: $color;
}
}
}
.status-body {
display: flex;
align-items: center;
}
</style>
......@@ -236,7 +236,7 @@ const getTableRows = () => {
};
const goDetail = (row) => {
router.push({
path: "/forewarning/rule-set/detail",
path: "/forewarning/indicator-config/detail",
query: {
id: row.id,
class_id: node.value.data.id,
......
......@@ -17,8 +17,9 @@
default-expand-all
:data="slideTree"
:current-node-key="selectId"
node-key="id"
node-key="class_id"
empty-text="暂无数据"
:props="treeProps"
:highlight-current="true"
:expand-on-click-node="false"
:filter-node-method="filterNode"
......@@ -69,7 +70,8 @@
<el-form :model="state.form_target" ref="add_warn_target_form" :rules="state.target_rules" label-width="80px">
<el-form-item label="预警分类" prop="type">
<el-select style="flex: 1" v-model="state.form_target.type" placeholder="请选择预警分类" filterable>
<el-option v-for="item in slideTree" :key="item.id" :label="item.label" :value="item.id"> </el-option>
<el-option v-for="item in slideTree" :key="item.class_id" :label="item.class_name" :value="item.class_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预警对象" prop="target">
......@@ -101,6 +103,8 @@
<script setup>
import { nextTick, onBeforeMount, reactive, ref } from "vue";
import GapTitle from "@/components/gap-title.vue";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const props = defineProps({
modelValue: {
type: Object,
......@@ -109,55 +113,31 @@ const props = defineProps({
});
const search = ref("");
let slideTree = ref([]);
const treeProps = {
// 组织树获取数据规则
children: "children",
label: "class_name",
};
const treeRef = ref(null);
const selectId = ref("");
const getSlideTree = async () => {
slideTree.value = [
{
id: 1,
label: "容器云",
children: [
{
id: 11,
label: "容器集群",
},
{
id: 12,
label: "容器节点",
},
{
id: 13,
label: "工作负载",
},
{
id: 4,
label: "网关",
},
],
},
{
id: 2,
label: "机房",
},
{
id: 3,
label: "机柜",
},
{
id: 4,
label: "服务器",
},
{
id: 5,
label: "数据库/达梦数据库",
},
];
await nextTick();
treeRef.value.setCurrentKey(slideTree.value[0].children[0].id);
setTimeout(() => {
const node = treeRef.value.getNode(slideTree.value[0].children[0]);
treeNodeChoose(slideTree.value[0].children[0], node);
}, 1000);
const getSlideTree = () => {
const params = {
page: 1,
page_size: 100000000000,
};
axios.get("/v1/api/alert_class/list", { params }).then(async (res) => {
if (res.data.code == 200) {
slideTree.value = res.data.data.list;
await nextTick();
treeRef.value.setCurrentKey(slideTree.value[0]?.children?.[0].class_id);
const node = treeRef.value.getNode(slideTree.value[0]?.children?.[0]);
if (node) {
treeNodeChoose(slideTree.value[0].children[0], node);
}
} else {
ElMessage.error(res.data.msg);
}
});
};
const filterNode = (value, data) => {
if (!value) return data;
......@@ -209,8 +189,8 @@ const operations = {
label: () => "上移",
disabled: (node, data) => {
let arr = getBrotherNodes(node);
let id = data.id;
let i = arr.findIndex((e) => e.id == id);
let id = data.class_id;
let i = arr.findIndex((e) => e.class_id == id);
return 0 == i;
},
},
......@@ -218,8 +198,8 @@ const operations = {
label: () => "下移",
disabled: (node, data) => {
let arr = getBrotherNodes(node);
let id = data.id;
let i = arr.findIndex((e) => e.id == id);
let id = data.class_id;
let i = arr.findIndex((e) => e.class_id == id);
return arr.length - 1 == i;
},
},
......@@ -240,38 +220,49 @@ const Operation = (key, node, data) => {
if (node.level == 1) {
addWarnType.value = true;
await nextTick();
state.form.name = data.label;
state.form.name = data.class_name;
} else {
addWarnTarget.value = true;
await nextTick();
state.form_target.type = activeTree.value.data.id;
state.form_target.target = data.label;
state.form_target.type = activeTree.value.data.class_id;
state.form_target.target = data.class_name;
}
isEditWarnType.value = true;
},
2: () => {
addWarnTarget.value = true;
isEditWarnType.value = false;
state.form_target.type = activeTree.value.data.id;
state.form_target.type = activeTree.value.data.class_id;
},
3: () => {
delWarnType.value = true;
},
4: () => {
let arr = getBrotherNodes(node);
let id = data.id;
let i = arr.findIndex((e) => e.id == id);
let prev = arr[i - 1];
move(data.class_id, "up");
},
5: () => {
let arr = getBrotherNodes(node);
let id = data.id;
let i = arr.findIndex((e) => e.id == id);
let next = arr[i + 1];
move(data.class_id, "down");
},
};
operation_handled_fn[key]();
};
const move = (class_id, type) => {
const params = {
class_id,
};
axios.put(`/v1/api/alert_class/move/${type}`, params).then((res) => {
if (res.data.code == 200) {
let text = {
up: "上移",
down: "下移",
};
ElMessage.success(`${text[type]}成功`);
getSlideTree();
} else {
ElMessage.error(res.data.msg);
}
});
};
const add_warn_type_form = ref(null);
const add_warn_target_form = ref(null);
const state = reactive({
......@@ -298,8 +289,23 @@ const Cancel = async () => {
const Save = () => {
add_warn_type_form.value.validate((valid) => {
if (valid) {
console.log(state.form);
Cancel();
const params = {
class_name: state.form.name,
parent_id: 0,
};
if (isEditWarnType.value) {
params.class_id = activeTree.value.own.class_id;
}
let method = isEditWarnType.value ? "put" : "post";
axios[method]("/v1/api/alert_class", params).then((res) => {
if (res.data.code == 200) {
ElMessage.success("预警分类新建成功");
Cancel();
getSlideTree();
} else {
ElMessage.error(res.data.msg);
}
});
} else {
return false;
}
......@@ -313,8 +319,23 @@ const CancelAddWarnTarget = async () => {
const SaveAddWarnTarget = () => {
add_warn_target_form.value.validate((valid) => {
if (valid) {
console.log(state.form_target);
Cancel();
const params = {
class_name: state.form_target.target,
parent_id: state.form_target.type,
};
if (isEditWarnType.value) {
params.class_id = activeTree.value.own.class_id;
}
let method = isEditWarnType.value ? "put" : "post";
axios[method]("/v1/api/alert_class", params).then((res) => {
if (res.data.code == 200) {
ElMessage.success("预警对象新建成功");
CancelAddWarnTarget();
getSlideTree();
} else {
ElMessage.error(res.data.msg);
}
});
} else {
return false;
}
......@@ -324,8 +345,21 @@ const CancelDel = () => {
delWarnType.value = false;
};
const ConfirmDel = () => {
console.log(activeTree.value.own);
CancelDel();
axios
.delete("/v1/api/alert_class", {
data: {
class_id: activeTree.value.own.class_id,
},
})
.then((res) => {
if (res.data.code == 200) {
ElMessage.success("删除成功");
CancelDel();
getSlideTree();
} else {
ElMessage.error(res.data.msg);
}
});
};
onBeforeMount(() => {
getSlideTree();
......
......@@ -155,21 +155,26 @@
v-model="closeWarningDialog"
width="400px"
:before-close="cancelCloseWarningDialog">
<el-form ref="closeForm" :model="closeFormData" :rules="closeRules" label-width="80px" class="bg_form">
<el-form-item label="关闭备注" prop="close_notes">
<el-input
v-model="closeFormData.close_notes"
type="textarea"
:autosize="{ minRows: 2 }"
show-word-limit
maxlength="30"
resize="vertical"
placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="" prop="close_remind" style="margin-bottom: 0px">
<el-checkbox v-model="closeFormData.close_remind" label="三天内将不再推送该预警信息" />
</el-form-item>
</el-form>
<div style="padding-top: 20px">
<el-form ref="closeForm" :model="closeFormData" :rules="closeRules" label-width="80px" class="bg_form">
<el-form-item label="关闭备注" prop="close_notes">
<el-input
v-model="closeFormData.close_notes"
type="textarea"
:autosize="{ minRows: 2 }"
show-word-limit
maxlength="30"
resize="vertical"
placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="" class="no-el-label" prop="close_remind" style="margin-bottom: 0px">
<el-checkbox v-model="closeFormData.close_remind">
<div>三天内将不再自动推送该告警信息给处置人员,</div>
<div>可手动推送,但告警数据依然会出现</div>
</el-checkbox>
</el-form-item>
</el-form>
</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="cancelCloseWarningDialog">取消</el-button>
......@@ -701,4 +706,13 @@ const {
}
}
}
.no-el-label {
:deep(.el-form-item__content) {
text-align: left;
margin-left: 10px !important;
.el-checkbox__label {
line-height: 18px;
}
}
}
</style>
......@@ -63,11 +63,11 @@ const labelData = [
],
[
{
label: "预警对象",
label: "预警分类",
prop: "warning_target",
},
{
label: "预警分类",
label: "预警对象",
prop: "warning_type",
},
],
......
......@@ -169,11 +169,11 @@ const state = reactive({
width: 200,
},
{
label: "预警对象",
label: "预警分类",
prop: "warning_object",
},
{
label: "预警分类",
label: "预警对象",
prop: "warning_type_name",
},
{
......
......@@ -28,20 +28,39 @@
<div class="add-form-item">
<div class="duration">
<el-form-item label="持续时间" prop="time">
<span>当预警持续</span>
<el-input v-model="state.form.time" placeholder="请输入持续时间" @input="inputNum"></el-input>
</el-form-item>
<el-form-item label="" prop="time" class="no-el-label">
<el-select v-model="state.form.unit" placeholder="请选择">
<el-option v-for="(value, key) in unitOptions" :key="key" :label="value.label" :value="key"> </el-option>
</el-select>
<span>时产生报警</span>
<el-input v-model="state.form.time" placeholder="请输入持续时间" @input="inputNum">
<template #prepend>
<span>当预警持续</span>
</template>
<template #append>
<el-select v-model="state.form.unit" placeholder="请选择">
<el-option v-for="(value, key) in unitOptions" :key="key" :label="value.label" :value="key">
</el-option>
</el-select>
</template>
</el-input>
<span class="duration-append">
<span> 时产生报警 </span>
<el-popover
:width="300"
title=""
content="大于等于0的正整数,等于0时代表直接报警"
trigger="hover"
placement="top-start">
<template #reference>
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-left: 8px; vertical-align: middle"
icon="#bg-ic-s-circle-tips"></bg-icon>
</template>
</el-popover>
</span>
</el-form-item>
</div>
<el-form-item label="检查周期" prop="inspection_cycle">
<el-select style="flex: 1" v-model="state.form.inspection_cycle" placeholder="请选择">
<el-select class="cycle-select" style="flex: 1" v-model="state.form.inspection_cycle" placeholder="请选择">
<el-option v-for="item in inspectionCycleOptions" :key="item" :label="item" :value="item"> </el-option>
</el-select>
<div class="cycle-unit">分钟</div>
</el-form-item>
</div>
<gap-title :hasLine="true" title="预警工单推送"></gap-title>
......@@ -205,25 +224,37 @@ defineExpose({
}
}
.duration {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
:deep(.el-form-item__content) {
display: flex;
align-items: center;
gap: 8px;
> .el-input {
:deep(.el-form-item) {
flex: 1;
.el-input {
margin-right: 8px;
flex: 1;
width: 80px;
}
}
.no-el-label {
:deep(.el-form-item__content) {
.el-select {
width: 80px;
}
.el-input-group__prepend {
width: 102px;
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.el-input-group__append {
width: 80px;
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
// :deep(.el-form-item__content) {
// display: flex;
// align-items: center;
// gap: 8px;
// > .el-input {
// flex: 1;
// width: 80px;
// }
// }
}
:deep(.el-switch__inner) {
.is-hide {
......@@ -235,6 +266,26 @@ defineExpose({
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.duration-append {
display: flex;
align-items: center;
color: #404a62;
}
.cycle-unit {
width: 60px;
height: 36px;
background-color: #f7f7f9;
border-radius: 0px 4px 4px 0px;
border: solid 1px #dadee7;
text-align: center;
border-left: 0;
}
.cycle-select {
:deep(.el-input__wrapper) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}
}
.no-el-label {
......
......@@ -5,7 +5,7 @@
<el-form-item label="预警对象" prop="warn_target">
<el-input
v-model="state.form.warn_target"
placeholder="请输入"
placeholder="请输入预警对象"
:disabled="isEdit"
:maxlength="20"
show-word-limit
......@@ -15,7 +15,7 @@
<el-form-item label="预警分类" prop="warn_type">
<el-input
v-model="state.form.warn_type"
placeholder="请输入"
placeholder="请输入预警分类"
:disabled="isEdit"
clearable
:maxlength="20"
......@@ -25,7 +25,7 @@
<el-form-item label="预警指标" prop="warn_indicator">
<el-input
v-model="state.form.warn_indicator"
placeholder="请输入"
placeholder="请输入预警指标"
:disabled="isEdit"
:maxlength="30"
show-word-limit
......@@ -97,7 +97,7 @@
<el-select
style="flex: 1"
v-model="state.form.ruleRows[$index].risk_level"
placeholder="请选择">
placeholder="请选择风险程度">
<el-option
v-for="item in riskLevelOptions($index)"
:key="item.id"
......@@ -175,16 +175,15 @@ const state = reactive({
ruleRows: [],
},
rules: {
warn_target: [{ required: true, message: "请输入", trigger: "blur" }],
warn_type: [{ required: true, message: "请输入", trigger: "blur" }],
warn_target: [{ required: true, message: "请输入预警对象", trigger: "blur" }],
warn_type: [{ required: true, message: "请输入预警分类", trigger: "blur" }],
warn_indicator: [{ validator: validateWarnIndex, trigger: "blur" }],
indicator_expression: [{ required: true, message: "请输入", trigger: "blur" }],
rule_type: [{ required: true, message: "请选择", trigger: "change" }],
indicator_expression: [{ required: true, message: "请输入预警指标", trigger: "blur" }],
},
tableRules: {
from: [{ required: true, message: "请输入", trigger: "blur" }],
to: [{ required: true, message: "请输入", trigger: "blur" }],
risk_level: [{ required: true, message: "请选择", trigger: "change" }],
risk_level: [{ required: true, message: "请选择风险程度", trigger: "change" }],
},
});
const changeWarnCustomTarget = () => {};
......
......@@ -21,8 +21,11 @@
style="flex: 1"
v-model.number="state.form.ruleRows[$index].from"
placeholder="请输入"
@input="changeWarningThresholdFrom($index)">
<template v-if="state.form.rule_type != 'empty'" #append>ms</template>
@input="inputNum($index, 'from')"
@blur="changeWarningThresholdFrom($index)">
<template v-if="state.form.rule_type != 'empty'" #append>{{
ruleTypeOptions[props.rule_type].unit
}}</template>
</el-input>
</el-form-item>
<span class="to">-</span>
......@@ -32,8 +35,11 @@
v-model.number="state.form.ruleRows[$index].to"
placeholder="请输入"
clearable
@input="changeWarningThresholdTo($index)">
<template v-if="state.form.rule_type != 'empty'" #append>ms</template>
@input="inputNum($index, 'to')"
@blur="changeWarningThresholdTo($index)">
<template v-if="state.form.rule_type != 'empty'" #append>{{
ruleTypeOptions[props.rule_type].unit
}}</template>
</el-input>
</el-form-item>
</div>
......@@ -77,13 +83,62 @@
<script setup>
import { computed, reactive, ref, watch } from "vue";
import gapTitle from "@/components/gap-title.vue";
import { ElMessage } from "element-plus";
const props = defineProps({
form: {
type: Object,
default: null,
},
rule_type: {
type: String,
default: "1",
},
});
const ruleTypeOptions = {
empty: {
label: "",
},
1: {
label: "百分比范围",
unit: "%",
limit: {
down: 0,
up: 100,
},
},
2: {
label: "毫秒范围",
unit: "ms",
limit: {
down: 0,
up: "",
},
},
3: {
label: "秒范围",
unit: "s",
limit: {
down: 0,
up: "",
},
},
4: {
label: "个范围",
unit: "",
limit: {
down: 0,
up: "",
},
},
5: {
label: "温度范围",
unit: "",
limit: {
down: "",
up: "",
},
},
};
const state = reactive({
form: {
ruleRows: [],
......@@ -160,11 +215,26 @@ const setLimits = (index) => {
}) || []
);
};
const limit = computed(() => {
return (
ruleTypeOptions[props.rule_type].limit || {
down: "",
up: "",
}
);
});
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) || +from > +to) {
if (+from > +up || (index == 0 && +from < +down) || (to != "" && from > +to)) {
if (+from < +down) {
ElMessage.error(`下限不能小于${down}`);
} else if (+from > +up) {
ElMessage.error(`上限不能超过${up}`);
} else {
ElMessage.error(`下限不能大于上限`);
}
state.form.ruleRows[index].from = "";
return;
}
......@@ -177,14 +247,25 @@ const changeWarningThresholdFrom = (index) => {
}
});
} catch (e) {
ElMessage.error(`该范围已被设置`);
state.form.ruleRows[index].from = "";
}
};
const inputNum = (index, key) => {
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 > +to) {
if ((index == 0 && +to > +up) || +to < +down || (from != "" && +from > +to)) {
if (+to > +up) {
ElMessage.error(`上限不能超过${up}`);
} else if (+to < +down) {
ElMessage.error(`下限不能小于${down}`);
} else {
ElMessage.error(`上限不能小于下限`);
}
state.form.ruleRows[index].to = "";
return;
}
......@@ -197,6 +278,7 @@ const changeWarningThresholdTo = (index) => {
}
});
} catch (e) {
ElMessage.error(`该范围已被设置`);
state.form.ruleRows[index].to = "";
}
};
......
......@@ -52,7 +52,7 @@
<el-input
class="warn-scpoe-input-value"
v-model="state.form.warning_scpoe_form[index].value"
placeholder="请输入"
:placeholder="`请输入${item.chinese_name}`"
v-if="!showSelect.includes(item.select)"
:disabled="item.select == 1">
</el-input>
......@@ -60,7 +60,7 @@
class="warn-scpoe-input-value"
v-else
v-model="item.value"
placeholder="请选择"
:placeholder="`请选择${item.chinese_name}`"
filterable
:loading="item.loading"
remote
......@@ -83,7 +83,7 @@
</el-option>
</el-select>
</el-form-item>
<Gateway v-else ref="warn_type_com" />
<Gateway v-else ref="warn_type_com" :rule_type="alert_rule_type" />
</div>
</div>
</div>
......@@ -370,9 +370,9 @@ defineExpose({
width: 100%;
padding-left: 8px;
.warning-scope-main {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 16px;
// display: grid;
// grid-template-columns: 1fr 1fr;
// grid-column-gap: 16px;
:deep(.el-input-group__prepend) {
border-radius: 4px;
border-top-right-radius: 0;
......@@ -385,9 +385,13 @@ defineExpose({
.warn-scpoe-select {
width: 114px !important;
:deep(.el-input__wrapper) {
background-color: #2b4695;
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
.el-input__inner {
color: #fff;
}
}
}
.warn-scpoe-input-item {
......
......@@ -905,9 +905,9 @@ markdown-it@^13.0.1:
mdurl "^1.0.1"
uc.micro "^1.0.5"
mavon-editor@^3.0.0:
mavon-editor@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/mavon-editor/-/mavon-editor-3.0.1.tgz"
resolved "https://registry.yarnpkg.com/mavon-editor/-/mavon-editor-3.0.1.tgz#0c2660569ded5b29e59d0e429af61eb618783a90"
integrity sha512-973cYCwv+AB+fcecsU6Ua6UXATxDMaY0Q7QzKQ/GmRW1sg+3DolZDnCGXth7XHDgrmqKTO57N42fVYujt0wfFw==
dependencies:
xss "^1.0.10"
......@@ -1083,6 +1083,11 @@ ssr-window@^3.0.0-alpha.1:
resolved "https://registry.npmmirror.com/ssr-window/-/ssr-window-3.0.0.tgz"
integrity sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==
string-format@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b"
integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
......@@ -1161,6 +1166,11 @@ vue-demi@*:
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-demi@^0.14.5:
version "0.14.5"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
integrity sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==
vue-i18n@^9.1.7:
version "9.1.10"
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.1.10.tgz"
......
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