This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
cyber-narrator-cn-ui/src/views/detections/detectionPolicies/PolicyForm.vue

573 lines
21 KiB
Vue
Raw Normal View History

2023-08-03 18:47:18 +08:00
<template>
<div class="detection-form">
<loading :loading="myLoading"></loading>
2023-08-03 18:47:18 +08:00
<div class="detection-form-header">
{{ ruleId ? $t('detection.editEventPolicies') : $t('detection.createEventPolicies') }}
2023-08-03 18:47:18 +08:00
</div>
<div class="detection-form-content">
<!--第一步General Settings-->
2023-08-03 18:47:18 +08:00
<div class="detection-form-collapse">
<el-collapse v-model="activeNames">
<el-collapse-item name="1">
<template #title>
<div class="form-collapse-header">
<div :class="activeNames[0]==='1' ? 'form-collapse-header-no-active' : 'form-collapse-header-no'">1</div>
<div class="form-collapse-header-title">{{ $t('detection.create.generalSettings') }}</div>
2023-08-03 18:47:18 +08:00
</div>
</template>
<div class="form-collapse-content">
<general-settings ref="form" :editObj="editObj" :isComplete="isCompleteSetting" @setSettingForm="getFormSetting" />
2023-08-03 18:47:18 +08:00
</div>
</el-collapse-item>
</el-collapse>
</div>
<!--第二步Rule Definition-->
<div class="detection-form-collapse">
<el-collapse v-model="activeNames" class="rule-definition">
2023-08-03 18:47:18 +08:00
<el-collapse-item name="2">
<template #title>
<div class="form-collapse-header">
<div :class="activeNames[0]==='2' ? 'form-collapse-header-no-active' : 'form-collapse-header-no'">2</div>
<div class="form-collapse-header-title">{{ $t('detection.create.ruleDefinition') }}</div>
2023-08-03 18:47:18 +08:00
</div>
</template>
<div class="form-collapse-content">
<rule-definition :settingObj="settingObj" :editObj="editObj" :isComplete="isCompleteRule" @setRuleObj="getRuleObj" />
2023-08-03 18:47:18 +08:00
</div>
</el-collapse-item>
</el-collapse>
</div>
<!--第三步Trigger-->
<div class="detection-form-collapse">
<el-collapse v-model="activeNames" class="policy-form-trigger">
2023-08-03 18:47:18 +08:00
<el-collapse-item name="3">
<template #title>
<div class="form-collapse-header">
<div :class="activeNames[0]==='3' ? 'form-collapse-header-no-active' : 'form-collapse-header-no'">3</div>
<div class="form-collapse-header-title">{{ $t('detection.create.trigger') }}</div>
2023-08-03 18:47:18 +08:00
</div>
</template>
<div class="form-collapse-content margin-t-18">
2023-11-01 12:10:54 +08:00
<el-form v-if="language===EN" class="trigger-block margin-b-20" ref="form3" :model="triggerObj" :rules="rules">
2023-08-03 18:47:18 +08:00
<div class="trigger-block-item margin-b-10">
<div>At least</div>
<el-form-item prop="atLeast">
2024-04-10 16:50:39 +08:00
<el-input maxlength="5" size="small" v-model="triggerObj.atLeast" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
2023-08-03 18:47:18 +08:00
</el-form-item>
<div>times within</div>
<el-form-item prop="interval" class="policy-form-item">
2024-04-10 16:50:39 +08:00
<el-input maxlength="5" size="small" v-model="triggerObj.interval" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
2023-08-03 18:47:18 +08:00
</el-form-item>
2024-04-10 16:50:39 +08:00
<el-form-item prop="intervalVal" class="form-trigger__select">
<el-select v-model="triggerObj.intervalVal" placeholder=" " size="small" @change="resetEditFlag">
2023-08-03 18:47:18 +08:00
<el-option
v-for="item in intervalList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
<div class="trigger-block-item">
<div>With the counter resetting after no activity for</div>
<el-form-item prop="resetInterval" class="policy-form-item">
2024-04-10 16:50:39 +08:00
<el-input maxlength="5" size="small" v-model="triggerObj.resetInterval" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
2023-08-03 18:47:18 +08:00
</el-form-item>
2024-04-10 16:50:39 +08:00
<el-form-item prop="resetIntervalVal" class="form-trigger__select">
<el-select v-model="triggerObj.resetIntervalVal" placeholder=" " size="small" @change="resetEditFlag">
<el-option
v-for="item in intervalList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
2023-08-03 18:47:18 +08:00
</div>
</el-form>
2023-11-01 12:10:54 +08:00
<el-form v-if="language===ZH" class="trigger-block margin-b-20" ref="form3" :model="triggerObj" :rules="rules">
<div class="trigger-block-item margin-b-10">
<el-form-item prop="interval">
<el-input size="small" maxlength="5" v-model="triggerObj.interval" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
</el-form-item>
2024-04-10 16:50:39 +08:00
<el-form-item prop="intervalVal" class="form-trigger__select">
<el-select size="small" v-model="triggerObj.intervalVal" placeholder=" " @change="resetEditFlag">
<el-option
v-for="item in intervalList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
内至少发生
<el-form-item prop="atLeast">
<el-input size="small" maxlength="5" v-model="triggerObj.atLeast" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
</el-form-item>
</div>
<div class="trigger-block-item">
若连续
<el-form-item prop="resetInterval">
<el-input size="small" maxlength="5" v-model="triggerObj.resetInterval" oninput="value=value.replace(/[^\d]/g,'')" @input="resetEditFlag"></el-input>
</el-form-item>
2024-04-10 16:50:39 +08:00
<el-form-item prop="resetIntervalVal" class="form-trigger__select">
<el-select size="small" v-model="triggerObj.resetIntervalVal" placeholder=" " @change="resetEditFlag">
<el-option
v-for="item in intervalList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
不活跃将重置计数
</div>
</el-form>
2023-08-03 18:47:18 +08:00
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
<div class="policy-form__footer">
<div class="policy-form__footer__btn">
<div class="btn1">
<el-button @click="cancel">{{ $t('overall.cancel') }}</el-button>
</div>
<el-button @click="createPolicy">{{ $t('overall.save') }}</el-button>
</div>
</div>
2023-08-03 18:47:18 +08:00
</div>
</template>
<script>
import GeneralSettings from '@/components/table/detection/GeneralSettings'
import RuleDefinition from '@/components/table/detection/RuleDefinition'
import { api } from '@/utils/api'
import axios from 'axios'
import { useRoute } from 'vue-router'
import { ref } from 'vue'
import { getDurationsTimeByType, getTimeByDurations } from '@/utils/date-util'
import Loading from '@/components/common/Loading'
2023-11-01 12:10:54 +08:00
import { storageKey, detectionUnitList, ZH, EN } from '@/utils/constants'
2024-02-02 18:13:11 +08:00
import { ElMessageBox } from 'element-plus'
2023-08-03 18:47:18 +08:00
export default {
name: 'DetectionForm',
data () {
const intervalValidator = (rule, value, callback) => {
const obj = this.handleIntervalByDateType(rule, value, this.triggerObj.intervalVal)
if (obj && !obj.flag && obj.msg) {
callback(new Error(obj.msg))
} else {
callback()
}
}
const intervalValValidator = (rule, value, callback) => {
const obj = this.handleIntervalByDateType(rule, this.triggerObj.intervalVal, value)
if (obj && !obj.flag && obj.msg) {
this.$refs.form3.validateField('interval')
callback()
} else {
callback()
}
}
const resetIntervalValidator = (rule, value, callback) => {
const obj = this.handleIntervalByDateType(rule, value, this.triggerObj.resetIntervalVal)
if (obj && !obj.flag && obj.msg) {
callback(new Error(obj.msg))
} else {
callback()
}
}
const resetIntervalValValidator = (rule, value, callback) => {
const obj = this.handleIntervalByDateType(rule, this.triggerObj.resetIntervalVal, value)
if (obj && !obj.flag && obj.msg) {
this.$refs.form3.validateField('resetInterval')
callback()
} else {
callback()
}
}
2023-08-03 18:47:18 +08:00
return {
activeNames: ['1'],
rules: {
atLeast: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
}
],
interval: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
},
{
validator: intervalValidator,
trigger: 'blur'
2023-08-03 18:47:18 +08:00
}
],
intervalVal: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'change'
},
{
validator: intervalValValidator,
trigger: 'change'
2023-08-03 18:47:18 +08:00
}
],
resetInterval: [
2023-08-03 18:47:18 +08:00
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
},
{
validator: resetIntervalValidator,
trigger: 'blur'
2023-08-03 18:47:18 +08:00
}
],
resetIntervalVal: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'change'
},
{
validator: resetIntervalValValidator,
trigger: 'change'
}
2023-08-03 18:47:18 +08:00
]
},
intervalList: [],
editObj: {},
isCompleteSetting: true, // 参数完整标识默认完整照顾编辑模式false即不完整
isCompleteRule: true, // 参数完整标识默认完整照顾编辑模式false即不完整
2023-11-01 12:10:54 +08:00
language: EN,
ZH,
EN
2023-08-03 18:47:18 +08:00
}
},
components: {
GeneralSettings,
RuleDefinition,
Loading
2023-08-03 18:47:18 +08:00
},
mounted () {
2023-11-01 12:10:54 +08:00
this.language = localStorage.getItem(storageKey.language) || EN
if (this.language === EN) {
this.intervalList = detectionUnitList.intervalList
2023-11-01 12:10:54 +08:00
} else if (this.language === ZH) {
this.intervalList = detectionUnitList.intervalListCN
}
this.getDetailInfo()
},
setup () {
const { query } = useRoute()
const ruleId = ref(query.id || '')
const pageNoForTable = ref(query.pageNoForTable || 1)
const myLoading = ref(!!ruleId.value)
// General Settings即第一步的form表单信息
const settingObj = ref({})
// 第二步的form表单信息
const ruleObj = ref({})
// 第三步的form表单信息
const triggerObj = ref({
atLeast: '',
interval: '',
intervalVal: '',
resetInterval: '',
resetIntervalVal: '',
editFlag: false
})
return {
ruleId,
myLoading,
pageNoForTable,
settingObj,
ruleObj,
triggerObj
}
2023-08-03 18:47:18 +08:00
},
methods: {
/** 编辑时获取详情 */
getDetailInfo () {
if (this.ruleId) {
axios.get(`${api.detection.detail}/${this.ruleId}`).then(response => {
if (response.status === 200) {
if (!response.data.data) {
throw new Error('No data found, id: ' + this.ruleId)
}
this.myLoading = false
this.editObj = { ...response.data.data, ruleId: this.ruleId }
this.settingObj = this.$_.cloneDeep(this.editObj)
this.settingObj.editFlag = false
this.settingObj.saveFlag = true
this.ruleObj = this.$_.cloneDeep(this.editObj.ruleConfigObj)
this.triggerObj = this.$_.cloneDeep(this.editObj.ruleTriggerObj)
this.triggerObj.intervalVal = getTimeByDurations(this.triggerObj.interval).type
this.triggerObj.interval = getTimeByDurations(this.triggerObj.interval).value
this.triggerObj.resetIntervalVal = getTimeByDurations(this.triggerObj.resetInterval).type
this.triggerObj.resetInterval = getTimeByDurations(this.triggerObj.resetInterval).value
this.activeNames = ['1', '2', '3']
} else {
console.error(response.data)
}
}).catch(e => {
console.error(e)
this.$message.error(this.errorMsgHandler(e))
this.$router.push({
2023-11-09 16:17:25 +08:00
path: '/detection/policy',
query: {
pageNo: this.pageNoForTable ? Number(this.pageNoForTable) : 1,
t: +new Date()
}
})
})
}
2023-08-03 18:47:18 +08:00
},
/** 获取General Settings折叠板form数据 */
getFormSetting (data) {
if (data.saveFlag) {
this.handleActiveNames('1', this.activeNames, data.settingNoContinue)
}
2023-08-03 18:47:18 +08:00
this.settingObj = JSON.parse(JSON.stringify(data))
},
/** 获取Rule Definition折叠板form数据 */
getRuleObj (data) {
if (data.dataSource && data.knowledgeId && data.level) {
data.editFlag = false
data.saveFlag = true
this.handleActiveNames('2', this.activeNames, data.ruleNoContinue)
}
2023-08-03 18:47:18 +08:00
this.ruleObj = JSON.parse(JSON.stringify(data))
},
/** 自动展开收起折叠板 */
handleActiveNames (name, arr, flag) {
if (!flag) {
const list = arr
list.splice(list.indexOf(name), 1)
if (name === '1' && list.indexOf('2') < 0) {
list.push('2')
}
if (name === '2' && list.indexOf('3') < 0) {
list.push('3')
}
this.activeNames = []
list.forEach(t => {
this.activeNames.push(t)
})
}
2023-08-03 18:47:18 +08:00
},
/** 创建policy */
createPolicy () {
2023-08-03 18:47:18 +08:00
const settingLen = Object.keys(this.settingObj).length
const ruleLen = Object.keys(this.ruleObj).length
if (settingLen > 0 && ruleLen > 0) {
this.$refs.form3.validate(valid => {
if (valid) {
// 最终提交form
const formObj = this.$_.cloneDeep({ ...this.settingObj, ruleConfig: JSON.stringify(this.ruleObj), ruleTrigger: this.triggerObj })
// 将时间转为参数所需如5分钟转为PT5M
formObj.ruleTrigger.resetInterval = getDurationsTimeByType(formObj.ruleTrigger.resetInterval, formObj.ruleTrigger.resetIntervalVal)
formObj.ruleTrigger.interval = getDurationsTimeByType(formObj.ruleTrigger.interval, formObj.ruleTrigger.intervalVal)
formObj.ruleTrigger.atLeast = parseInt(formObj.ruleTrigger.atLeast)
formObj.ruleTrigger = JSON.stringify(formObj.ruleTrigger)
// 删除多余参数
delete formObj.ruleConfigObj
delete formObj.ruleTriggerObj
delete formObj.editFlag
delete formObj.saveFlag
if (!this.ruleId) {
// post调用是新增put是编辑
this.myLoading = true
axios.post(api.detection.create.create, formObj).then(response => {
if (response.status === 200) {
this.$message({
duration: 2000,
type: 'success',
message: this.$t('tip.saveSuccess')
})
this.$router.push({
2023-11-09 16:17:25 +08:00
path: '/detection/policy',
query: {
t: +new Date()
}
})
} else {
console.error(response.data.message)
this.$message.error(this.errorMsgHandler(response))
}
}).catch(e => {
console.error(e)
this.$message.error(this.errorMsgHandler(e))
}).finally(() => {
this.myLoading = false
})
} else {
this.myLoading = true
axios.put(api.detection.create.create, formObj).then(response => {
if (response.status === 200) {
this.$message({
duration: 2000,
type: 'success',
message: this.$t('tip.saveSuccess')
})
const { query } = this.$route
const queryInfo = {
pageNo: self.pageNoForTable ? Number(self.pageNoForTable) : 1,
t: +new Date()
}
if (query.name && query.id) {
queryInfo.ruleId = query.id
queryInfo.name = this.settingObj.name
}
this.$router.push({
2023-11-09 16:17:25 +08:00
path: '/detection/policy',
query: queryInfo
})
} else {
console.error(response.data.message)
this.$message.error(this.errorMsgHandler(response))
}
}).catch(e => {
console.error(e)
this.$message.error(this.errorMsgHandler(e))
}).finally(() => {
this.myLoading = false
})
}
} else {
this.isCompleteSetting = false
this.isCompleteRule = false
2023-08-03 18:47:18 +08:00
}
})
} else if (settingLen === 0) {
this.isCompleteSetting = false
2023-08-03 18:47:18 +08:00
this.handleFormError('1')
} else if (ruleLen === 0) {
this.isCompleteRule = false
2023-08-03 18:47:18 +08:00
this.handleFormError('2')
}
},
handleFormError (name) {
const list = this.activeNames
if (list.indexOf(name) < 0) {
list.push(name)
this.activeNames = []
list.forEach(t => {
this.activeNames.push(t)
})
}
this.$message.error(this.$t('detection.create.informationFilled'))
},
handleIntervalByDateType (rule, value, type) {
if (value && (type === 'hours' || type === '小时')) {
if (parseInt(value) <= 24) {
return { flag: true }
} else {
return { flag: false, msg: this.$t('policy.dateTimeRangeHours') }
}
}
if (value && (type === 'minutes' || type === '分钟')) {
if (parseInt(value) <= 1440) {
return { flag: true }
} else {
return { flag: false, msg: this.$t('policy.dateTimeRangeMinutes') }
}
}
if (value && (type === 'seconds' || type === '秒')) {
if (parseInt(value) <= 86400) {
return { flag: true }
} else {
return { flag: false, msg: this.$t('policy.dateTimeRangeSeconds') }
}
}
},
cancel () {
const { query } = this.$route
const queryInfo = {
pageNo: this.pageNoForTable ? Number(this.pageNoForTable) : 1,
t: +new Date()
}
if (query.name && query.id) {
queryInfo.ruleId = query.id
queryInfo.name = this.settingObj.name
}
if (this.settingObj.editFlag || this.ruleObj.editFlag || this.triggerObj.editFlag) {
// if (this.settingObj.editFlag) {
// this.isCompleteSetting = false
// this.handleFormError('1')
// }
// if (this.ruleObj.editFlag) {
// this.isCompleteRule = false
// this.handleFormError('2')
// }
if (this.triggerObj.editFlag) {
this.$refs.form3.validate(valid => {
if (!valid) {
this.confirmMessage(queryInfo)
} else {
this.$router.push({
path: '/detection/policy',
query: queryInfo
})
}
})
} else {
this.confirmMessage(queryInfo)
}
} else {
this.$router.push({
path: '/detection/policy',
query: queryInfo
})
}
},
confirmMessage (queryInfo) {
2024-02-02 18:13:11 +08:00
ElMessageBox.confirm(this.$t('tip.leavePage'), {
confirmButtonText: this.$t('tip.confirm'),
cancelButtonText: this.$t('overall.cancel'),
message: this.$t('tip.leavePageTips'),
title: this.$t('tip.leavePage'),
2024-02-02 18:13:11 +08:00
// type: 'warning',
iconClass: 'width:0px;height:0px;',
customClass: 'del-model'
}).then(() => {
this.$router.push({
path: '/detection/policy',
query: queryInfo
})
}).catch(() => {})
},
resetEditFlag () {
this.triggerObj.editFlag = true
2023-08-03 18:47:18 +08:00
}
}
}
</script>