<template>
<div style="flex: 1 1 0%;width: 100%;">
<!-- 搜索条件 -->
<el-form class="query-form" ref="form" :model="searchForm" label-width="60px">
<el-row :gutter="24">
<el-col :span="4">
<el-form-item label="规则名称">
<el-input v-model.trim="searchForm.name" placeholder="请输入规则名称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="规则分类">
<el-select
v-model="searchForm.rule_type"
style="width: 100%;"
clearable
placeholder="请选择"
@clear="searchForm.rule_type = null"
>
<el-option
v-for="item in ruleTypesOptions"
:key="item.conf_key"
:label="item.conf_value"
:value="item.conf_key"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="状态">
<el-select
v-model="searchForm.status"
style="width: 100%;"
clearable
placeholder="请选择"
@clear="searchForm.status = null"
>
<el-option
v-for="item in statusArr"
:key="item.index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="handleQuery">
<i class="iconfont icon-btn"></i>
查询
</el-button>
<el-button type="primary" @click="handleAdd">
<i class="el-icon-circle-plus"></i>
新增
</el-button>
</el-col>
</el-row>
</el-form>
<!-- 内容部分 -->
<el-container>
<el-main>
<div class="table-inner">
<el-table
ref="singleTable"
v-loading="listLoading"
element-loading-text="加载中..."
:data="tableData"
border
show-overflow-tooltip
highlight-current-row
@current-change="handleCurrentCulumn"
height="100%">
<el-table-column
label="序号"
fixed
width="60"
align="center">
<template slot-scope="scope">{{ scope.$index+1 }}</template>
</el-table-column>
<el-table-column
label="操作"
fixed
width="90">
<template slot-scope="scope">
<el-button
type="text"
@click.stop="handleStatusChange(scope.row)">
{{ scope.row.status === 1 ? '禁用' : '启用' }}
</el-button>
<el-button type="text" @click.stop="handleDelete(scope.row, scope.$index)">删除</el-button>
</template>
</el-table-column>
<el-table-column
label="规则名称"
prop="name">
</el-table-column>
<el-table-column
label="规则分类">
<template slot-scope="scope">
<span>{{ scope.row.category_id | selectOptionFilter(that, ruleTypesOptions) }}</span>
</template>
</el-table-column>
<el-table-column
prop="status"
label="状态"
width="70">
<template slot-scope="scope">
<span>
<i class="status-circle" :class="scope.row.status ? 'el-button--success':'el-button--danger'"></i>
<span :class="scope.row.status ? 'status-success':'status-danger'">{{ scope.row.status | statusFilter }}</span>
</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<el-pagination
class="person-pagination page"
background
:current-page="currentPage"
:page-sizes="[20, 50, 100, 200]"
:page-size="pageSize"
layout="sizes, total, jumper, prev, pager, next"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</el-main>
<el-aside width="60%" v-loading="editPartLoading">
<m-card-title :level="1">告警规则
<div slot="btn-group">
<div style="border-top: none" v-if="isEditRuleFlag">
<el-button type="primary" @click="onSaveRuleDetail" v-if="isEdit" >提交</el-button>
<el-button type="primary" @click="onEditRuleDetail" v-else>编辑</el-button>
<!--<el-button @click="onReset" v-if="isEdit">重置</el-button>-->
</div>
</div>
</m-card-title>
<div class="el-aside-form">
<el-form ref="ruleForm" :rules="rules" :model="form" label-width="90px" v-loading="ruleDetailLoading">
<el-row>
<el-col :span="24">
<el-form-item label="规则名称" prop="name">
<el-input
v-model.trim="form.name"
maxlength="140"
style="width: 100%;"
:disabled="isEditRuleFlag && !isEdit"
clearable
placeholder="不超过140个字符"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="规则分类" prop="category_id">
<el-select
v-model="form.category_id"
style="width: 100%;"
placeholder="请选择"
:disabled="isEditRuleFlag && !isEdit"
>
<el-option
v-for="item in ruleTypesOptions"
:key="item.index"
:label="item.conf_value"
:value="item.conf_key"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" v-if="isEditRuleFlag">
<el-form-item label="变更人">
<el-input
v-model.trim="form.updated_by"
maxlength="20"
style="width: 100%;"
disabled
clearable
placeholder="不超过20个字符"
/>
</el-form-item>
</el-col>
<el-col :span="8" v-if="isEditRuleFlag">
<el-form-item label="变更时间">
<el-input
v-model.trim="form.updated_time"
maxlength="20"
style="width: 100%;"
disabled
clearable
placeholder="不超过20个字符"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="规则描述" prop="description">
<el-input
v-model.trim="form.description"
maxlength="600"
style="width: 100%;"
:disabled="isEditRuleFlag &&!isEdit"
clearable
type="textarea"
:autosize="{ minRows: 2, maxRows: 2}"
placeholder="请输入备注"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="执行规则频率" prop="interval_time">
<el-input-number
style="width: 120px"
v-model="form.interval_time"
:disabled="isEditRuleFlag && !isEdit"
:min="1"
:max="10000"
label="描述文字">
</el-input-number>
<el-select
v-model="form.time_unit"
style="width: 120px"
placeholder="请选择"
:disabled="isEditRuleFlag && !isEdit"
>
<el-option
v-for="item in timeUnitArr"
:key="item.index"
:label="item.conf_key"
:value="item.conf_value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<m-card-title>过滤条件</m-card-title>
<el-row>
<el-col :span="8">
<el-form-item label="时间范围" prop="latest_hours">
<el-input-number
v-model="form.latest_hours"
:disabled="isEditRuleFlag && !isEdit"
:min="1"
:max="10000"
label="描述文字"
style="width: 120px">
</el-input-number>
小时
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="时间范围" prop="duration" >
<el-checkbox :disabled="isEditRuleFlag && !isEdit" v-model="form.timeAroundFlag"></el-checkbox>
<el-time-picker
v-show="form.timeAroundFlag"
is-range
:disabled="isEditRuleFlag && !isEdit"
arrow-control
value-format="HH:mm:ss"
v-model="form.timeAround"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围">
</el-time-picker>
</el-form-item>
</el-col>
</el-row>
<!--<div class="el-dialog__footer" style="border-top: none" v-if="isEditRuleFlag">
<el-button type="primary" @click="onSaveRuleDetail" v-if="isEdit" >提交</el-button>
<el-button type="primary" @click="onEditRuleDetail" v-else>编辑</el-button>
<!–<el-button @click="onReset" v-if="isEdit">重置</el-button>–>
</div>-->
</el-form>
<!--分组-->
<div class="filter-group__wrapper">
<el-button type="primary" @click="onAddGroup">
<i class="el-icon-circle-plus"></i>
新增分组
</el-button>
<alarm-rule-group
v-for="(group, groupIndex) in groupArr"
:rule_id="editDetailId"
ref="alarmRuleGroup"
:group="group"
:dictCategoryAll="dictCategoryAll"
:isNewAddFlag.sync="group.isNewAddFlag"
:isEditRuleFlag="isEditRuleFlag"
:key="group.id"
:groupIndex="groupIndex"
:uebaMetaDataList="uebaMetaDataList"
@onDelGroupCb="onDelGroup(groupIndex, group)"
@submitFormCn="submitFormCn"></alarm-rule-group>
</div>
<div class="el-dialog__footer" v-if="!isEditRuleFlag">
<el-button type="primary" @click="onSave">提交</el-button>
<!--<el-button type="primary" @click="onEdit">编辑</el-button>
<el-button @click="onReset" v-if="isEdit">重置</el-button>-->
</div>
</div>
</el-aside>
</el-container>
</div>
</template>
<script>
import mixins from '@/mixins/index.js'
import alarmRuleGroup from './components/alarm-rule-group'
import { isRegExpContent } from '@/utils/index'
export default {
components: {
alarmRuleGroup
},
mixins: [mixins],
filters: {
statusFilter(val) {
const statusMap = {
0: '禁用',
1: '启用',
}
return statusMap[val]
},
},
data() {
return {
that: this,
form: {
name: '',
description: '',
category_id: '',
interval_time: '',
time_unit: 'hour', // 时间单位: hour或minute
latest_hours: '', // 查询时间范围
begin_time: '', // 开始时段:00:00:00
end_time: '', // 结束时段:00:00:00
timeAroundFlag: false,
// 时间插件默认显示时分秒(这里的年月日只是保持格式一致使用,请忽略)
// 默认:开始时段:00:00:00 结束时段:00:00:00
timeAround: [new Date(2020, 6, 1, 0, 0, 0), new Date(2020, 6, 1, 0, 0, 0)],
condition_groups: []
},
rules: {
name: [
{ required: true, message: '请输入规则名称', trigger: 'blur' }
],
category_id: [
{ required: true, message: '请选择规则分类', trigger: 'change' }
],
description: [
{ required: true, message: '请输入规则描述', trigger: 'blur' }
],
interval_time: [
{ required: true, message: '请输入执行频率', trigger: 'change' }
],
latest_hours: [
{ required: true, message: '请输入时间范围', trigger: 'change' }
],
},
statusArr: [
{
value: 0,
label: '禁用'
},
{
value: 1,
label: '启用'
}
],
timeUnitArr: [
{
conf_value: 'hour',
conf_key: '分钟',
},
{
conf_value: 'minute',
conf_key: '小时',
}
],
// 规则类型(搜索)
ruleTypesOptions: [],
// 字段名称下拉选项
uebaMetaDataList: [],
searchForm: {
name: '',
status: null, // 0/1
category_id: null,
},
listLoading: false,
ruleDetailLoading: false,
currentPage: 1,
pageSize: 20,
total: 0,
tableData: [],
// 编辑区域laodings
editPartLoading: false,
isEdit: true,
isEditRuleFlag: false,
// ----------
/// 表单相关参数
dataDict:{},
// 预警类型
alarmTypes: [],
// 防火墙名称
sysNameArr: [],
// 规则类型
ruleTypes: [],
// 因为接口共用,前端必须控制传参字段正确
paramsArr: [],
// 区分编辑还是新增
editDetailId: '',
dictCategoryAll: [],
groupArr: [{
groupId: Date.now(),
isNewAddFlag: true
}]
};
},
created() {
this.getDictCategoryAll();
this.getDataDictQuery();
this.getUebaMetaDataList();
this.initTableData();
},
mounted() {
},
methods: {
// 初始化列表数据
async initTableData(val) {
this.currentPage = val
this.listLoading = true
const options = {
page: this.currentPage,
page_size: this.pageSize,
...this.searchForm
}
await this.$API.uebaRuleList(options).then(res => {
this.listLoading = false
if (res && res.code === 0) {
this.tableData = res.data.rows;
// this.setCurrent(this.tableData[0])
this.total = res.data.total_rows; //总数
this.currentPage = res.data.page; //当前页码
} else {
this.$message.error(res.msg)
}
}).catch(error => {
this.listLoading = false
console.log(error)
})
},
checkStatus(val) {
const statusType = {
'0': {
text: '启用',
postData: 1
},
'1': {
text: '禁用',
postData: 0
}
}
return statusType[val]
},
// 启用/禁用
handleStatusChange(row) {
const statusText = this.checkStatus(row.status).text
const statusPostData = this.checkStatus(row.status).postData
this.$confirm(`确定${statusText}该告警规则么?`, statusText, {
closeOnClickModal: false
}).then(() => {
const options = {
id: row.id,
status: statusPostData
}
this.$API.alarmRulesStatus(options).then(response => {
if (response && response.code === 0) {
this.initTableData(1)
} else {
this.$message.error(response.msg)
}
}).catch(error => {
this.listLoading = false
console.log(error)
})
}).catch((msg) => {
console.log(msg)
})
},
handleDelete(row, index) {
let rule_ids = [].concat(row.id)
const options = {
ids: rule_ids
}
this.$confirm('此操作将删除该告警规则,确认删除么?', {
confirmButtonText: '确定',
cancleButtonText: '取消',
type: 'warning'
}).then(async() => {
this.$API.uebaRuleDelete(options).then(response => {
if (response && response.code === 0) {
this.tableData.splice(index, 1)
this.$message.success('删除成功!')
// 如果删除当前编辑信息,则刷新返回新增信息状态
if(rule_ids.includes(this.editDetailId)){
this.handleAdd()
}
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
}).catch(error => {
console.log(error)
})
},
// 查询
async handleQuery() {
this.initTableData(1)
},
// 新增
handleAdd() {
this.editPartLoading = true
this.isEditRuleFlag = false
this.editDetailId = ''
this.setCurrent()
this.initEditForm()
setTimeout(()=>{
// 默认显示
this.editPartLoading = false
this.clearValidate()
},300)
},
// 初始编辑内容
initEditForm() {
const obj = {
name: '',
description: '',
category_id: "",
interval_time: '',
time_unit: 'hour', // 时间单位: hour或minute
latest_hours: '', // 查询时间范围
begin_time: '', // 开始时段:00:00:00
end_time: '', // 结束时段:00:00:00
timeAroundFlag: false,
// 时间插件默认显示时分秒(这里的年月日只是保持格式一致使用,请忽略)
// 默认:开始时段:00:00:00 结束时段:00:00:00
timeAround: [new Date(2020, 6, 1, 0, 0, 0), new Date(2020, 6, 1, 0, 0, 0)],
condition_groups: []
}
this.groupArr = [{
groupId: Date.now(),
isNewAddFlag: true
}]
Object.assign(this.form, obj)
},
handleSizeChange(v) {
this.pageSize = v;
this.initTableData(1);
},
handleCurrentChange(v) {
this.initTableData(v);
},
setCurrent(row) {
this.$refs.singleTable.setCurrentRow(row);
},
// 数据字典
getDataDictQuery() {
const options = {
code_list: ['ueba_rule_type']
}
this.$API.dataDictQuery(options).then(response => {
if (response && response.code === 0) {
this.ruleTypesOptions = response.data.ueba_rule_type
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},
// 编辑详情
handleCurrentCulumn(row) {
// 编辑提交会触发此事件
if(!row){
return
}
this.editPartLoading = true
this.isEdit = false
this.editDetailId = row.id
this.groupArr = []
const options = {
id: row.id
}
this.clearValidate()
setTimeout(()=>{
this.$API.uebaRuleDetail(options).then(response => {
if (response && response.code === 0) {
const {
begin_time, category_id, description, end_time, id, interval_time, latest_hours,
name, time_unit, updated_time, updated_by
} = response.data
let timeAroundFlag = false
let timeAround = false
if(begin_time !== '00:00:00' || end_time !== '00:00:00'){
timeAroundFlag = true
timeAround = [new Date(`2020-6-1 ${begin_time}`), new Date(`2020-6-1 ${end_time}`)]
}else {
timeAround = [new Date(2020, 6, 1, 0, 0, 0), new Date(2020, 6, 1, 0, 0, 0)]
}
let obj = { begin_time, category_id, description, end_time, id, updated_by, updated_time,
interval_time, latest_hours, name, time_unit, timeAroundFlag, timeAround,
}
Object.assign(this.form, obj)
this.editPartLoading = false
this.isEditRuleFlag = true
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
this.$API.uebaRuleConditionGroupList({rule_id: options.id}).then(response => {
if (response && response.code === 0) {
const data = response.data
Object.assign(this.form, {
condition_fields: data,
})
this.groupArr = this.groupArr.concat(data)
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},300)
},
submitFormCn(form) {
// 过滤,去除重复的groupId
const index = this.form.condition_groups.findIndex(item => item.groupId === form.groupId)
if(index !== -1){
this.form.condition_groups.splice(index, 1)
}
this.form.condition_groups.push(form)
},
onSave(){
// 获取子组件,通过refs访问子组件方法,校验条件值
const alarmRuleGroup = this.$refs['alarmRuleGroup']
alarmRuleGroup.forEach( subVue => {
subVue.submitForm()
})
this.$refs['ruleForm'].validate(valid => {
// 创建分组数量跟内容校验通过数是否一致
const { condition_groups } = this.form
if(alarmRuleGroup.length !== condition_groups.length){
return
}
if (valid) {
let {
name, description, category_id, interval_time, time_unit, latest_hours,
begin_time, end_time, timeAroundFlag, timeAround, condition_groups,
} = this.form
// 时间传参处理
if(timeAroundFlag) {
begin_time = timeAround[0]
end_time = timeAround[1]
}else {
begin_time = '00:00:00'
end_time = '00:00:00'
}
let options = {
name, description, category_id, interval_time, time_unit, latest_hours, begin_time, end_time, condition_groups,
}
if(!this.editDetailId){
this.$API['uebaRuleCreate'](options).then(response => {
if (response && response.code === 0) {
this.$message.success(response.msg)
this.initTableData(1)
// 编辑成功,切换回新增状态
if(this.editDetailId){
this.editDetailId = ''
}
this.initEditForm()
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
}else {
options.rule_id = this.editDetailId
// 规则条件组编辑
}
} else {
console.log('error submit!!')
}
})
},
onReset(){
},
clearValidate() {
this.$refs.ruleForm.clearValidate();
},
onAddGroup() {
this.groupArr.push({
groupId: Date.now(),
isNewAddFlag: true
})
},
handleDeleteGroup(id, groupIndex) {
let rule_ids = [id]
const options = {
ids: rule_ids
}
this.$confirm('此操作将删除该规则条件组,确认删除么?', {
confirmButtonText: '确定',
cancleButtonText: '取消',
type: 'warning'
}).then(async() => {
this.$API.uebaRuleConditionGroupDelete(options).then(response => {
if (response && response.code === 0) {
this.$message.success('删除成功!')
this.groupArr.splice(groupIndex, 1)
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
}).catch(error => {
console.log(error)
})
},
onDelGroup(groupIndex, group) {
if(this.groupArr.length <= 1){
this.$message.warning('最少有一个条件组')
return
}
if(this.isEditRuleFlag){
this.handleDeleteGroup(group.id, groupIndex)
return
}
this.groupArr.splice(groupIndex, 1)
},
// 规则名称下拉
getUebaMetaDataList() {
this.$API.uebaMetaDataList().then(response => {
if (response && response.code === 0) {
this.uebaMetaDataList = response.data
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},
onEditRuleDetail() {
this.isEdit = true
},
onSaveRuleDetail() {
this.ruleDetailLoading = true
setTimeout(()=>{
this.$refs['ruleForm'].validate(valid => {
if (valid) {
let {
name, description, category_id, interval_time, time_unit, latest_hours,
begin_time, end_time, timeAroundFlag, timeAround, id
} = this.form
// 时间传参处理
if(timeAroundFlag) {
// 默认值
if(typeof timeAround[0] === 'object' || typeof timeAround[1] === 'object'){
begin_time = end_time
end_time = end_time
}else {
begin_time = timeAround[0]
end_time = timeAround[1]
}
}else {
begin_time = '00:00:00'
end_time = '00:00:00'
}
let options = {
name, description, category_id, interval_time, time_unit, latest_hours, begin_time, end_time, id
}
this.$API['uebaRuleModify'](options).then(response => {
if (response && response.code === 0) {
this.$message.success('修改成功')
this.ruleDetailLoading = false
this.isEdit = false
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
} else {
console.log('error submit!!')
}
})
},300)
},
getDictCategoryAll() {
this.$API
.dataDictCategoryAll({
name: 'UEBA数据字典' // TODO 这里需要约定下,不能随意改
})
.then(async (res) => {
if (res.code === 0) {
const curdDictCategoryId = res.data[0].id
let { data } = await this.$API.dataDictList({
category_id: curdDictCategoryId,
page: 1,
page_size: 200000
});
this.dictCategoryAll = data.rows.map(item=>({
conf_value: item.name,
conf_key: item.code
}))
}
});
},
}
};
</script>
<style lang="scss" scoped>
.el-container {
width: 100%;
min-height: calc(100vh - 200px);
margin-bottom: 30px;
.el-aside {
margin-left: 10px;
border: 1px solid #eee;
/deep/ .el-input-group__append {
background: #9571e9;
color: #fff;
border: none;
}
.levelUl {
.levelLi {
padding: 0 20px;
line-height: 40px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
flex-direction: row;
align-items: center;
position: relative;
}
.levelLi:hover {
background: #9571e9;
color: #fff;
}
}
.tree-inner {
height: calc(100% - 100px);
overflow-y: scroll;
.el-tree {
font-size: 12px;
}
}
}
.el-main {
padding: 0;
.table-inner {
height: calc(100% - 55px);
overflow-y: scroll;
}
}
/deep/ .el-range-editor.is-disabled input {
color: #000!important;
}
}
.person-pagination {
width: 100%;
// flex: flex;
position: relative;
left: 0;
}
.el-aside-form{
margin: 10px 10px 10px 0px;
}
.status-circle{
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
}
.status-success {
color: #00b94d;
}
.status-danger {
color: #f55;
}
.filter-group__wrapper {
padding: 20px;
border-top: 1px solid #c1bfc7;
}
</style>
<template>
<!--自定义字段-->
<div class="filter-group">
<el-card class="filter-group__item" v-loading="loading">
<div class="title el-button--text">
<span>条件分组 {{groupIndex + 1}}</span>
<div class="title-rgith">
<el-button icon="el-icon-delete" @click="onDelGroup" :disabled="!isNewAddFlag && isEditRuleFlag && !isEdit">删除分组</el-button>
<div v-if="isEditRuleFlag">
<el-button type="primary" @click="onSave" v-if="!isNewAddFlag && isEdit" >提交</el-button>
<el-button type="primary" @click="onEdit" v-if="!isNewAddFlag && !isEdit">编辑</el-button>
<!--<el-button @click="onReset" v-if="isEdit">重置</el-button>-->
<el-button type="primary" v-if="isNewAddFlag" @click="onAddNew">新增</el-button>
</div>
</div>
</div>
<p class="sub-title el-button--text"><span>基础条件:</span></p>
<el-form ref="ruleForm" :model="form" label-width="70px">
<el-row :gutter="24">
<el-col :span="7">
<el-form-item
label="操作最小次数" prop="min_counts" label-width="88px"
:rules="[
{ required: true, message: '请输入操作最小次数', trigger: 'blur' }
]">
<el-input-number
v-model="form.min_counts"
:min="1"
:max="1000000"
label="描述文字"
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
style="width: 120px">
</el-input-number>
</el-form-item>
</el-col>
</el-row>
<p class="sub-title el-button--text rule"><span>条件规则:</span></p>
<el-row :gutter="24" v-for="(item, index) in form.condition_fields">
<el-col :span="7" class="col-item">
<el-form-item
label="字段名称"
:key="item.key"
:prop="'condition_fields.' + index + '.field_id'"
:rules="[
{ required: true, message: '请选择字段名称', trigger: 'change' }
]">
<el-select
v-model="item.field_id"
style="width: 100%;"
placeholder="请选择"
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
@change="changeRuleName(item)"
>
<el-option
v-for="item in uebaMetaDataList"
:key="item.id"
:label="item.field_name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
label="条件关系"
:prop="'condition_fields.' + index + '.operation'"
:key="item.key"
label-width="70px"
:rules="[
{ required: true, message: '请选择条件关系', trigger: 'change' }
]">
<el-select
v-model="item.operation"
style="width: 100%;"
clearable
placeholder="请选择"
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
>
<el-option
v-for="operation in operationArr[item.field_type]"
:key="operation.conf_value"
:label="operation.conf_key"
:value="operation.conf_value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<!--
field_type: string、enum、date
-->
<el-form-item
label="条件值"
:prop="'condition_fields.' + index + '.input_content'"
:key="item.key"
label-width="60px"
:rules="[
{ required: true, message: '条件值不能为空', trigger: 'change' }
]">
<template>
<div class="inner-datc-dict" v-show="item.field_type === 'string'">
<span class="el-form-item__label">引用数据字典:</span>
<el-checkbox v-model="item.userDictFlag" :disabled="!isNewAddFlag && isEditRuleFlag && !isEdit" @change="onSwitchUseDict(item)"></el-checkbox>
</div>
</template>
<el-input
v-show="item.field_type === 'string' && item.values_type === 'text'"
v-model.trim="item.input_content"
clearable
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
placeholder="请输入条件值"
/>
<el-date-picker
v-show="item.field_type === 'date' || item.field_type === 'datetime'"
v-model="item.input_content"
type="date"
value-format="yyyy-MM-dd"
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
style="display: inline-block"
placeholder="选择日期">
</el-date-picker>
<el-select
v-show="item.field_type === 'enum' || item.values_type === 'dict_code'"
v-model="item.input_content"
style="width: 100%;"
clearable
:disabled="!isNewAddFlag && isEditRuleFlag && !isEdit"
placeholder="请选择"
>
<el-option
v-for="i in dictCodeArr"
:key="i.conf_value"
:label="i.conf_value"
:value="i.conf_key"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-button type="danger" icon="el-icon-minus" :disabled="!isNewAddFlag && isEditRuleFlag && !isEdit" circle @click="onDel(index)"></el-button>
<el-button v-show="(index+1) === form.condition_fields.length" type="primary" icon="el-icon-plus" :disabled="!isNewAddFlag && isEditRuleFlag && !isEdit" circle @click="onAdd"></el-button>
</el-col>
</el-row>
</el-form>
<!--<div class="el-dialog__footer" v-if="isEditRuleFlag">
<el-button type="primary" @click="onSave" v-if="!isNewAddFlag && isEdit" >提交</el-button>
<el-button type="primary" @click="onEdit" v-if="!isNewAddFlag && !isEdit">编辑</el-button>
<!–<el-button @click="onReset" v-if="isEdit">重置</el-button>–>
<el-button type="primary" v-if="isNewAddFlag" @click="onAddNew">新增</el-button>
</div>-->
</el-card>
<el-divider>与</el-divider>
</div>
</template>
<script>
export default {
name: 'alarm-rule-group',
props: {
group: {
type: Object,
default:() => {}
},
uebaMetaDataList: {
type: Array,
default:() => []
},
rule_id: {
type: [Number,String],
default: ''
},
dictCategoryAll: {
type: Array,
default: ()=>[]
},
// 区分父组件是否 【编辑状态】 还是 【新增状态】
isEditRuleFlag: {
type: Boolean,
default: false
},
isNewAddFlag: {
type: Boolean,
default: false
},
groupIndex: {
type: Number,
default: 0
},
},
created() {
// 处理默认值
let {
condition_fields,
id,
min_counts
} = this.group
// 编辑
if(id){
this.form.id = id
this.form.groupId = id
this.form.min_counts = min_counts
this.form.condition_fields = []
condition_fields.forEach(item=> {
this.changeRuleName(item, false)
this.form.condition_fields.push({
field_id: item.field_id,
operation: item.operation,
values_type: item.values_type, // text或dict_code(引用外部数据字典)
userDictFlag: item.values_type === 'dict_code' ? true: false,
input_content: item.input_values[0], // TODO 需要把input_content的内容放在input_values传给后端
input_values: item.input_values, // 统一数组形式传给后端
field_type: item.field_type,
key: Date.now()
})
})
}
},
data() {
return {
loading: false,
isEdit: false,
dictCodeArr: [],
form: {
groupId: Date.now(), // 前端标记识别用
min_counts: '',
condition_fields: [
{
field_id: '',
operation: '',
values_type: 'text', // text或dict_code(引用外部数据字典)
userDictFlag: false,
input_content: '', // 需要把input_content的内容放在input_values传给后端
input_values: [], // 统一数组形式传给后端
field_type: 'string'
},
],
},
operationArr: {
string: [
{ conf_value: 'equal', conf_key: '等于' },
{ conf_value: 'not_equal ', conf_key: '不等于' },
{ conf_value: 'lt', conf_key: '小于' },
{ conf_value: 'lte', conf_key: '小于等于' },
{ conf_value: 'gt', conf_key: '大于' },
{ conf_value: 'gte', conf_key: '大于等于' },
{ conf_value: 'between', conf_key: '范围于' },
],
enum: [
{ conf_value: 'equal', conf_key: '等于' },
{ conf_value: 'not_equal ', conf_key: '不等于' },
{ conf_value: 'in', conf_key: '包含于' },
{ conf_value: 'not_in', conf_key: '不包含于' },
{ conf_value: 'like', conf_key: '匹配' },
{ conf_value: 'not_like', conf_key: '不匹配' },
],
date: [
{ conf_value: 'equal', conf_key: '等于' },
{ conf_value: 'not_equal ', conf_key: '不等于' },
{ conf_value: 'in', conf_key: '包含于' },
{ conf_value: 'not_in', conf_key: '不包含于' },
{ conf_value: 'like', conf_key: '匹配' },
{ conf_value: 'not_like', conf_key: '不匹配' },
],
datetime: [
{ conf_value: 'equal', conf_key: '等于' },
{ conf_value: 'not_equal ', conf_key: '不等于' },
{ conf_value: 'in', conf_key: '包含于' },
{ conf_value: 'not_in', conf_key: '不包含于' },
{ conf_value: 'like', conf_key: '匹配' },
{ conf_value: 'not_like', conf_key: '不匹配' },
],
},
}
},
methods: {
// 数据字典
getDataDictQuery(code_list) {
const options = {
code_list: [code_list],
}
this.$API.dataDictQuery(options).then(response => {
if (response && response.code === 0) {
this.dictCodeArr = response.data[code_list]
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},
// 切换规则名称
changeRuleName(item, refresh = true) {
const curMeta = this.uebaMetaDataList.find(meta => meta.id == item.field_id)
item.field_type = curMeta['field_type']
if(curMeta.dict_code) {
this.getDataDictQuery(curMeta.dict_code)
}
if(item.values_type === 'dict_code'){
this.dictCodeArr = this.dictCategoryAll
}
if(refresh){
item.operation = ''
item.input_content = ''
}
},
// 引用数据字典
onSwitchUseDict(item) {
item.values_type = item.userDictFlag ? 'dict_code' : 'text'
this.dictCodeArr = this.dictCategoryAll
},
onDel(index) {
if(this.form.condition_fields.length <= 1){
this.$message.warning('最少有一个条件')
return
}
this.form.condition_fields.splice(index, 1)
},
onAdd() {
this.form.condition_fields.push({
field_id: '',
operation: '',
values_type: 'text', // text或dict_code(引用外部数据字典)
userDictFlag: false,
input_content: '', // 需要把input_content的内容放在input_values传给后端
input_values: [], // 统一数组形式传给后端
field_type: 'string',
key: Date.now()
})
},
onDelGroup() {
this.$emit('onDelGroupCb')
},
// 提交校验数据
submitForm(fn) {
console.log('进来了')
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
if(fn){
fn()
return
}
this.form.condition_fields.forEach(item => {
item.input_values = [item.input_content]
})
this.$emit('submitFormCn', this.form)
} else {
console.log('error submit!!');
return false;
}
});
},
// 重置
resetForm() {
this.$refs['ruleForm'].resetFields();
},
// 规则条件组编辑
onEditRuleGroup() {
this.loading = true
this.isEdit = false
setTimeout(()=>{
this.form.condition_fields.forEach(item => {
item.input_values = [item.input_content]
})
this.$API.uebaRuleConditionGroupModify(this.form).then(response => {
if (response && response.code === 0) {
this.loading = false
this.$message.success('修改成功')
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},300)
},
onSave() {
this.submitForm(this.onEditRuleGroup)
},
onEdit() {
this.isEdit = true
},
onReset() {
},
// 详情状态 新增规则组
onAddNew() {
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
this.loading = true
this.isEdit = false
setTimeout(()=>{
this.form.condition_fields.forEach(item => {
item.input_values = [item.input_content]
})
const options = {
condition_groups: [this.form],
rule_id: this.rule_id
}
this.$API.uebaRuleConditionGroupAdd(options).then(response => {
if (response && response.code === 0) {
this.loading = false
// 新增成功切换编辑状态,后端返回id
this.form.id = response.data[0]
this.$emit("update:isNewAddFlag", false)
this.$message.success('新增成功')
} else {
this.$message.error(response.msg)
}
}).catch(error => {
console.log(error)
})
},300)
} else {
console.log('error submit!!');
return false;
}
});
},
}
}
</script>
<style lang="scss" scoped>
.filter-group{
.filter-group__item {
margin-top: 16px;
.title {
font-size: 15px;
font-weight: 600;
padding-bottom: 14px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.title-rgith {
display: flex;
align-items: center;
.el-button{
margin-right: 15px;
&:last-child {
margin-right: 0;
}
}
}
}
.sub-title {
margin-bottom: 20px;
text-align: center;
position: relative;
font-size: 13px;
font-weight: 600;
&.rule {
margin-bottom: 30px;
}
span {
display: inline-block;
background: #fff;
position: relative;
z-index: 1;
width: 80px;
}
&:after {
content: '';
height: 0.2px;
width: 100%;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
background: rgba(149,113,223,0.5);
}
}
}
.el-form-item {
position: relative;
.inner-datc-dict{
position: absolute;
top: -30px;
left: 0;
}
}
}
.el-row{
margin-top: 20px;
}
.el-date-editor.el-input {
width: 100%;
}
</style>
export default {
filters: {
// 下拉组件-根据code显示label
selectOptionFilter(code, that, arr) {
if (code !== '') {
if (that.selectColumns(arr).length > 0) {
let data = that.selectColumns(arr).find(v => v.code === code)
if(data){
return data.text
}else {
// 这里兼容【账号告警】下的 告警平台
// 如果字典没有配置,则不做处理,直接返回
return code
}
} else {
return ''
}
}
return ''
}
},
methods: {
selectColumns(arr) {
let columnsInMixin = []
if (arr && arr.length) {
columnsInMixin = arr.map(v => {
return {
text: v.conf_value,
code: v.conf_key
}
})
return columnsInMixin
} else {
return []
}
}
}
}
999e4abe452b5669a92a1c3814e9c4d9.png
f2894c970863e151069347733bfcc733.png
网友评论