Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
so-manage-ui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
smart-operation
so-manage-ui
Commits
302fb2f2
Commit
302fb2f2
authored
Jun 29, 2023
by
张耀
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:
预警管理静态页面开发
parent
e849bae2
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
3652 additions
and
27 deletions
+3652
-27
src/bg-ui/bg-code-editor.vue
src/bg-ui/bg-code-editor.vue
+14
-6
src/bg-ui/bg-table.vue
src/bg-ui/bg-table.vue
+12
-10
src/components/env.js
src/components/env.js
+4
-0
src/components/manual-distribution/form.vue
src/components/manual-distribution/form.vue
+0
-1
src/components/warn-detail/info.vue
src/components/warn-detail/info.vue
+3
-3
src/page/main/forewarning/indicator-config/add/index.vue
src/page/main/forewarning/indicator-config/add/index.vue
+60
-0
src/page/main/forewarning/indicator-config/detail/index.vue
src/page/main/forewarning/indicator-config/detail/index.vue
+7
-0
src/page/main/forewarning/indicator-config/edit/index.vue
src/page/main/forewarning/indicator-config/edit/index.vue
+126
-0
src/page/main/forewarning/indicator-config/index.vue
src/page/main/forewarning/indicator-config/index.vue
+384
-0
src/page/main/forewarning/indicator-config/modules/add-form.vue
...ge/main/forewarning/indicator-config/modules/add-form.vue
+469
-0
src/page/main/forewarning/indicator-config/modules/interface.js
...ge/main/forewarning/indicator-config/modules/interface.js
+39
-0
src/page/main/forewarning/indicator-config/modules/slide.vue
src/page/main/forewarning/indicator-config/modules/slide.vue
+418
-0
src/page/main/forewarning/list/index.vue
src/page/main/forewarning/list/index.vue
+4
-1
src/page/main/forewarning/rule-set/add/index.vue
src/page/main/forewarning/rule-set/add/index.vue
+56
-0
src/page/main/forewarning/rule-set/detail/index.vue
src/page/main/forewarning/rule-set/detail/index.vue
+253
-3
src/page/main/forewarning/rule-set/edit/index.vue
src/page/main/forewarning/rule-set/edit/index.vue
+210
-0
src/page/main/forewarning/rule-set/index.vue
src/page/main/forewarning/rule-set/index.vue
+19
-3
src/page/main/forewarning/rule-set/modules/add-form.vue
src/page/main/forewarning/rule-set/modules/add-form.vue
+264
-0
src/page/main/forewarning/rule-set/modules/common-com.vue
src/page/main/forewarning/rule-set/modules/common-com.vue
+171
-0
src/page/main/forewarning/rule-set/modules/custom.vue
src/page/main/forewarning/rule-set/modules/custom.vue
+440
-0
src/page/main/forewarning/rule-set/modules/gateway.vue
src/page/main/forewarning/rule-set/modules/gateway.vue
+286
-0
src/page/main/forewarning/rule-set/modules/static.vue
src/page/main/forewarning/rule-set/modules/static.vue
+412
-0
src/page/main/ticket/business-ticket-manage/add/index.vue
src/page/main/ticket/business-ticket-manage/add/index.vue
+1
-0
No files found.
src/bg-ui/bg-code-editor.vue
View file @
302fb2f2
...
...
@@ -82,20 +82,28 @@ const states = reactive({
const
codeChange
=
()
=>
{
emit
(
"
update:modelValue
"
,
states
.
content
);
};
onMounted
(()
=>
{
const
init
=
(
n
)
=>
{
let
obj
=
""
;
// console.log(typeof JSON.parse(this.datas));
try
{
if
(
typeof
JSON
.
parse
(
props
.
modelValue
)
==
"
object
"
)
{
obj
=
JSON
.
stringify
(
JSON
.
parse
(
props
.
modelValue
),
null
,
"
\t
"
);
if
(
typeof
JSON
.
parse
(
n
)
==
"
object
"
)
{
obj
=
JSON
.
stringify
(
JSON
.
parse
(
n
),
null
,
"
\t
"
);
}
else
{
obj
=
props
.
modelValue
;
obj
=
n
;
}
}
catch
(
e
)
{
obj
=
props
.
modelValue
;
obj
=
n
;
}
states
.
content
=
obj
;
};
watch
(
()
=>
props
.
modelValue
,
(
n
)
=>
{
init
(
n
);
}
);
onMounted
(()
=>
{
init
(
props
.
modelValue
);
});
const
{
content
}
=
toRefs
(
states
);
...
...
src/bg-ui/bg-table.vue
View file @
302fb2f2
...
...
@@ -24,7 +24,7 @@
<!-- 序号 -->
</el-table-column>
<el-table-column
v-for=
"
(header)
in headers"
v-for=
"
header
in headers"
:width=
"header.width"
:min-width=
"header.minWidth"
:align=
"header.align"
...
...
@@ -52,15 +52,8 @@
<
script
setup
>
import
{
watch
,
ref
,
nextTick
}
from
"
vue
"
;
import
{
selectTableMixin
}
from
"
./hook/mixin-select-table
"
;
const
{
nowSelectData
,
allSelectData
,
initAllSelectData
,
selectData
,
initSelectTableData
,
runPage
,
dealSelectData
,
}
=
selectTableMixin
();
const
{
nowSelectData
,
allSelectData
,
initAllSelectData
,
selectData
,
initSelectTableData
,
runPage
,
dealSelectData
}
=
selectTableMixin
();
const
props
=
defineProps
({
height
:
{
...
...
@@ -112,6 +105,11 @@ const props = defineProps({
type
:
Array
,
default
:
()
=>
[],
},
// 自定义返回值用来决定这一行的 CheckBox 是否可以勾选
selectable
:
{
type
:
Function
,
default
:
null
,
},
});
const
table
=
ref
(
null
);
...
...
@@ -198,6 +196,10 @@ const tableRowClassName = ({ row, rowIndex }) => {
}
};
const
selectable
=
(
row
,
index
)
=>
{
// 判断是否传入自定义返回值用来决定这一行的 CheckBox 是否可以勾选,否则使用默认勾选逻辑
if
(
props
.
selectable
)
{
return
props
.
selectable
(
row
,
index
);
}
if
(
props
.
canEdit
)
{
if
(
row
[
props
.
canEditFlag
]
&&
row
[
props
.
canEditFlag
]
==
1
)
{
return
false
;
...
...
src/components/env.js
View file @
302fb2f2
...
...
@@ -2,4 +2,8 @@ export const TIMEING_RULES = {
1
:
'
手动下发
'
,
2
:
'
按周
'
,
3
:
'
自定义时间
'
}
export
const
MAX_DAY
=
7
;
export
const
ONLY_INPUT_NUM
=
(
value
)
=>
{
return
value
.
replace
(
/
[^\d]
/g
,
''
)
}
\ No newline at end of file
src/components/manual-distribution/form.vue
View file @
302fb2f2
...
...
@@ -268,7 +268,6 @@ defineExpose({
}
}
.user-table
{
max-height
:
345px
;
:deep
(
.el-table
thead
th
)
{
background-color
:
#f5f6f9
;
}
...
...
src/components/warn-detail/info.vue
View file @
302fb2f2
...
...
@@ -2,7 +2,7 @@
<div>
<div
class=
"info-list"
v-for=
"(list, index) in labelData"
:key=
"`warn-$
{index}`">
<div
class=
"info-item"
v-for=
"(item, i) in list"
:key=
"`warn-$
{index}-${i}`">
<div
class=
"label"
>
<div
class=
"label"
:title=
"item.label"
>
{{
item
.
label
}}
</div>
<div
class=
"value"
>
...
...
@@ -13,7 +13,7 @@
<span
class=
"status"
:class=
"`status-$
{valueData.status}`">
</span>
<span>
{{
STATUS_OBJ
[
valueData
[
item
.
prop
]]
}}
</span>
</span>
<span
v-else
>
{{
valueData
[
item
.
prop
]
}}
</span>
<span
v-else
:title=
"valueData[item.prop]"
>
{{
valueData
[
item
.
prop
]
}}
</span>
</span>
</div>
</div>
...
...
@@ -60,7 +60,7 @@ const status_obj = computed(() => {
align-items
:
center
;
flex
:
1
;
height
:
48px
;
line-height
:
4
6
px
;
line-height
:
4
8
px
;
font-size
:
14px
;
color
:
#404a62
;
.label
{
...
...
src/page/main/forewarning/indicator-config/add/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"detail_container"
>
<bg-breadcrumb></bg-breadcrumb>
<div
class=
"main_container"
>
<div
class=
"add-form-main bg-scroll"
>
<add-form
ref=
"add_form"
></add-form>
</div>
<div
class=
"add-btns"
>
<el-button
size=
"default"
@
click=
"Cancle"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"SaveSubmit"
>
保存
</el-button>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
"
vue
"
;
import
bgBreadcrumb
from
"
@/components/bg-breadcrumb.vue
"
;
import
addForm
from
"
../modules/add-form.vue
"
;
import
{
Save
}
from
"
../modules/interface.js
"
;
import
{
useRouter
,
useRoute
}
from
"
vue-router
"
;
const
router
=
useRouter
();
const
route
=
useRoute
();
const
{
id
,
class_id
}
=
route
.
query
;
const
add_form
=
ref
(
null
);
const
params
=
{};
const
SaveSubmit
=
async
()
=>
{
let
res
=
await
add_form
.
value
.
Submit
();
if
(
!
res
)
return
;
Save
(
res
);
};
const
Cancle
=
()
=>
{
router
.
go
(
-
1
);
};
</
script
>
<
style
lang=
"scss"
scoped
>
.detail_container
{
width
:
100%
;
height
:
calc
(
100vh
-
56px
);
padding
:
0
24px
16px
;
min-height
:
100%
;
.main_container
{
height
:
calc
(
100%
-
46px
);
padding
:
0
;
.add-form-main
{
padding
:
24px
24px
16px
;
height
:
calc
(
100%
-
68px
);
}
.add-btns
{
height
:
68px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
border-top
:
1px
solid
#ddd
;
padding
:
0
24px
;
}
}
}
</
style
>
src/page/main/forewarning/indicator-config/detail/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div>
指标配置详情
</div>
</
template
>
<
script
setup
></
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/page/main/forewarning/indicator-config/edit/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"detail_container"
>
<bg-breadcrumb></bg-breadcrumb>
<div
class=
"main_container"
>
<div
class=
"add-form-main bg-scroll"
>
<add-form
ref=
"add_form"
:row=
"infoData"
></add-form>
</div>
<div
class=
"add-btns"
>
<el-button
size=
"default"
@
click=
"Cancle"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"SaveSubmit"
>
保存
</el-button>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
onBeforeMount
,
ref
}
from
"
vue
"
;
import
bgBreadcrumb
from
"
@/components/bg-breadcrumb.vue
"
;
import
addForm
from
"
../modules/add-form.vue
"
;
import
{
Save
,
URL
}
from
"
../modules/interface.js
"
;
import
{
ElMessage
}
from
"
element-plus
"
;
import
{
useRouter
,
useRoute
}
from
"
vue-router
"
;
const
router
=
useRouter
();
const
route
=
useRoute
();
const
{
id
,
class_id
}
=
route
.
query
;
const
infoData
=
ref
({});
const
add_form
=
ref
(
null
);
const
SaveSubmit
=
async
()
=>
{
let
res
=
await
add_form
.
value
.
Submit
();
if
(
!
res
)
return
;
Save
(
res
,
{
id
,
class_id
});
};
const
Cancle
=
()
=>
{
router
.
go
(
-
1
);
};
const
getInfoData
=
()
=>
{
// axios
// .get(URL, {
// params: {
// id: id,
// },
// })
// .then((res) => {
// if (res.data.code == 200) {
// console.log(res.data.data);
// } else {
// ElMessage.error(res.data.data);
// }
// });
let
res
=
{
id
:
"
20da8f87-628a-4f0c-bd9c-0ad176d18d59
"
,
class_id
:
101
,
metric_name
:
"
xx请求次数告警
"
,
expr
:
'
shttp_requests_total{method="GET",$pod$}
'
,
duration
:
5
,
duration_unit
:
"
m
"
,
check_period
:
3
,
is_enabled
:
1
,
alert_rule_type
:
"
9f1e6170-65e8-4e14-9c17-6a7b87a900a7
"
,
created_by
:
""
,
created_at
:
"
2023-06-28 17:28:29
"
,
updated_by
:
""
,
updated_at
:
"
2023-06-28 17:54:33
"
,
alert_range
:
[
{
variable_name
:
"
$pod$
"
,
metric_name
:
"
shttp_requests_total
"
,
metric_label
:
"
pod
"
,
chinese_name
:
"
demoString
"
,
is_required
:
true
,
is_linked
:
true
,
},
],
};
infoData
.
value
=
{
name
:
res
.
metric_name
,
indicator_expression
:
res
.
expr
,
rule_type
:
res
.
alert_rule_type
,
time
:
res
.
duration
,
unit
:
res
.
duration_unit
,
inspection_cycle
:
res
.
check_period
,
warningScopeRows
:
res
.
alert_range
.
map
((
e
)
=>
{
return
{
key
:
e
.
variable_name
,
input_indicator_tag
:
e
.
metric_label
,
indicator_scope
:
e
.
metric_name
,
indicator_tag
:
e
.
metric_label
,
cname
:
e
.
chinese_name
,
is_required
:
e
.
is_required
?
1
:
0
,
is_linkage
:
e
.
is_linked
?
1
:
0
,
};
})
||
[],
state
:
res
.
is_enabled
,
res
:
res
,
};
};
onBeforeMount
(()
=>
{
getInfoData
();
});
</
script
>
<
style
lang=
"scss"
scoped
>
.detail_container
{
width
:
100%
;
height
:
calc
(
100vh
-
56px
);
padding
:
0
24px
16px
;
min-height
:
100%
;
.main_container
{
height
:
calc
(
100%
-
46px
);
padding
:
0
;
.add-form-main
{
padding
:
24px
;
height
:
calc
(
100%
-
68px
);
}
.add-btns
{
height
:
68px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
border-top
:
1px
solid
#ddd
;
padding
:
0
24px
;
}
}
}
</
style
>
src/page/main/forewarning/indicator-config/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"detail_container"
>
<bg-breadcrumb></bg-breadcrumb>
<div
class=
"detail_container-main"
>
<Slide
v-model=
"node"
/>
<div
class=
"main-content"
>
<bg-filter-group
@
search=
"changeSearch"
v-model=
"filter.search"
placeholder=
"请输入指标名称"
>
<template
v-slot:left_action
>
<div
class=
"apaas_button"
>
<el-button
type=
"primary"
@
click=
"addRule"
>
<bg-icon
style=
"font-size: 12px; color: #fff; margin-right: 8px"
icon=
"#bg-ic-add"
></bg-icon>
新增
</el-button>
<el-button
type=
"default"
@
click=
"batchDelete"
>
批量删除
</el-button>
<span
class=
"header_info"
>
已选择
<span
style=
"color: #202531; font-weight: bold"
>
{{
state
.
selected
.
length
}}
</span>
项
</span>
<span
class=
"header_info can_click_text"
@
click=
"clearSelected"
>
清空
</span>
</div>
</
template
>
<
template
v-slot:filter_group
>
<div
class=
"left-filter filter_list"
>
<div
class=
"filter_item"
>
<span
class=
"filter_title"
>
启用状态
</span>
<el-select
v-model=
"filter.state"
placeholder=
"请选择"
style=
"width: 300px"
>
<el-option
v-for=
"(item, index) in stateOptions"
:key=
"'stateOptions' + index"
:label=
"item.name"
:value=
"item.value"
>
</el-option>
</el-select>
</div>
<div
class=
"filter_item"
>
<span
class=
"filter_title"
>
创建时间
</span>
<el-date-picker
style=
"width: 400px"
v-model=
"filter.time"
type=
"datetimerange"
value-format=
"yyyy-MM-DD HH:mm:ss"
range-separator=
"至"
start-placeholder=
"开始时间"
end-placeholder=
"结束时间"
/>
</div>
</div>
<div
class=
"right-action apaas_button"
>
<el-button
type=
"primary"
@
click=
"filterAction"
>
查询
</el-button>
<el-button
type=
"default"
@
click=
"filterClear"
>
重置
</el-button>
</div>
</
template
>
</bg-filter-group>
<div
class=
"table_container"
>
<div
class=
"table bg-scroll"
>
<bg-table
ref=
"dataTable"
:headers=
"headers"
:rows=
"tableRows"
@
selectAc=
"selectRows"
:selectable=
"selectable"
:isIndex=
"true"
:select=
"true"
:stripe=
"true"
>
<
template
v-slot:indicator_name=
"{ row }"
>
<span
class=
"can_click_text"
@
click=
"goDetail(row)"
>
{{
row
.
indicator_name
}}
</span>
</
template
>
<
template
#state
="{
row
}"
>
<bg-switch
@
click=
"stateChange(row)"
:labels=
"['否', '是']"
:values=
"[0, 1]"
v-model=
"row.state"
></bg-switch>
</
template
>
<
template
v-slot:created_time=
"{ row }"
>
{{
row
.
created_time
?
row
.
created_time
.
split
(
"
+
"
)[
0
].
replace
(
"
T
"
,
"
"
).
replace
(
"
Z
"
,
"
"
)
:
"
-
"
}}
</
template
>
<
template
v-slot:action=
"{ row }"
>
<bg-table-btns2
:limit=
"3"
:tableData=
"tableRows"
>
<bg-table-btn
:disabled=
"row.state != 0"
@
click=
"editRow(row)"
>
编辑
</bg-table-btn>
<bg-table-btn
:disabled=
"row.state != 0"
@
click=
"deleteRow(row)"
>
删除
</bg-table-btn>
</bg-table-btns2>
</
template
>
</bg-table>
</div>
<bg-pagination
:page=
"filter.page"
:size=
"filter.size"
:total=
"tableTotal"
@
change-page=
"changePage"
@
change-size=
"changeSize"
>
</bg-pagination>
</div>
</div>
</div>
<!-- 删除 -->
<el-dialog
class=
"dialog_box"
title=
"删除"
v-model=
"delDialog"
width=
"420px"
>
<div
style=
"padding: 20px 0"
>
确定要删除吗?
</div>
<
template
v-slot:footer
>
<div
class=
"apaas_button"
>
<el-button
type=
"default"
@
click=
"delDialog = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"delConfirm"
>
确定
</el-button>
</div>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
>
import
bgBreadcrumb
from
"
@/components/bg-breadcrumb.vue
"
;
import
{
reactive
,
ref
,
onBeforeMount
,
toRefs
,
computed
,
watch
,
nextTick
,
watchEffect
}
from
"
vue
"
;
import
Slide
from
"
./modules/slide.vue
"
;
import
{
ElMessage
}
from
"
element-plus
"
;
import
axios
from
"
@/request/http.js
"
;
import
{
useRouter
}
from
"
vue-router
"
;
const
router
=
useRouter
();
const
node
=
ref
({});
watch
(
()
=>
node
.
value
,
(
n
)
=>
{
console
.
log
(
n
);
},
{
deep
:
true
}
);
const
dataTable
=
ref
(
null
);
const
state
=
reactive
({
stateOptions
:
[
{
name
:
"
全部
"
,
value
:
""
,
},
{
name
:
"
启用
"
,
value
:
1
,
},
{
name
:
"
停用
"
,
value
:
2
,
},
],
// 状态
headers
:
[
{
label
:
"
指标名称
"
,
prop
:
"
indicator_name
"
,
width
:
200
,
},
{
label
:
"
是否启用
"
,
prop
:
"
state
"
,
},
{
label
:
"
创建人
"
,
prop
:
"
created_user
"
,
},
{
label
:
"
创建时间
"
,
prop
:
"
created_time
"
,
width
:
160
,
},
{
label
:
"
操作
"
,
prop
:
"
action
"
,
width
:
136
,
fixed
:
"
right
"
,
},
],
filter
:
{
notice_method
:
""
,
// 通知方式
state
:
""
,
// 状态
time
:
[],
search
:
""
,
page
:
1
,
limit
:
10
,
},
tableRows
:
[],
// 表格数据
selected
:
[],
//选择数据
tableTotal
:
0
,
// 表格数据条数
actionRow
:
null
,
// 当前操作的数据
delDialog
:
false
,
// 删除弹窗
delType
:
0
,
// 1-单条删除 2-批量删除
});
const
changePage
=
(
page
)
=>
{
state
.
filter
.
page
=
page
;
getTableRows
();
};
// 改变页码
const
changeSize
=
(
size
)
=>
{
state
.
filter
.
limit
=
size
;
changePage
(
1
);
};
// 改变每页条数
const
changeSearch
=
(
val
)
=>
{
state
.
filter
.
search
=
val
;
changePage
(
1
);
};
const
filterAction
=
()
=>
{
changePage
(
1
);
};
const
filterClear
=
()
=>
{
state
.
filter
=
{
state
:
""
,
// 状态
time
:
[],
search
:
""
,
page
:
1
,
limit
:
10
,
};
changePage
(
1
);
};
const
selectable
=
(
row
,
index
)
=>
{
return
row
.
state
===
0
;
};
const
getTableRows
=
()
=>
{
let
params
=
{
...
state
.
filter
};
state
.
tableTotal
=
23
;
state
.
tableRows
=
[
{
id
:
1
,
indicator_name
:
"
磁盘使用率
"
,
state
:
1
,
created_user
:
"
李四
"
,
created_time
:
"
2020-01-01 00:00:00
"
,
},
{
id
:
2
,
indicator_name
:
"
磁盘使用率
"
,
state
:
0
,
created_user
:
"
李四
"
,
created_time
:
"
2020-01-01 00:00:00
"
,
},
{
id
:
3
,
indicator_name
:
"
磁盘使用率
"
,
state
:
1
,
created_user
:
"
李四
"
,
created_time
:
"
2020-01-01 00:00:00
"
,
},
];
};
const
goDetail
=
(
row
)
=>
{
router
.
push
({
path
:
"
/forewarning/rule-set/detail
"
,
query
:
{
id
:
row
.
id
,
class_id
:
node
.
value
.
data
.
id
,
},
});
};
// 查看详情
const
selectRows
=
(
data
)
=>
{
state
.
selected
=
data
.
selection
;
};
const
deleteRow
=
(
row
)
=>
{
state
.
actionRow
=
row
;
state
.
delType
=
1
;
state
.
delDialog
=
true
;
console
.
log
(
"
删除
"
);
};
// 删除
const
batchDelete
=
()
=>
{
console
.
log
(
"
批量删除
"
);
if
(
!
state
.
selected
||
state
.
selected
.
length
==
0
)
{
ElMessage
.
error
(
"
请先勾选要删除的数据
"
);
return
;
}
state
.
delType
=
2
;
state
.
delDialog
=
true
;
};
// 批量删除
const
delConfirm
=
()
=>
{
let
ids
=
[];
if
(
state
.
delType
==
1
)
{
ids
.
push
(
state
.
actionRow
.
id
);
}
else
{
ids
=
state
.
selected
.
map
((
e
)
=>
{
return
e
.
id
;
});
}
console
.
log
(
ids
);
state
.
delDialog
=
false
;
setTimeout
(()
=>
{
clearSelected
();
changePage
(
1
);
},
200
);
};
// 确定删除
const
clearSelected
=
()
=>
{
dataTable
.
value
.
clearTable
();
};
// 清空
const
addRule
=
()
=>
{
console
.
log
(
"
新增
"
);
router
.
push
({
path
:
`/forewarning/indicator-config/add`
,
query
:
{
class_id
:
node
.
value
.
data
.
id
,
},
});
};
// 新增规则
const
editRow
=
(
row
)
=>
{
console
.
log
(
"
编辑
"
);
router
.
push
({
path
:
`/forewarning/indicator-config/edit`
,
query
:
{
id
:
row
.
id
,
class_id
:
node
.
value
.
data
.
id
,
},
});
};
// 编辑
const
stateChange
=
(
row
)
=>
{
console
.
log
(
"
更改状态
"
);
// axios
// .put(`/xxx/xxx?id=${row.id}&state=${row.state}`)
// .then((res) => {
// if (res.data.code == 200) {
// ElMessage.success(res.data.msg);
// changePage(1);
// } else {
// ElMessage.error(res.data.data);
// row.state = row.state == 0 ? 1 : 0;
// }
// });
};
onBeforeMount
(()
=>
{
getTableRows
();
});
const
{
headers
,
tableRows
,
tableTotal
,
filter
,
noticeTypes
,
stateOptions
,
delDialog
}
=
toRefs
(
state
);
</
script
>
<
style
lang=
"scss"
scoped
>
.detail_container
{
width
:
100%
;
height
:
calc
(
100vh
-
56px
);
padding
:
0
24px
;
min-height
:
100%
;
&
-main
{
width
:
100%
;
height
:
calc
(
100%
-
46px
);
display
:
flex
;
align-items
:
center
;
padding-bottom
:
16px
;
}
.main-content
{
height
:
100%
;
width
:
calc
(
100%
-
336px
);
background-color
:
#fff
;
box-shadow
:
0
1px
4px
0
rgba
(
0
,
7
,
101
,
0
.15
);
border-radius
:
6px
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
flex-start
;
align-items
:
stretch
;
.filter-group
{
.left-filter
{
flex
:
1
;
display
:
flex
;
justify-content
:
start
;
flex-wrap
:
wrap
;
}
.right-action
{
width
:
144px
;
padding-bottom
:
16px
;
.el-button
{
width
:
64px
;
}
}
}
.table_container
{
flex
:
1
;
width
:
100%
;
padding
:
0
16px
;
position
:
relative
;
.table
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
calc
(
100%
-
64px
);
}
.bg-pagination
{
height
:
64px
;
position
:
absolute
;
right
:
0
;
bottom
:
0
;
padding
:
16px
;
margin-top
:
0
;
}
}
}
}
</
style
>
src/page/main/forewarning/indicator-config/modules/add-form.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"add-form"
>
<el-form
:model=
"state.form"
ref=
"form_ref"
:rules=
"state.rules"
label-width=
"100px"
>
<div
class=
"add-form-item"
>
<el-form-item
label=
"指标名称"
prop=
"name"
>
<el-input
v-model=
"state.form.name"
:disabled=
"isEdit"
placeholder=
"请输入指标名称"
></el-input>
</el-form-item>
<el-form-item
label=
"指标表达式"
prop=
"indicator_expression"
>
<div
class=
"indicator-expression"
>
<bg-code-editor
v-model=
"state.form.indicator_expression"
></bg-code-editor>
</div>
</el-form-item>
<el-form-item
label=
"预警范围"
prop=
""
>
<el-form
:model=
"state.form.warningScopeRows"
ref=
"table_form_ref"
:rules=
"state.tableRules"
label-width=
"0"
style=
"width: 100%"
>
<el-table
:data=
"state.form.warningScopeRows"
stripe
border
empty-text=
"请输入表达式,根据表达式$...$自动生成表格"
>
<el-table-column
v-for=
"header in warningScopeHeaders"
:prop=
"header.prop"
:key=
"header.prop"
:label=
"header.label"
:width=
"header.width"
>
<template
#default
="
{ $index }">
<div
v-if=
"header.prop == 'indicator_tag'"
>
<el-form-item
:prop=
"`[$
{$index}].input_indicator_tag`"
:rules="state.tableRules.input_indicator_tag">
<div
class=
"indictor-tag"
>
<el-popover
popper-class=
"cascader-operation"
placement=
"bottom-start"
>
<template
#reference
>
<el-input
v-model=
"state.form.warningScopeRows[$index].input_indicator_tag"
placeholder=
"请选择指标标签"
@
input=
"getDataTree"
></el-input>
</
template
>
<div
class=
"is-loading"
v-show=
"isLoading"
>
<el-icon>
<Loading
/>
</el-icon>
<span>
加载中
</span>
</div>
<el-cascader-panel
v-show=
"!isLoading"
:options=
"dataTree"
:props=
"indicator_tag_props"
@
change=
"(val) => handleChange(val, $index)"
/>
</el-popover>
</div>
</el-form-item>
</div>
<div
v-else-if=
"header.prop == 'cname'"
>
<el-form-item
:prop=
"`[${$index}].cname`"
:rules=
"state.tableRules.cname"
>
<el-input
style=
"flex: 1"
v-model=
"state.form.warningScopeRows[$index].cname"
:maxlength=
"20"
show-word-limit
placeholder=
"请输入中文名称"
>
</el-input>
</el-form-item>
</div>
<div
v-else-if=
"header.prop == 'is_required'"
>
<el-form-item
:prop=
"`[${$index}].is_required`"
:rules=
"state.tableRules.is_required"
>
<el-select
v-model=
"state.form.warningScopeRows[$index].is_required"
placeholder=
"请选择"
style=
"flex: 1"
>
<el-option
v-for=
"(value, key) in tableSelOptions"
:key=
"key"
:label=
"value"
:value=
"key"
>
</el-option>
</el-select>
</el-form-item>
</div>
<div
v-else-if=
"header.prop == 'is_linkage'"
>
<el-form-item
:prop=
"`[${$index}].is_linkage`"
:rules=
"state.tableRules.is_linkage"
>
<el-select
v-model=
"state.form.warningScopeRows[$index].is_linkage"
placeholder=
"请选择"
style=
"flex: 1"
>
<el-option
v-for=
"(value, key) in tableSelOptions"
:key=
"key"
:label=
"value"
:value=
"key"
>
</el-option>
</el-select>
</el-form-item>
</div>
</template>
</el-table-column>
</el-table>
</el-form>
</el-form-item>
<el-form-item
label=
"预警规则类型"
prop=
"rule_type"
>
<el-select
style=
"flex: 1"
v-model=
"state.form.rule_type"
placeholder=
"请选择"
filterable
@
change=
"changeRuleType"
>
<el-option
v-for=
"(value, key) in ruleTypeOptions"
:key=
"key"
:label=
"value"
:value=
"key"
>
</el-option>
</el-select>
</el-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=
""
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-form-item>
</div>
<el-form-item
label=
"检查周期"
prop=
"inspection_cycle"
>
<el-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>
</el-form-item>
<el-form-item
label=
"是否立即启用"
>
<el-switch
class=
"bg-switch-ele"
v-model=
"state.form.state"
:active-value=
"1"
:inactive-value=
"0"
inline-prompt
active-text=
"是"
inactive-text=
"否"
/>
</el-form-item>
</div>
</el-form>
</div>
</template>
<
script
setup
>
import
{
reactive
,
ref
,
shallowReactive
,
computed
,
nextTick
,
watch
}
from
"
vue
"
;
import
gapTitle
from
"
@/components/gap-title.vue
"
;
import
ManualDistributionForm
from
"
@/components/manual-distribution/form.vue
"
;
import
{
MAX_DAY
,
ONLY_INPUT_NUM
}
from
"
@/components/env.js
"
;
const
props
=
defineProps
({
row
:
{
type
:
Object
,
default
:
null
,
},
});
const
tableSelOptions
=
[
"
否
"
,
"
是
"
];
const
ruleTypeOptions
=
{
empty
:
"
空
"
,
1
:
"
百分比范围
"
,
2
:
"
毫秒范围
"
,
3
:
"
秒范围
"
,
4
:
"
个范围
"
,
5
:
"
温度范围
"
,
};
const
isEdit
=
computed
(()
=>
!!
props
.
row
);
const
history
=
computed
(()
=>
props
.
row
?.
manual_distribution_form
||
null
);
const
typrFormData
=
computed
(()
=>
props
.
row
?.
type_com_ref
||
null
);
const
unitOptions
=
{
s
:
{
label
:
"
秒
"
,
max
:
MAX_DAY
*
24
*
3600
},
m
:
{
label
:
"
分钟
"
,
max
:
MAX_DAY
*
24
*
60
},
h
:
{
label
:
"
小时
"
,
max
:
MAX_DAY
*
24
},
};
const
state
=
reactive
({
form
:
{
name
:
""
,
indicator_expression
:
""
,
rule_type
:
"
empty
"
,
time
:
10
,
unit
:
"
s
"
,
inspection_cycle
:
1
,
warningScopeRows
:
[],
state
:
1
,
},
rules
:
{
name
:
[{
required
:
true
,
message
:
"
请输入指标名称
"
,
trigger
:
"
blur
"
}],
indicator_expression
:
[{
required
:
true
,
message
:
"
请输入指标表达式
"
,
trigger
:
"
blur
"
}],
time
:
[{
required
:
true
,
message
:
"
请输入持续时间
"
,
trigger
:
"
blur
"
}],
},
tableRules
:
{
input_indicator_tag
:
[{
required
:
true
,
message
:
"
请选择
"
,
trigger
:
"
blur
"
}],
cname
:
[{
required
:
true
,
message
:
"
请输入
"
,
trigger
:
"
blur
"
}],
},
});
const
warningScopeHeaders
=
[
{
prop
:
"
key
"
,
label
:
"
变量名称
"
,
width
:
100
,
},
{
prop
:
"
indicator_tag
"
,
label
:
"
指标标签
"
,
},
{
prop
:
"
cname
"
,
label
:
"
中文名称
"
,
},
{
prop
:
"
is_required
"
,
label
:
"
是否必填
"
,
width
:
150
,
},
{
prop
:
"
is_linkage
"
,
label
:
"
是否联动
"
,
width
:
150
,
},
];
const
dataTree
=
ref
([]);
const
isLoading
=
ref
(
false
);
const
getDataTree
=
()
=>
{
isLoading
.
value
=
true
;
setTimeout
(()
=>
{
const
res
=
{
code
:
200
,
msg
:
"
OK
"
,
data
:
[
{
name
:
"
http_requests_total
"
,
children
:
[
{
name
:
"
instance
"
,
value
:
"
localhost:2023
"
,
},
{
name
:
"
job
"
,
value
:
"
prometheus
"
,
},
{
name
:
"
method
"
,
value
:
"
GET
"
,
},
],
},
{
name
:
"
system_monitor_counter
"
,
children
:
[
{
name
:
"
instance
"
,
value
:
"
localhost:2023
"
,
},
{
name
:
"
job
"
,
value
:
"
prometheus
"
,
},
{
name
:
"
system_id
"
,
value
:
"
YW230177
"
,
},
{
name
:
"
user_id
"
,
value
:
"
xc-admin
"
,
},
],
},
],
};
dataTree
.
value
=
res
.
data
;
isLoading
.
value
=
false
;
},
2000
);
};
const
handleChange
=
async
(
val
,
index
)
=>
{
state
.
form
.
warningScopeRows
[
index
].
indicator_scope
=
val
[
0
];
state
.
form
.
warningScopeRows
[
index
].
input_indicator_tag
=
val
[
1
];
state
.
form
.
warningScopeRows
[
index
].
indicator_tag
=
val
[
1
];
};
const
indicator_tag_props
=
{
value
:
"
name
"
,
label
:
"
name
"
,
};
const
tableCreateKeys
=
ref
([]);
watch
(
()
=>
state
.
form
.
indicator_expression
,
(
n
)
=>
{
tableCreateKeys
.
value
=
n
?.
match
(
/
\$(
.+
?)\$
/g
)
||
[];
let
arr
=
[];
tableCreateKeys
.
value
.
forEach
((
e
)
=>
{
let
i
=
state
.
form
.
warningScopeRows
.
findIndex
((
el
)
=>
el
.
key
==
e
);
arr
.
push
(
i
!=
-
1
?
state
.
form
.
warningScopeRows
[
i
]
:
{
key
:
e
,
input_indicator_tag
:
""
,
indicator_scope
:
""
,
indicator_tag
:
""
,
cname
:
""
,
is_required
:
1
,
is_linkage
:
0
,
}
);
});
state
.
form
.
warningScopeRows
=
arr
;
}
);
const
inputNum
=
()
=>
{
state
.
form
.
time
=
state
.
form
.
time
.
replace
(
/
[^\d]
/g
,
""
);
let
time
=
+
state
.
form
.
time
;
let
{
max
}
=
unitOptions
[
state
.
form
.
unit
];
if
(
time
>
+
max
)
{
state
.
form
.
time
=
max
;
}
};
const
inspectionCycleOptions
=
ref
([
1
,
3
,
5
,
10
,
20
]);
const
form_ref
=
ref
(
null
);
const
table_form_ref
=
ref
(
null
);
const
Submit
=
async
()
=>
{
let
form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
let
table_form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
table_form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
if
(
form_valid
&&
table_form_valid
)
{
return
{
...
state
.
form
,
};
}
return
;
};
const
changeRuleType
=
()
=>
{};
watch
(
()
=>
props
.
row
,
async
(
n
)
=>
{
if
(
!
n
)
return
;
state
.
form
.
warningScopeRows
=
n
.
warningScopeRows
.
map
((
e
)
=>
{
return
{
key
:
e
.
key
,
input_indicator_tag
:
e
.
input_indicator_tag
,
indicator_scope
:
e
.
indicator_scope
,
indicator_tag
:
e
.
indicator_tag
,
cname
:
e
.
cname
,
is_required
:
e
.
is_required
||
1
,
is_linkage
:
e
.
is_linkage
||
0
,
};
})
||
[];
state
.
form
.
name
=
n
.
name
;
state
.
form
.
rule_type
=
n
.
rule_type
||
"
empty
"
;
state
.
form
.
inspection_cycle
=
n
.
inspection_cycle
||
1
;
state
.
form
.
state
=
n
.
state
||
1
;
state
.
form
.
time
=
n
.
time
||
10
;
state
.
form
.
unit
=
n
.
unit
||
"
s
"
;
state
.
form
.
indicator_expression
=
n
.
indicator_expression
;
},
{
deep
:
true
,
immediate
:
true
}
);
defineExpose
({
Submit
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.add-form
{
:deep
(
.gap-title
)
{
margin-bottom
:
16px
;
}
&
-item
{
max-width
:
1080px
;
width
:
100%
;
.indicator-expression
{
height
:
300px
;
width
:
100%
;
:deep
(
.vue-ace-editor
)
{
margin-top
:
0
;
}
}
.duration
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
:deep
(
.el-form-item__content
)
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
>
.el-input
{
flex
:
1
;
width
:
80px
;
}
}
.no-el-label
{
:deep
(
.el-form-item__content
)
{
.el-select
{
width
:
80px
;
}
}
}
}
:deep
(
.el-switch__inner
)
{
.is-hide
{
display
:
none
;
}
}
:deep
(
.el-input-group__append
,
.el-input-group__prepend
)
{
border-radius
:
4px
;
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
}
.no-el-label
{
:deep
(
.el-form-item__content
)
{
margin-left
:
0
!
important
;
}
}
.manual-distribution-form
{
:deep
(
.el-form-item
)
{
&
:not
(
:last-child
)
{
margin-bottom
:
18px
;
}
}
}
.indictor-tag
{
width
:
100%
;
}
</
style
>
<
style
lang=
"scss"
>
.el-form-item
{
min-height
:
36px
;
label
{
height
:
36px
;
line-height
:
36px
;
}
.el-input__inner
{
min-height
:
34px
;
}
}
.cascader-operation
{
width
:
auto
!
important
;
padding
:
0
!
important
;
min-width
:
180px
!
important
;
position
:
relative
;
min-height
:
204px
;
.is-loading
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
gap
:
4px
;
svg
{
animation
:
rotate
3s
linear
infinite
;
}
@keyframes
rotate
{
from
{
transform
:
rotate
(
0deg
);
}
to
{
transform
:
rotate
(
360deg
);
}
}
}
.el-scrollbar
{
border-radius
:
0
;
}
.el-cascader-panel
{
border
:
0
!
important
;
box-shadow
:
none
!
important
;
}
}
</
style
>
src/page/main/forewarning/indicator-config/modules/interface.js
0 → 100644
View file @
302fb2f2
import
{
ElMessage
}
from
"
element-plus
"
;
const
setParams
=
(
res
,
{
id
,
class_id
})
=>
{
let
params
=
{
class_id
,
metric_name
:
res
.
name
,
expr
:
res
.
indicator_expression
,
alert_range
:
res
.
warningScopeRows
.
map
((
e
)
=>
{
return
{
variable_name
:
e
.
key
,
metric_name
:
e
.
indicator_scope
,
metric_label
:
e
.
indicator_tag
,
chinese_name
:
e
.
cname
,
is_required
:
e
.
is_required
==
1
,
is_linked
:
e
.
is_linkage
==
1
,
};
})
||
[],
duration
:
res
.
time
,
duration_unit
:
res
.
unit
,
check_period
:
res
.
inspection_cycle
,
is_enabled
:
res
.
state
,
alert_rule_type
:
res
.
rule_type
,
}
if
(
id
)
{
params
.
id
=
id
}
return
params
;
}
export
const
URL
=
"
https://so.wodcloud.co/v1/api/metric_config
"
export
const
Save
=
(
res
,
p
)
=>
{
let
params
=
setParams
(
res
,
p
);
console
.
log
(
"
params:
"
,
params
);
// axios[id ? 'put' : 'post'](URL, params).then(res => {
// if(res.data.code == 200){
// console.log('success');
// }else{
// ElMessage.error(res.data.data)
// }
// })
}
\ No newline at end of file
src/page/main/forewarning/indicator-config/modules/slide.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"main-slide"
>
<div
class=
"slide-title"
>
预警对象
</div>
<div
class=
"slide-search"
>
<el-input
v-model=
"search"
placeholder=
"请输入关键字"
clearable
@
input=
"Search"
@
clear=
"Search"
>
<template
#prefix
>
<bg-icon
style=
"font-size: 12px; color: #404a62"
icon=
"#bg-ic-search"
></bg-icon>
</
template
>
</el-input>
<el-button
type=
"primary"
size=
"default"
@
click=
"Add"
>
<bg-icon
style=
"font-size: 12px; color: #fff"
icon=
"#bg-ic-add"
></bg-icon>
</el-button>
</div>
<div
class=
"slide-tree bg-scroll"
>
<el-tree
ref=
"treeRef"
default-expand-all
:data=
"slideTree"
:current-node-key=
"selectId"
node-key=
"id"
empty-text=
"暂无数据"
:highlight-current=
"true"
:expand-on-click-node=
"false"
:filter-node-method=
"filterNode"
@
node-click=
"treeNodeChoose"
>
<
template
#default
="{
node
,
data
}"
>
<span
class=
"custom-tree-node"
>
<span>
{{
node
.
label
}}
</span>
<el-popover
popper-class=
"tree-operation"
placement=
"right-start"
:width=
"120"
trigger=
"click"
>
<template
#reference
>
<span
class=
"operation"
@
click.stop=
""
>
<bg-icon
style=
"font-size: 12px; color: #404a62"
icon=
"#bg-ic-s-more"
></bg-icon>
</span>
</
template
>
<
template
#default
>
<ul
class=
"operation-lists"
>
<li
v-for=
"(value, key) in operations"
:key=
"key"
@
click.stop=
"Operation(key, node, data)"
>
<el-button
link
:disabled=
"value.disabled(node, data)"
>
{{
value
.
label
(
node
)
}}
</el-button>
</li>
</ul>
</
template
>
</el-popover>
</span>
</template>
</el-tree>
</div>
</div>
<el-dialog
:close-on-click-modal=
"false"
v-model=
"addWarnType"
width=
"558px"
:before-close=
"Cancel"
>
<
template
#header
>
<GapTitle
:title=
"isEditWarnType ? '编辑预警分类' : '新增预警分类'"
></GapTitle>
</
template
>
<div
style=
"padding-top: 20px"
>
<el-form
:model=
"state.form"
ref=
"add_warn_type_form"
:rules=
"state.rules"
label-width=
"80px"
>
<el-form-item
label=
"预警分类"
prop=
"name"
>
<el-input
v-model=
"state.form.name"
placeholder=
"请输入预警分类"
maxlength=
"20"
show-word-limit
></el-input>
</el-form-item>
</el-form>
</div>
<
template
#footer
>
<el-button
size=
"default"
@
click=
"Cancel"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"Save"
>
保存
</el-button>
</
template
>
</el-dialog>
<el-dialog
:close-on-click-modal=
"false"
v-model=
"addWarnTarget"
width=
"558px"
:before-close=
"Cancel"
>
<
template
#header
>
<GapTitle
:title=
"isEditWarnType ? '编辑预警对象' : '新增预警对象'"
></GapTitle>
</
template
>
<div
style=
"padding-top: 20px"
>
<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-select>
</el-form-item>
<el-form-item
label=
"预警对象"
prop=
"target"
>
<el-input
v-model=
"state.form_target.target"
placeholder=
"请输入预警对象"
maxlength=
"20"
show-word-limit
></el-input>
</el-form-item>
</el-form>
</div>
<
template
#footer
>
<el-button
size=
"default"
@
click=
"CancelAddWarnTarget"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"SaveAddWarnTarget"
>
保存
</el-button>
</
template
>
</el-dialog>
<el-dialog
v-model=
"delWarnType"
width=
"400px"
:before-close=
"Cancel"
>
<
template
#header
>
<GapTitle
title=
"删除预警分类"
></GapTitle>
</
template
>
<div
style=
"padding: 20px 0"
>
是否确定删除 {{ activeTree.own.label }} 这个预警分类
</div>
<
template
#footer
>
<el-button
size=
"default"
@
click=
"CancelDel"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"ConfirmDel"
>
确定
</el-button>
</
template
>
</el-dialog>
</template>
<
script
setup
>
import
{
nextTick
,
onBeforeMount
,
reactive
,
ref
}
from
"
vue
"
;
import
GapTitle
from
"
@/components/gap-title.vue
"
;
const
props
=
defineProps
({
modelValue
:
{
type
:
Object
,
default
:
()
=>
({}),
},
});
const
search
=
ref
(
""
);
let
slideTree
=
ref
([]);
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
filterNode
=
(
value
,
data
)
=>
{
if
(
!
value
)
return
data
;
return
data
.
label
.
includes
(
value
);
};
const
Search
=
async
()
=>
{
await
nextTick
();
treeRef
.
value
.
filter
(
search
.
value
);
};
const
Add
=
()
=>
{
addWarnType
.
value
=
true
;
};
const
emits
=
defineEmits
([
"
undate:modelValue
"
]);
const
treeNodeChoose
=
(
data
,
node
)
=>
{
if
(
node
.
level
==
1
)
return
;
emits
(
"
update:modelValue
"
,
{
data
,
node
});
};
const
getBrotherNodes
=
(
node
)
=>
{
let
arr
=
[];
if
(
node
.
level
==
1
)
{
arr
=
slideTree
.
value
;
}
else
{
arr
=
node
.
parent
.
data
.
children
;
}
return
arr
;
};
const
operations
=
{
1
:
{
label
:
(
node
)
=>
{
return
node
.
level
==
1
?
"
编辑预警分类
"
:
"
编辑预警对象
"
;
},
disabled
:
()
=>
{
return
false
;
},
},
2
:
{
label
:
()
=>
"
新增预警对象
"
,
disabled
:
()
=>
{
return
false
;
},
},
3
:
{
label
:
()
=>
"
删除
"
,
disabled
:
()
=>
{
return
false
;
},
},
4
:
{
label
:
()
=>
"
上移
"
,
disabled
:
(
node
,
data
)
=>
{
let
arr
=
getBrotherNodes
(
node
);
let
id
=
data
.
id
;
let
i
=
arr
.
findIndex
((
e
)
=>
e
.
id
==
id
);
return
0
==
i
;
},
},
5
:
{
label
:
()
=>
"
下移
"
,
disabled
:
(
node
,
data
)
=>
{
let
arr
=
getBrotherNodes
(
node
);
let
id
=
data
.
id
;
let
i
=
arr
.
findIndex
((
e
)
=>
e
.
id
==
id
);
return
arr
.
length
-
1
==
i
;
},
},
};
const
addWarnType
=
ref
(
false
);
const
addWarnTarget
=
ref
(
false
);
const
delWarnType
=
ref
(
false
);
const
isEditWarnType
=
ref
(
false
);
const
activeTree
=
ref
({});
const
Operation
=
(
key
,
node
,
data
)
=>
{
activeTree
.
value
=
{
node
,
own
:
data
,
data
:
node
.
level
==
1
?
data
:
node
.
parent
.
data
,
};
let
operation_handled_fn
=
{
1
:
async
()
=>
{
if
(
node
.
level
==
1
)
{
addWarnType
.
value
=
true
;
await
nextTick
();
state
.
form
.
name
=
data
.
label
;
}
else
{
addWarnTarget
.
value
=
true
;
await
nextTick
();
state
.
form_target
.
type
=
activeTree
.
value
.
data
.
id
;
state
.
form_target
.
target
=
data
.
label
;
}
isEditWarnType
.
value
=
true
;
},
2
:
()
=>
{
addWarnTarget
.
value
=
true
;
isEditWarnType
.
value
=
false
;
state
.
form_target
.
type
=
activeTree
.
value
.
data
.
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
];
},
5
:
()
=>
{
let
arr
=
getBrotherNodes
(
node
);
let
id
=
data
.
id
;
let
i
=
arr
.
findIndex
((
e
)
=>
e
.
id
==
id
);
let
next
=
arr
[
i
+
1
];
},
};
operation_handled_fn
[
key
]();
};
const
add_warn_type_form
=
ref
(
null
);
const
add_warn_target_form
=
ref
(
null
);
const
state
=
reactive
({
form
:
{
name
:
""
,
},
form_target
:
{
type
:
""
,
target
:
""
,
},
rules
:
{
name
:
[{
required
:
true
,
message
:
"
请输入预警分类
"
,
trigger
:
"
blur
"
}],
},
target_rules
:
{
type
:
[{
required
:
true
,
message
:
"
请选择预警分类
"
,
trigger
:
"
change
"
}],
target
:
[{
required
:
true
,
message
:
"
请输入预警对象
"
,
trigger
:
"
blur
"
}],
},
});
const
Cancel
=
async
()
=>
{
add_warn_type_form
.
value
.
resetFields
();
await
nextTick
();
addWarnType
.
value
=
false
;
};
const
Save
=
()
=>
{
add_warn_type_form
.
value
.
validate
((
valid
)
=>
{
if
(
valid
)
{
console
.
log
(
state
.
form
);
Cancel
();
}
else
{
return
false
;
}
});
};
const
CancelAddWarnTarget
=
async
()
=>
{
add_warn_target_form
.
value
.
resetFields
();
await
nextTick
();
addWarnTarget
.
value
=
false
;
};
const
SaveAddWarnTarget
=
()
=>
{
add_warn_target_form
.
value
.
validate
((
valid
)
=>
{
if
(
valid
)
{
console
.
log
(
state
.
form_target
);
Cancel
();
}
else
{
return
false
;
}
});
};
const
CancelDel
=
()
=>
{
delWarnType
.
value
=
false
;
};
const
ConfirmDel
=
()
=>
{
console
.
log
(
activeTree
.
value
.
own
);
CancelDel
();
};
onBeforeMount
(()
=>
{
getSlideTree
();
});
</
script
>
<
style
lang=
"scss"
scoped
>
.main-slide
{
width
:
320px
;
height
:
100%
;
background-color
:
#fff
;
box-shadow
:
0
1px
4px
0
rgba
(
0
,
7
,
101
,
0
.15
);
border-radius
:
6px
;
margin-right
:
16px
;
overflow
:
hidden
;
.slide-title
{
height
:
40px
;
background-color
:
#f7f7f9
;
display
:
flex
;
align-items
:
center
;
padding-left
:
16px
;
}
.slide-search
{
padding
:
16px
;
display
:
flex
;
align-items
:
center
;
:deep
(
.el-button
)
{
margin-left
:
8px
;
}
}
.slide-tree
{
height
:
calc
(
100%
-
108px
);
:deep
(
.el-tree-node__content
)
{
height
:
36px
;
}
.custom-tree-node
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
font-size
:
14px
;
overflow
:
hidden
;
&
:hover
{
.operation
{
visibility
:
visible
;
}
}
.operation
{
display
:
flex
;
visibility
:
hidden
;
width
:
36px
;
height
:
36px
;
align-items
:
center
;
justify-content
:
center
;
box-shadow
:
-4px
0
4px
0px
rgba
(
0
,
7
,
101
,
0
.15
);
}
}
}
}
.add-warn-type-form
{
padding-top
:
20px
;
}
</
style
>
<
style
lang=
"scss"
>
.tree-operation
{
padding
:
4px
0
!
important
;
min-width
:
0
!
important
;
.operation-lists
{
li
{
line-height
:
34px
;
cursor
:
pointer
;
transition
:
all
300ms
;
.el-button
{
width
:
100%
;
height
:
34px
;
justify-content
:
flex-start
;
padding
:
0
16px
;
}
&
:hover
{
background-color
:
#f2f3f7
;
.el-button
{
&
:not
(
.is-disabled
)
{
color
:
#3759be
;
}
}
}
}
}
}
</
style
>
src/page/main/forewarning/list/index.vue
View file @
302fb2f2
...
...
@@ -87,6 +87,7 @@
:headers=
"headers"
:rows=
"tableRows"
@
selectAc=
"selectRows"
:selectable=
"selectable"
:isIndex=
"true"
:select=
"true"
:stripe=
"true"
>
...
...
@@ -398,7 +399,9 @@ const filterClear = () => {
};
changePage
(
1
);
};
// 重置筛选项
const
selectable
=
(
row
,
index
)
=>
{
return
row
.
state
===
0
;
};
const
getTableRows
=
()
=>
{
let
params
=
{
...
state
.
filter
};
// axios
...
...
src/page/main/forewarning/rule-set/add/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"detail_container"
>
<bg-breadcrumb></bg-breadcrumb>
<div
class=
"main_container"
>
<div
class=
"add-form-main bg-scroll"
>
<add-form
ref=
"add_form"
></add-form>
</div>
<div
class=
"add-btns"
>
<el-button
size=
"default"
@
click=
"Cancle"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"Save"
>
保存
</el-button>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
"
vue
"
;
import
{
useRouter
}
from
"
vue-router
"
;
import
bgBreadcrumb
from
"
@/components/bg-breadcrumb.vue
"
;
import
addForm
from
"
../modules/add-form.vue
"
;
const
router
=
useRouter
();
const
Cancle
=
()
=>
{
router
.
go
(
-
1
);
};
const
add_form
=
ref
(
null
);
const
Save
=
async
()
=>
{
let
res
=
await
add_form
.
value
.
Submit
();
if
(
!
res
)
return
;
console
.
log
(
"
res:
"
,
res
);
};
</
script
>
<
style
lang=
"scss"
scoped
>
.detail_container
{
width
:
100%
;
height
:
calc
(
100vh
-
56px
);
padding
:
0
24px
16px
;
min-height
:
100%
;
.main_container
{
height
:
calc
(
100%
-
46px
);
padding
:
0
;
.add-form-main
{
padding
:
24px
;
height
:
calc
(
100%
-
68px
);
}
.add-btns
{
height
:
68px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
border-top
:
1px
solid
#ddd
;
padding
:
0
24px
;
}
}
}
</
style
>
src/page/main/forewarning/rule-set/detail/index.vue
View file @
302fb2f2
<
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"
>
<Info
:labelData=
"warning_scope_label"
:valueData=
"watning_scope_data"
>
</Info>
</div>
<gap-title
:hasLine=
"true"
title=
"预警规则"
></gap-title>
<div
class=
"info"
>
<bg-table
border
ref=
"ruletable"
:headers=
"ruleHeaders"
:rows=
"ruleRows"
height=
"100%"
>
</bg-table>
</div>
<gap-title
:hasLine=
"true"
title=
"高级配置"
>
</gap-title>
<div
class=
"info"
>
<Info
:labelData=
"advanced_label"
:valueData=
"advanced_data"
>
</Info>
</div>
<gap-title
:hasLine=
"true"
title=
"预警工单推送"
>
</gap-title>
<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>
</
template
>
</Info>
<div
class=
"push-lists"
>
<bg-table
border
ref=
"pushtable"
:headers=
"pushHeaders"
:rows=
"pushRows"
height=
"100%"
:isIndex=
"true"
>
</bg-table>
</div>
</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_rule_name
"
,
},
{
label
:
"
启用状态
"
,
prop
:
"
status
"
,
},
],
[
{
label
:
"
预警对象
"
,
prop
:
"
warning_target
"
,
},
{
label
:
"
预警分类
"
,
prop
:
"
warning_type
"
,
},
],
[
{
label
:
"
预警指标
"
,
prop
:
"
warning_index
"
,
},
{
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
"
,
};
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
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
ruleHeaders
=
[
{
prop
:
"
warning_threshold
"
,
label
:
"
预警阈值
"
,
},
{
prop
:
"
risk_level
"
,
label
:
"
风险程度
"
,
},
];
const
ruleRows
=
[
{
warning_threshold
:
"
12% - 50%
"
,
risk_level
:
"
较大风险
"
,
},
{
warning_threshold
:
"
50% - 100%
"
,
risk_level
:
"
重大风险
"
,
},
];
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
;
}
}
}
}
.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
>
src/page/main/forewarning/rule-set/edit/index.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"detail_container"
>
<bg-breadcrumb></bg-breadcrumb>
<div
class=
"main_container"
>
<div
class=
"add-form-main bg-scroll"
>
<add-form
ref=
"add_form"
:row=
"infoData"
></add-form>
</div>
<div
class=
"add-btns"
>
<el-button
size=
"default"
@
click=
"Cancle"
>
取消
</el-button>
<el-button
type=
"primary"
size=
"default"
@
click=
"Save"
>
保存
</el-button>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
"
vue
"
;
import
{
useRouter
}
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,
// },
// ],
// },
// });
const
router
=
useRouter
();
const
Cancle
=
()
=>
{
router
.
go
(
-
1
);
};
const
add_form
=
ref
(
null
);
const
Save
=
async
()
=>
{
let
res
=
await
add_form
.
value
.
Submit
();
if
(
!
res
)
return
;
console
.
log
(
"
res:
"
,
res
);
};
</
script
>
<
style
lang=
"scss"
scoped
>
.detail_container
{
width
:
100%
;
height
:
calc
(
100vh
-
56px
);
padding
:
0
24px
16px
;
min-height
:
100%
;
.main_container
{
height
:
calc
(
100%
-
46px
);
padding
:
0
;
.add-form-main
{
padding
:
24px
;
height
:
calc
(
100%
-
68px
);
}
.add-btns
{
height
:
68px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
border-top
:
1px
solid
#ddd
;
padding
:
0
24px
;
}
}
}
</
style
>
src/page/main/forewarning/rule-set/index.vue
View file @
302fb2f2
...
...
@@ -69,6 +69,7 @@
:headers=
"headers"
:rows=
"tableRows"
@
selectAc=
"selectRows"
:selectable=
"selectable"
:isIndex=
"true"
:select=
"true"
:stripe=
"true"
>
...
...
@@ -243,7 +244,12 @@ const batchDelete = () => {
const
goDetail
=
(
row
)
=>
{
console
.
log
(
"
去详情
"
);
router
.
push
(
`/forewarning/rule-set/detail?id=
${
row
.
id
}
`
);
router
.
push
({
path
:
"
/forewarning/rule-set/detail
"
,
query
:
{
id
:
row
.
id
,
},
});
};
// 查看详情
const
changeSearch
=
(
val
)
=>
{
...
...
@@ -267,6 +273,9 @@ const filterClear = () => {
changePage
(
1
);
};
// 重置筛选项
const
selectable
=
(
row
,
index
)
=>
{
return
row
.
state
===
0
;
};
const
getTableRows
=
()
=>
{
let
params
=
{
...
state
.
filter
};
// axios
...
...
@@ -349,12 +358,19 @@ const stateChange = (row) => {
const
addRule
=
()
=>
{
console
.
log
(
"
新增
"
);
// router.push(`/xxx/xxx`);
router
.
push
({
path
:
`/forewarning/rule-set/add`
,
});
};
// 新增规则
const
editRow
=
(
row
)
=>
{
console
.
log
(
"
编辑
"
);
// router.push(`/xxx/xxx?id=${row.id}`);
router
.
push
({
path
:
`/forewarning/rule-set/edit`
,
query
:
{
id
:
row
.
id
,
},
});
};
// 编辑
const
deleteRow
=
(
row
)
=>
{
...
...
src/page/main/forewarning/rule-set/modules/add-form.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"add-form"
>
<el-form
:model=
"state.form"
ref=
"form_ref"
:rules=
"state.rules"
label-width=
"110px"
>
<div
class=
"add-form-item"
>
<el-form-item
label=
"预警规则名称"
prop=
"name"
>
<el-input
v-model=
"state.form.name"
:disabled=
"isEdit"
placeholder=
"请输入预警规则名称"
></el-input>
</el-form-item>
<el-form-item
label=
"检测类型"
prop=
"type"
>
<el-button-group>
<el-button
v-for=
"(value, key) in types"
:key=
"key"
:type=
"state.form.type_key == key ? 'primary' : ''"
size=
"small"
@
click=
"changeType(key)"
:disabled=
"isEdit"
>
{{
value
}}
</el-button>
</el-button-group>
</el-form-item>
</div>
<component
ref=
"type_com_ref"
:is=
"typeCom[state.form.type_key]"
:isEdit=
"isEdit"
:form=
"typrFormData"
></component>
<gap-title
:hasLine=
"true"
title=
"高级配置"
></gap-title>
<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-form-item>
</div>
<el-form-item
label=
"检查周期"
prop=
"inspection_cycle"
>
<el-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>
</el-form-item>
</div>
<gap-title
:hasLine=
"true"
title=
"预警工单推送"
></gap-title>
<div
class=
"add-form-item"
>
<el-form-item
class=
"no-el-label"
label=
""
prop=
"push_method"
>
<div
style=
"width: 100%"
>
<ManualDistributionForm
ref=
"manual_distribution_form"
class=
"manual-distribution-form"
:noElLabel=
"false"
methodLabel=
"预警通知方式"
:history=
"history"
/>
</div>
</el-form-item>
<el-form-item
label=
"消息推送次数"
>
<el-input
style=
"flex: 1"
v-model=
"state.form.push_num"
placeholder=
"请输入消息推送次数"
clearable
>
<template
#append
>
次
</
template
>
</el-input>
</el-form-item>
<el-form-item
label=
"消息推送频率"
>
<el-input
style=
"flex: 1"
v-model=
"state.form.push_frequency"
placeholder=
"请输入消息推送频率"
clearable
>
<
template
#append
>
分钟
</
template
>
</el-input>
</el-form-item>
<el-form-item
label=
"是否立即启用"
prop=
""
>
<el-switch
v-model=
"state.form.enabled"
inline-prompt
active-text=
"是"
inactive-text=
"否"
:active-value=
"true"
:inactive-value=
"false"
>
</el-switch>
</el-form-item>
</div>
</el-form>
</div>
</template>
<
script
setup
>
import
{
reactive
,
ref
,
shallowReactive
,
computed
,
nextTick
,
watch
}
from
"
vue
"
;
import
gapTitle
from
"
@/components/gap-title.vue
"
;
import
ManualDistributionForm
from
"
@/components/manual-distribution/form.vue
"
;
import
Static
from
"
./static.vue
"
;
import
Custom
from
"
./custom.vue
"
;
import
{
MAX_DAY
}
from
"
@/components/env.js
"
;
const
props
=
defineProps
({
row
:
{
type
:
Object
,
default
:
null
,
},
});
const
isEdit
=
computed
(()
=>
!!
props
.
row
);
const
history
=
computed
(()
=>
props
.
row
?.
manual_distribution_form
||
null
);
const
typrFormData
=
computed
(()
=>
props
.
row
?.
type_com_ref
||
null
);
const
manual_distribution_form
=
ref
(
null
);
const
typeCom
=
shallowReactive
({
static
:
Static
,
custom
:
Custom
,
});
const
unitOptions
=
{
s
:
{
label
:
"
秒
"
,
max
:
MAX_DAY
*
24
*
3600
},
m
:
{
label
:
"
分钟
"
,
max
:
MAX_DAY
*
24
*
60
},
h
:
{
label
:
"
小时
"
,
max
:
MAX_DAY
*
24
},
};
const
state
=
reactive
({
form
:
{
name
:
""
,
type_key
:
"
static
"
,
time
:
10
,
unit
:
"
s
"
,
inspection_cycle
:
1
,
push_num
:
1
,
push_frequency
:
60
,
enabled
:
true
,
},
rules
:
{
name
:
[{
required
:
true
,
message
:
"
请输入预警规则名称
"
,
trigger
:
"
blur
"
}],
time
:
[{
required
:
true
,
message
:
"
请输入持续时间
"
,
trigger
:
"
blur
"
}],
},
});
const
inputNum
=
()
=>
{
state
.
form
.
time
=
state
.
form
.
time
.
replace
(
/
[^\d]
/g
,
""
);
let
time
=
+
state
.
form
.
time
;
let
{
max
}
=
unitOptions
[
state
.
form
.
unit
];
if
(
time
>
+
max
)
{
state
.
form
.
time
=
max
;
}
};
const
types
=
{
static
:
"
静态阈值
"
,
custom
:
"
自定义
"
,
};
const
changeType
=
async
(
key
)
=>
{
state
.
form
.
type_key
=
key
;
form_ref
.
value
.
clearValidate
();
};
const
durationOptions
=
[
{
id
:
1
,
name
:
"
直接产生预警
"
,
},
{
id
:
2
,
name
:
"
当预警持续
"
,
},
];
const
timeOptions
=
[
10
,
20
,
60
,
120
,
180
,
300
];
const
inspectionCycleOptions
=
ref
([
1
,
3
,
5
,
10
,
20
]);
const
form_ref
=
ref
(
null
);
const
type_com_ref
=
ref
(
null
);
const
Submit
=
async
()
=>
{
let
form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
let
type_com_ref_valid
=
await
type_com_ref
.
value
.
Submit
();
let
manual_distribution_form_valid
=
await
manual_distribution_form
.
value
.
Submit
();
if
(
form_valid
&&
type_com_ref_valid
&&
manual_distribution_form_valid
)
{
return
{
...
state
.
form
,
type_com_ref
:
type_com_ref
.
value
?.
form
||
{},
manual_distribution_form
:
manual_distribution_form
.
value
?.
form
||
{},
};
}
return
;
};
watch
(
()
=>
props
.
row
,
(
n
)
=>
{
if
(
!
n
)
return
;
state
.
form
.
name
=
n
.
name
;
state
.
form
.
type_key
=
n
.
type_key
;
state
.
form
.
unit
=
n
.
unit
;
state
.
form
.
time
=
n
.
time
||
10
;
state
.
form
.
inspection_cycle
=
n
.
inspection_cycle
||
1
;
state
.
form
.
push_num
=
n
.
push_num
||
1
;
state
.
form
.
push_frequency
=
n
.
push_frequency
||
60
;
state
.
form
.
enabled
=
n
.
enabled
||
false
;
},
{
deep
:
true
,
immediate
:
true
}
);
defineExpose
({
Submit
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.add-form
{
:deep
(
.gap-title
)
{
margin-bottom
:
16px
;
}
&
-item
{
max-width
:
1080px
;
width
:
100%
;
padding-left
:
8px
;
.indicator-expression
{
height
:
300px
;
width
:
100%
;
:deep
(
.vue-ace-editor
)
{
margin-top
:
0
;
}
}
.duration
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
:deep
(
.el-form-item__content
)
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
>
.el-input
{
flex
:
1
;
width
:
80px
;
}
}
.no-el-label
{
:deep
(
.el-form-item__content
)
{
.el-select
{
width
:
80px
;
}
}
}
}
:deep
(
.el-switch__inner
)
{
.is-hide
{
display
:
none
;
}
}
:deep
(
.el-input-group__append
,
.el-input-group__prepend
)
{
border-radius
:
4px
;
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
}
.no-el-label
{
:deep
(
.el-form-item__content
)
{
margin-left
:
0
!
important
;
}
}
.manual-distribution-form
{
:deep
(
.el-form-item
)
{
&
:not
(
:last-child
)
{
margin-bottom
:
18px
;
}
}
}
</
style
>
<
style
lang=
"scss"
>
.el-form-item
{
min-height
:
36px
;
label
{
height
:
36px
;
line-height
:
36px
;
}
.el-input__inner
{
min-height
:
34px
;
}
}
</
style
>
src/page/main/forewarning/rule-set/modules/common-com.vue
0 → 100644
View file @
302fb2f2
<
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
>
src/page/main/forewarning/rule-set/modules/custom.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"custom-form"
>
<el-form
:model=
"state.form"
ref=
"form_ref"
:rules=
"state.rules"
label-width=
"110px"
>
<div
class=
"custom-form-item"
>
<el-form-item
label=
"预警对象"
prop=
"warn_target"
>
<el-input
v-model=
"state.form.warn_target"
placeholder=
"请输入"
:disabled=
"isEdit"
:maxlength=
"20"
show-word-limit
clearable
@
change=
"changeWarnCustomTarget"
></el-input>
</el-form-item>
<el-form-item
label=
"预警分类"
prop=
"warn_type"
>
<el-input
v-model=
"state.form.warn_type"
placeholder=
"请输入"
:disabled=
"isEdit"
clearable
:maxlength=
"20"
show-word-limit
@
change=
"changeWarnCustomType"
></el-input>
</el-form-item>
<el-form-item
label=
"预警指标"
prop=
"warn_indicator"
>
<el-input
v-model=
"state.form.warn_indicator"
placeholder=
"请输入"
:disabled=
"isEdit"
:maxlength=
"30"
show-word-limit
clearable
@
change=
"changeWarnCustomType"
></el-input>
</el-form-item>
</div>
<gap-title
:hasLine=
"true"
title=
"指标表达式"
>
</gap-title>
<div
class=
"custom-form-item"
>
<el-form-item
label=
""
prop=
"indicator_expression"
>
<div
class=
"indicator-expression"
>
<bg-code-editor
v-model=
"state.form.indicator_expression"
></bg-code-editor>
</div>
</el-form-item>
</div>
<gap-title
:hasLine=
"true"
title=
"预警规则"
></gap-title>
<div
class=
"add-form-item"
>
<el-form-item
label=
"预警规则类型"
prop=
"rule_type"
>
<el-select
style=
"flex: 1"
v-model=
"state.form.rule_type"
placeholder=
"请选择"
filterable
@
change=
"changeRuleType"
>
<el-option
v-for=
"(value, key) in ruleTypeOptions"
:key=
"key"
:label=
"value.label"
:value=
"key"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
""
v-if=
"state.form.ruleRows.length > 0 && state.form.rule_type != 'empty'"
>
<div
class=
"rule-table"
style=
"width: 100%"
>
<el-form
:model=
"state.form.ruleRows"
ref=
"table_form"
:rules=
"state.tableRules"
label-width=
"0"
style=
"width: 100%"
>
<el-table
:data=
"state.form.ruleRows"
stripe
border
>
<el-table-column
v-for=
"header in ruleHeaders"
:prop=
"header.prop"
:key=
"header.prop"
:label=
"header.label"
:width=
"header.width"
>
<template
#default
="
{ $index }">
<div
class=
"warning-threshold"
v-if=
"header.prop == 'warning_threshold'"
>
<el-form-item
:prop=
"`[$
{$index}].from`" :rules="state.tableRules.from" style="flex: 1">
<el-input
style=
"flex: 1"
v-model=
"state.form.ruleRows[$index].from"
placeholder=
"请输入"
@
input=
"changeWarningThresholdFrom($index)"
>
<template
#append
>
{{
unitMap
}}
</
template
>
</el-input>
</el-form-item>
<span
class=
"to"
>
-
</span>
<el-form-item
label=
""
:prop=
"`${$index}.to`"
:rules=
"state.tableRules.to"
style=
"flex: 1"
>
<el-input
style=
"flex: 1"
v-model=
"state.form.ruleRows[$index].to"
placeholder=
"请输入"
clearable
@
input=
"changeWarningThresholdTo($index)"
>
<
template
#append
>
{{
unitMap
}}
</
template
>
</el-input>
</el-form-item>
</div>
<div
v-else-if=
"header.prop == 'risk_level'"
>
<el-form-item
label=
""
:prop=
"`[${$index}].risk_level`"
:rules=
"state.tableRules.risk_level"
>
<el-select
style=
"flex: 1"
v-model=
"state.form.ruleRows[$index].risk_level"
placeholder=
"请选择"
>
<el-option
v-for=
"item in riskLevelOptions($index)"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
</div>
</template>
</el-table-column>
<el-table-column
prop=
""
label=
"操作"
width=
"150px"
>
<
template
#default
="{
$
index
}"
>
<div
class=
"table-operation"
>
<el-button
link
type=
"primary"
@
click=
"createRule($index)"
:disabled=
"state.form.ruleRows.length >= riskLevels.length"
>
新增
</el-button>
<span
class=
"line"
></span>
<el-button
link
type=
"primary"
@
click=
"removeRule($index)"
:disabled=
"state.form.ruleRows.length == 1"
>
删除
</el-button>
</div>
</
template
>
</el-table-column>
</el-table>
</el-form>
</div>
</el-form-item>
</div>
</el-form>
</div>
</template>
<
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
,
},
isEdit
:
{
type
:
Boolean
,
default
:
false
,
},
});
var
validateWarnIndex
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
===
""
)
{
if
(
state
.
form
.
type_key
==
"
static
"
)
{
callback
(
new
Error
(
"
请选择
"
));
}
else
{
callback
(
new
Error
(
"
请输入
"
));
}
}
else
{
callback
();
}
};
const
state
=
reactive
({
form
:
{
warn_target
:
""
,
warn_type
:
""
,
warn_indicator
:
""
,
indicator_expression
:
""
,
rule_type
:
"
empty
"
,
ruleRows
:
[],
},
rules
:
{
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
"
}],
},
tableRules
:
{
from
:
[{
required
:
true
,
message
:
"
请输入
"
,
trigger
:
"
blur
"
}],
to
:
[{
required
:
true
,
message
:
"
请输入
"
,
trigger
:
"
blur
"
}],
risk_level
:
[{
required
:
true
,
message
:
"
请选择
"
,
trigger
:
"
change
"
}],
},
});
const
changeWarnCustomTarget
=
()
=>
{};
const
changeWarnCustomType
=
()
=>
{};
const
setLimits
=
(
index
)
=>
{
let
rows
=
[...
state
.
form
.
ruleRows
];
rows
.
splice
(
index
,
1
);
return
(
rows
.
map
((
e
)
=>
{
return
{
down
:
+
e
.
from
,
up
:
+
e
.
to
,
};
})
||
[]
);
};
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
)
{
state
.
form
.
ruleRows
[
index
].
from
=
""
;
return
;
}
let
rows
=
setLimits
(
index
);
if
(
rows
.
length
==
0
)
return
;
try
{
rows
.
forEach
((
e
)
=>
{
if
(
+
e
.
up
>=
+
from
>
+
e
.
down
)
{
throw
""
;
}
});
}
catch
(
e
)
{
state
.
form
.
ruleRows
[
index
].
from
=
""
;
}
};
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
)
{
state
.
form
.
ruleRows
[
index
].
to
=
""
;
return
;
}
let
rows
=
setLimits
(
index
);
if
(
rows
.
length
==
0
)
return
;
try
{
rows
.
forEach
((
e
)
=>
{
if
(
+
e
.
up
>
+
to
>
+
e
.
down
)
{
throw
""
;
}
});
}
catch
(
e
)
{
state
.
form
.
ruleRows
[
index
].
to
=
""
;
}
};
const
changeRuleType
=
()
=>
{};
const
form_ref
=
ref
(
null
);
const
table_form
=
ref
(
null
);
const
Submit
=
async
()
=>
{
let
form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
let
table_form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
table_form
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
return
form_valid
&&
table_form_valid
;
};
const
riskLevels
=
ref
([
{
id
:
1
,
name
:
"
重大风险
"
,
},
{
id
:
2
,
name
:
"
较大风险
"
,
},
{
id
:
3
,
name
:
"
一般风险
"
,
},
{
id
:
4
,
name
:
"
低风险
"
,
},
]);
const
riskLevelOptions
=
computed
(()
=>
{
return
(
index
)
=>
{
let
risk_level
=
state
.
form
.
ruleRows
[
index
].
risk_level
;
let
rows
=
state
.
form
.
ruleRows
.
map
((
e
)
=>
e
.
risk_level
);
if
(
risk_level
)
{
let
i
=
rows
.
findIndex
((
e
)
=>
e
==
risk_level
);
rows
.
splice
(
i
,
1
);
}
return
riskLevels
.
value
.
filter
((
e
)
=>
!
rows
.
includes
(
e
.
id
));
};
});
const
unitMap
=
computed
(()
=>
{
return
ruleTypeOptions
[
state
.
form
.
rule_type
].
unit
||
""
;
});
const
limit
=
computed
(()
=>
{
return
(
ruleTypeOptions
[
state
.
form
.
rule_type
].
limit
||
{
down
:
""
,
up
:
""
,
}
);
});
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
ruleHeaders
=
[
{
prop
:
"
warning_threshold
"
,
label
:
"
预警阈值
"
,
width
:
"
500px
"
,
},
{
prop
:
"
risk_level
"
,
label
:
"
风险程度
"
,
},
];
const
createRule
=
(
index
=
-
1
)
=>
{
state
.
form
.
ruleRows
.
splice
(
index
+
1
,
0
,
{
from
:
""
,
to
:
""
,
risk_level
:
""
,
});
};
const
removeRule
=
(
index
)
=>
{
state
.
form
.
ruleRows
.
splice
(
index
,
1
);
};
watch
(
()
=>
props
.
form
,
(
f
)
=>
{
if
(
!
f
)
{
createRule
();
return
;
}
state
.
form
.
warn_target
=
f
.
warn_target
;
state
.
form
.
warn_type
=
f
.
warn_type
;
state
.
form
.
warn_indicator
=
f
.
warn_indicator
;
state
.
form
.
indicator_expression
=
f
.
indicator_expression
;
state
.
form
.
rule_type
=
f
.
rule_type
;
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
();
}
},
{
deep
:
true
,
immediate
:
true
,
}
);
defineExpose
({
Submit
,
form
:
state
.
form
,
form_ref
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.custom-form
{
:deep
(
.gap-title
)
{
margin-bottom
:
16px
;
}
&
-item
{
max-width
:
1080px
;
width
:
100%
;
padding-left
:
8px
;
.indicator-expression
{
height
:
300px
;
width
:
100%
;
:deep
(
.vue-ace-editor
)
{
margin-top
:
0
;
}
}
}
}
.warning-threshold
{
display
:
flex
;
align-items
:
center
;
:deep
(
.el-input-group__append
,
.el-input-group__prepend
)
{
border-radius
:
4px
;
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
.to
{
margin
:
0
16px
;
}
.line
{
width
:
1px
;
height
:
14px
;
background-color
:
#c1c7d7
;
margin
:
0
16px
;
display
:
inline-block
;
}
.rule-table
{
:deep
(
.el-table
thead
th
)
{
background-color
:
#f5f6f9
;
}
}
</
style
>
src/page/main/forewarning/rule-set/modules/gateway.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"gateway-form"
>
<div
class=
"gateway-form-item"
>
<el-form
:model=
"state.form.ruleRows"
ref=
"form_ref"
:rules=
"state.tableRules"
label-width=
"0"
style=
"width: 100%"
>
<el-table
:data=
"state.form.ruleRows"
stripe
border
>
<el-table-column
v-for=
"header in ruleHeaders"
:prop=
"header.prop"
:key=
"header.prop"
:label=
"header.label"
:width=
"header.width"
>
<template
#default
="
{ $index }">
<div
class=
"warning-threshold"
v-if=
"header.prop == 'warning_threshold'"
>
<el-form-item
:prop=
"`[$
{$index}].from`" :rules="state.tableRules.from" style="flex: 1">
<el-input
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
>
</el-input>
</el-form-item>
<span
class=
"to"
>
-
</span>
<el-form-item
label=
""
:prop=
"`${$index}.to`"
:rules=
"state.tableRules.to"
style=
"flex: 1"
>
<el-input
style=
"flex: 1"
v-model.number=
"state.form.ruleRows[$index].to"
placeholder=
"请输入"
clearable
@
input=
"changeWarningThresholdTo($index)"
>
<
template
v-if=
"state.form.rule_type != 'empty'"
#append
>
ms
</
template
>
</el-input>
</el-form-item>
</div>
<div
v-else-if=
"header.prop == 'risk_level'"
>
<el-form-item
label=
""
:prop=
"`[${$index}].risk_level`"
:rules=
"state.tableRules.risk_level"
>
<el-select
style=
"flex: 1"
v-model=
"state.form.ruleRows[$index].risk_level"
placeholder=
"请选择"
>
<el-option
v-for=
"item in riskLevelOptions($index)"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
</div>
</template>
</el-table-column>
<el-table-column
prop=
""
label=
"操作"
width=
"150px"
>
<
template
#default
="{
$
index
}"
>
<div
class=
"table-operation"
>
<el-button
link
type=
"primary"
@
click=
"createRule($index)"
:disabled=
"state.form.ruleRows.length >= riskLevels.length"
>
新增
</el-button>
<span
class=
"line"
></span>
<el-button
link
type=
"primary"
@
click=
"removeRule($index)"
:disabled=
"state.form.ruleRows.length == 1"
>
删除
</el-button>
</div>
</
template
>
</el-table-column>
</el-table>
</el-form>
</div>
</div>
</template>
<
script
setup
>
import
{
computed
,
reactive
,
ref
,
watch
}
from
"
vue
"
;
import
gapTitle
from
"
@/components/gap-title.vue
"
;
const
props
=
defineProps
({
form
:
{
type
:
Object
,
default
:
null
,
},
});
const
state
=
reactive
({
form
:
{
ruleRows
:
[],
},
tableRules
:
{
from
:
[{
required
:
true
,
message
:
"
请输入
"
,
trigger
:
"
blur
"
}],
to
:
[{
required
:
true
,
message
:
"
请输入
"
,
trigger
:
"
blur
"
}],
risk_level
:
[{
required
:
true
,
message
:
"
请选择
"
,
trigger
:
"
change
"
}],
},
});
const
form_ref
=
ref
(
null
);
const
Submit
=
async
()
=>
{
let
form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
return
form_valid
;
};
const
riskLevels
=
ref
([
{
id
:
1
,
name
:
"
重大风险
"
,
},
{
id
:
2
,
name
:
"
较大风险
"
,
},
{
id
:
3
,
name
:
"
一般风险
"
,
},
{
id
:
4
,
name
:
"
低风险
"
,
},
]);
const
riskLevelOptions
=
computed
(()
=>
{
return
(
index
)
=>
{
let
risk_level
=
state
.
form
.
ruleRows
[
index
].
risk_level
;
let
rows
=
state
.
form
.
ruleRows
.
map
((
e
)
=>
e
.
risk_level
);
if
(
risk_level
)
{
let
i
=
rows
.
findIndex
((
e
)
=>
e
==
risk_level
);
rows
.
splice
(
i
,
1
);
}
return
riskLevels
.
value
.
filter
((
e
)
=>
!
rows
.
includes
(
e
.
id
));
};
});
const
ruleHeaders
=
[
{
prop
:
"
warning_threshold
"
,
label
:
"
预警阈值
"
,
width
:
"
500px
"
,
},
{
prop
:
"
risk_level
"
,
label
:
"
风险程度
"
,
},
];
const
createRule
=
(
index
=
-
1
)
=>
{
state
.
form
.
ruleRows
.
splice
(
index
+
1
,
0
,
{
from
:
""
,
to
:
""
,
risk_level
:
""
,
});
};
const
setLimits
=
(
index
)
=>
{
let
rows
=
[...
state
.
form
.
ruleRows
];
rows
.
splice
(
index
,
1
);
return
(
rows
.
map
((
e
)
=>
{
return
{
down
:
+
e
.
from
,
up
:
+
e
.
to
,
};
})
||
[]
);
};
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
)
{
state
.
form
.
ruleRows
[
index
].
from
=
""
;
return
;
}
let
rows
=
setLimits
(
index
);
if
(
rows
.
length
==
0
)
return
;
try
{
rows
.
forEach
((
e
)
=>
{
if
(
+
e
.
up
>=
+
from
>
+
e
.
down
)
{
throw
""
;
}
});
}
catch
(
e
)
{
state
.
form
.
ruleRows
[
index
].
from
=
""
;
}
};
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
)
{
state
.
form
.
ruleRows
[
index
].
to
=
""
;
return
;
}
let
rows
=
setLimits
(
index
);
if
(
rows
.
length
==
0
)
return
;
try
{
rows
.
forEach
((
e
)
=>
{
if
(
+
e
.
up
>
+
to
>
+
e
.
down
)
{
throw
""
;
}
});
}
catch
(
e
)
{
state
.
form
.
ruleRows
[
index
].
to
=
""
;
}
};
const
removeRule
=
(
index
)
=>
{
state
.
form
.
ruleRows
.
splice
(
index
,
1
);
};
watch
(
()
=>
props
.
form
,
(
f
)
=>
{
if
(
!
f
?.
ruleRows
)
{
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
();
}
},
{
deep
:
true
,
immediate
:
true
,
}
);
defineExpose
({
Submit
,
form
:
state
.
form
,
form_ref
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.gateway-form
{
margin-bottom
:
16px
;
:deep
(
.gap-title
)
{
margin-bottom
:
16px
;
}
&
-item
{
max-width
:
1080px
;
width
:
100%
;
padding-left
:
110px
;
:deep
(
.el-table
thead
th
)
{
background-color
:
#f5f6f9
;
}
.indicator-expression
{
height
:
300px
;
width
:
100%
;
:deep
(
.vue-ace-editor
)
{
margin-top
:
0
;
}
}
}
}
:deep
(
.el-form-item
)
{
margin-bottom
:
0
!
important
;
}
.warning-threshold
{
display
:
flex
;
align-items
:
center
;
:deep
(
.el-input-group__append
,
.el-input-group__prepend
)
{
border-radius
:
4px
;
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
.to
{
margin
:
0
16px
;
}
.line
{
width
:
1px
;
height
:
14px
;
background-color
:
#c1c7d7
;
margin
:
0
16px
;
display
:
inline-block
;
}
.rule-table
{
:deep
(
.el-table
thead
th
)
{
background-color
:
#f5f6f9
;
}
}
</
style
>
src/page/main/forewarning/rule-set/modules/static.vue
0 → 100644
View file @
302fb2f2
<
template
>
<div
class=
"static-form"
>
<el-form
:model=
"state.form"
ref=
"form_ref"
:rules=
"state.rules"
label-width=
"110px"
>
<div
class=
"static-form-item"
>
<el-form-item
label=
"预警对象/分类"
prop=
"warn_type"
>
<el-cascader
:disabled=
"props.isEdit"
ref=
"cascader_ref"
style=
"flex: 1"
placeholder=
"请选择预警对象/分类"
:options=
"staticTypeOptions"
v-model=
"state.form.warn_type"
@
change=
"changeWarnStaticType"
:props=
"cascaderProps"
>
</el-cascader>
</el-form-item>
<el-form-item
label=
"预警指标"
prop=
"warn_indicator"
>
<el-select
style=
"flex: 1"
:disabled=
"!formFormat.warn_type || props.isEdit"
v-model=
"state.form.warn_indicator"
placeholder=
"请选择预警指标"
>
<el-option
v-for=
"(value, key) in warningIndexOptions"
:key=
"key"
:label=
"value"
:value=
"key"
>
</el-option>
</el-select>
</el-form-item>
</div>
<div>
<div
v-if=
"state.form.warning_scpoe_form.length > 0"
>
<gap-title
:hasLine=
"true"
title=
"预警范围"
></gap-title>
<div
class=
"static-form-item"
>
<div
class=
"warning-scope-main"
>
<div
class=
"warn-scpoe-form"
v-for=
"(item, index) in state.form.warning_scpoe_form"
:key=
"index"
>
<el-form-item
:label=
"item.chinese_name"
>
<el-select
class=
"warn-scpoe-select"
v-model=
"item.select"
style=
"width: 114px"
@
change=
"changeSelect(index, item)"
>
<el-option
v-for=
"(value, key) in selectRule"
:key=
"key"
:label=
"value"
:value=
"key"
/>
</el-select>
</el-form-item>
<el-form-item
label=
""
class=
"no-el-label warn-scpoe-input-item"
prop=
"value"
:rules=
"[
{
validator: (rule, value, callback) => validateValue(rule, value, callback, item, index),
trigger: showSelect.includes(item.select) ? 'change' : 'blur',
},
]">
<el-input
class=
"warn-scpoe-input-value"
v-model=
"state.form.warning_scpoe_form[index].value"
placeholder=
"请输入"
v-if=
"!showSelect.includes(item.select)"
:disabled=
"item.select == 1"
>
</el-input>
<el-select
class=
"warn-scpoe-input-value"
v-else
v-model=
"item.value"
placeholder=
"请选择"
filterable
:loading=
"item.loading"
remote
:remote-method=
"(query) => remoteMethod(query, index)"
multiple
>
<el-option
v-for=
"item in item.options"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
</div>
</div>
</div>
</div>
<gap-title
:hasLine=
"true"
title=
"预警规则"
></gap-title>
<div
class=
"static-form-item"
>
<div
class=
"warning-rule-main"
>
<el-form-item
label=
"风险程度"
prop=
"risk_level"
v-if=
"isEmpty"
>
<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>
<Gateway
v-else
ref=
"warn_type_com"
/>
</div>
</div>
</div>
<!--
<component
ref=
"warn_type_com"
:is=
"warnTypeCom[formFormat.warn_type]"
:type=
"formFormat.warn_type"
:form=
"warn_type_com_form"
v-if=
"formFormat.warn_type"
></component>
-->
</el-form>
</div>
</
template
>
<
script
setup
>
import
{
computed
,
nextTick
,
reactive
,
ref
,
shallowReactive
,
watch
}
from
"
vue
"
;
import
gapTitle
from
"
@/components/gap-title.vue
"
;
// import CommonCom from "./common-com.vue";
import
Gateway
from
"
./gateway.vue
"
;
const
showSelect
=
[
"
4
"
,
"
5
"
];
const
selectRule
=
ref
({
1
:
"
全部
"
,
2
:
"
等于
"
,
3
:
"
不等于
"
,
4
:
"
正则匹配
"
,
5
:
"
正则不匹配
"
,
});
const
riskLevelOptions
=
ref
([
{
id
:
1
,
name
:
"
重大风险
"
,
},
{
id
:
2
,
name
:
"
较大风险
"
,
},
{
id
:
3
,
name
:
"
一般风险
"
,
},
{
id
:
4
,
name
:
"
低风险
"
,
},
]);
// const warnTypeCom = shallowReactive({
// colony: CommonCom,
// node: CommonCom,
// group: CommonCom,
// gateway: Gateway,
// });
const
props
=
defineProps
({
form
:
{
type
:
Object
,
default
:
null
,
},
isEdit
:
{
type
:
Boolean
,
default
:
false
,
},
});
const
changeSelect
=
(
index
,
item
)
=>
{
console
.
log
(
"
item.select:
"
,
item
.
select
);
if
(
showSelect
.
includes
(
item
.
select
))
{
state
.
form
.
warning_scpoe_form
[
index
].
value
=
[];
}
else
{
state
.
form
.
warning_scpoe_form
[
index
].
value
=
""
;
}
};
const
validateValue
=
(
rule
,
value
,
callback
,
item
,
index
)
=>
{
if
(
!
item
.
is_required
||
item
.
select
==
1
)
return
callback
();
if
(
item
.
value
==
""
)
{
let
msg
=
showSelect
.
includes
(
item
.
select
)
?
`请选择
${
item
.
chinese_name
}
`
:
`请输入
${
item
.
chinese_name
}
`
;
return
callback
(
new
Error
(
msg
));
}
return
callback
();
};
const
state
=
reactive
({
form
:
{
warn_type
:
[],
warn_indicator
:
""
,
risk_level
:
""
,
warning_scpoe_form
:
[],
},
rules
:
{
warn_type
:
[{
type
:
"
array
"
,
required
:
true
,
message
:
"
请选择预警对象/分类
"
,
trigger
:
"
change
"
}],
warn_indicator
:
[{
required
:
true
,
message
:
"
请选择预警指标
"
,
trigger
:
"
change
"
}],
risk_level
:
[{
required
:
true
,
message
:
"
请选择风险程度
"
,
trigger
:
"
change
"
}],
},
});
const
module_data
=
{
id
:
"
20da8f87-628a-4f0c-bd9c-0ad176d18d59
"
,
class_id
:
101
,
metric_name
:
"
xx请求次数告警
"
,
expr
:
'
shttp_requests_total{method="GET",$pod$}
'
,
duration
:
5
,
duration_unit
:
"
m
"
,
check_period
:
3
,
is_enabled
:
1
,
alert_rule_type
:
"
9f1e6170-65e8-4e14-9c17-6a7b87a900a7
"
,
created_by
:
""
,
created_at
:
"
2023-06-28 17:28:29
"
,
updated_by
:
""
,
updated_at
:
"
2023-06-28 17:54:33
"
,
alert_range
:
[
{
variable_name
:
"
$pod$
"
,
metric_name
:
"
shttp_requests_total
"
,
metric_label
:
"
pod
"
,
chinese_name
:
"
demoString
"
,
is_required
:
true
,
is_linked
:
true
,
},
{
variable_name
:
"
$image$
"
,
metric_name
:
"
shttp_requests_total
"
,
metric_label
:
"
image
"
,
chinese_name
:
"
镜像
"
,
is_required
:
true
,
is_linked
:
true
,
},
],
};
const
isEmpty
=
computed
(()
=>
{
return
false
;
// return module_data.alert_rule_type == "9f1e6170-65e8-4e14-9c17-6a7b87a900a7";
});
state
.
form
.
warning_scpoe_form
=
module_data
.
alert_range
.
map
((
e
)
=>
{
return
{
...
e
,
value
:
""
,
select
:
"
1
"
,
options
:
[],
loading
:
false
,
};
});
watch
(
()
=>
state
.
form
,
(
n
)
=>
{
console
.
log
(
n
);
},
{
deep
:
true
,
}
);
const
remoteMethod
=
(
query
,
index
)
=>
{
console
.
log
(
"
query, index:
"
,
query
,
index
);
if
(
!
query
)
{
state
.
form
.
warning_scpoe_form
[
index
].
options
=
[];
return
;
}
state
.
form
.
warning_scpoe_form
[
index
].
loading
=
true
;
setTimeout
(()
=>
{
state
.
form
.
warning_scpoe_form
[
index
].
loading
=
false
;
state
.
form
.
warning_scpoe_form
[
index
].
options
=
[
{
id
:
1
,
name
:
111
,
},
{
id
:
2
,
name
:
222
,
},
];
},
1000
);
};
const
warn_type_com_form
=
computed
(()
=>
props
.
form
?.
warn_type_com
||
null
);
watch
(
()
=>
props
.
form
,
(
n
)
=>
{
if
(
!
n
)
return
;
state
.
form
.
warn_type
=
n
.
warn_target
&&
n
.
warn_type
?
[
n
.
warn_target
,
n
.
warn_type
]
:
[];
state
.
form
.
warn_indicator
=
n
.
warn_indicator
;
},
{
deep
:
true
,
immediate
:
true
}
);
const
cascaderProps
=
{
value
:
"
id
"
,
label
:
"
label
"
,
};
const
staticTypeOptions
=
[
{
id
:
"
1
"
,
label
:
"
容器云平台
"
,
children
:
[
{
id
:
"
colony
"
,
label
:
"
容器集群
"
,
options
:
{
1
:
"
服务中断
"
,
2
:
"
CPU使用率
"
,
3
:
"
内存使用率
"
,
4
:
"
磁盘使用率
"
,
},
},
{
id
:
"
node
"
,
label
:
"
容器节点
"
,
options
:
{
1
:
"
服务中断
"
,
2
:
"
CPU使用率
"
,
3
:
"
内存使用率
"
,
4
:
"
磁盘使用率
"
,
},
},
{
id
:
"
group
"
,
label
:
"
容器组
"
,
options
:
{
1
:
"
服务中断
"
,
2
:
"
CPU使用率
"
,
3
:
"
内存使用率
"
,
},
},
{
id
:
"
gateway
"
,
label
:
"
网关
"
,
options
:
{
1
:
"
平均响应时长(入口网关)
"
,
},
},
],
},
];
const
formFormat
=
computed
(()
=>
{
let
[
warn_target
=
""
,
warn_type
=
""
]
=
state
.
form
.
warn_type
||
[];
let
obj
=
{
...
state
.
form
,
warn_target
,
warn_type
,
isEmpty
:
isEmpty
.
value
,
};
if
(
isEmpty
.
value
)
{
obj
.
warn_type_com
=
warn_type_com
.
value
?.
form
||
{};
}
return
obj
;
});
const
warningIndexOptions
=
ref
({});
const
cascader_ref
=
ref
(
null
);
const
changeWarnStaticType
=
async
()
=>
{
const
{
data
}
=
cascader_ref
.
value
.
getCheckedNodes
()[
0
];
warningIndexOptions
.
value
=
data
.
options
;
let
keys
=
Object
.
keys
(
warningIndexOptions
.
value
);
state
.
form
.
warn_indicator
=
keys
[
0
];
setTimeout
(()
=>
{
form_ref
.
value
.
clearValidate
([
"
warn_indicator
"
]);
});
};
const
changeRuleType
=
()
=>
{};
const
form_ref
=
ref
(
null
);
const
warn_type_com
=
ref
(
null
);
const
Submit
=
async
()
=>
{
let
form_valid
=
await
new
Promise
((
resolve
,
reject
)
=>
{
form_ref
.
value
.
validate
((
res
)
=>
resolve
(
res
));
});
if
(
isEmpty
.
value
)
return
form_valid
;
let
warn_type_com_valid
=
(
await
warn_type_com
.
value
?.
Submit
())
||
true
;
return
form_valid
&&
warn_type_com_valid
;
};
const
ruleHeaders
=
[
{
prop
:
"
warning_threshold
"
,
label
:
"
预警阈值
"
,
width
:
"
500px
"
,
},
{
prop
:
"
risk_level
"
,
label
:
"
风险程度
"
,
},
];
defineExpose
({
Submit
,
form
:
formFormat
,
form_ref
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.static-form
{
:deep
(
.gap-title
)
{
margin-bottom
:
16px
;
}
&
-item
{
max-width
:
1080px
;
width
:
100%
;
padding-left
:
8px
;
.warning-scope-main
{
display
:
grid
;
grid-template-columns
:
1fr
1fr
;
grid-column-gap
:
16px
;
:deep
(
.el-input-group__prepend
)
{
border-radius
:
4px
;
border-top-right-radius
:
0
;
border-bottom-right-radius
:
0
;
}
.warn-scpoe-form
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
.warn-scpoe-select
{
width
:
114px
!
important
;
:deep
(
.el-input__wrapper
)
{
border-radius
:
4px
;
border-top-right-radius
:
0
;
border-bottom-right-radius
:
0
;
}
}
.warn-scpoe-input-item
{
flex
:
1
;
.warn-scpoe-input-value
{
flex
:
1
;
:deep
(
.el-input__wrapper
)
{
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
}
}
}
}
}
.no-el-label
{
:deep
(
.el-form-item__content
)
{
margin-left
:
0
!
important
;
}
}
</
style
>
src/page/main/ticket/business-ticket-manage/add/index.vue
View file @
302fb2f2
...
...
@@ -63,6 +63,7 @@ const Distribute = async () => {
align-items
:
center
;
justify-content
:
flex-end
;
border-top
:
1px
solid
#ddd
;
padding
:
0
24px
;
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment