<template>
|
<div class="edit-rules-box">
|
<p style="padding: 0">
|
<b style="font-size: 14px; line-height: 28px;">策略配置</b>
|
<span class="btn" @click="createRule" v-if="groupRules.length === 0">
|
<i class="iconfont iconhebingxingzhuang" style="font-size:16px"></i>
|
新增
|
</span>
|
|
<span class="btn" @click="cleanRule" v-if="groupRules.length > 0">
|
<i class="iconfont iconshanchu11" style="font-size:16px"></i>
|
清空
|
</span>
|
</p>
|
<div class="sub-task-rules-box">
|
<span class="task-blank" v-show="groupRules.length == 0 ">暂无规则,请选择新增规则配置</span>
|
<div style=" text-align: left;" v-for="(rule, index) in groupRules" :key="index">
|
<div style="margin-left:10px;margin-top: 4px;" v-show="index > 0">
|
<el-select v-model="rule.rule_with_pre" placeholder="并列关系" size="mini">
|
<el-option
|
v-for="subitem in VideoManageData.Dictionary.RULECOMPUTEBETWEEN"
|
:key="subitem.id"
|
:label="subitem.name"
|
:value="subitem.value"
|
:title="subitem.name"
|
></el-option>
|
</el-select>
|
</div>
|
|
<div style="margin-left:10px;">
|
<!-- 选择区域 -->
|
<el-select
|
v-model="rule.polygonObj"
|
v-if="!isTemplate"
|
value-key="polygonId"
|
placeholder="选择区域"
|
size="mini"
|
@change="selectPolygonOption(rule)"
|
>
|
<el-option
|
v-for="subitem in allPolygonData"
|
:key="subitem.id"
|
:label="subitem.name"
|
:value="subitem"
|
:title="subitem.name"
|
></el-option>
|
</el-select>
|
|
<!-- 选择算法 -->
|
<el-select
|
v-model="rule.sdkObj"
|
value-key="id"
|
placeholder="选择算法"
|
size="mini"
|
@change="selectSDKOption(rule, true)"
|
>
|
<el-option
|
v-for="subitem in rule.sdksOptions"
|
:key="subitem.id"
|
:label="subitem.sdk_name"
|
:value="subitem"
|
:title="subitem.sdk_name"
|
v-show="!subitem.delete"
|
></el-option>
|
</el-select>
|
|
<!-- 选择类型 -->
|
<el-select
|
v-model="rule.sdk_arg_type"
|
placeholder="目标"
|
size="mini"
|
style="width:90px;"
|
@change="selectArgTypeOption(rule)"
|
>
|
<el-option value="target" label="目标"></el-option>
|
<el-option value="label" label="标签"></el-option>
|
</el-select>
|
|
<!-- 选择规则 -->
|
<el-select
|
v-model="rule.argObj"
|
value-key="alias"
|
placeholder="选择规则"
|
size="mini"
|
@change="selectArgsOption(rule, true)"
|
>
|
<el-option
|
v-for="subitem in rule.argsOptions"
|
:key="subitem.alias"
|
:label="subitem.name"
|
:value="subitem"
|
:title="subitem.name"
|
></el-option>
|
</el-select>
|
|
<!-- 选择条件 -->
|
<el-select
|
v-model="rule.operatorObj"
|
value-key="value"
|
placeholder="选择条件"
|
size="mini"
|
style="min-width:100px;width:8%"
|
@change="setOperator(rule)"
|
>
|
<el-option
|
v-for="subitem in VideoManageData.Dictionary.RULECOMPUTE"
|
:key="subitem.value"
|
:label="subitem.name"
|
:value="subitem"
|
></el-option>
|
</el-select>
|
|
<!-- 值类型 -->
|
<el-select
|
v-show="false"
|
v-model="rule.operator_type"
|
placeholder="值类型"
|
size="mini"
|
style="min-width:100px;width:8%"
|
@change="selectValueOption(rule)"
|
>
|
<el-option value="value" label="值" :disabled="rule.argType === 'option'"></el-option>
|
<el-option value="option" label="被选项" :disabled="rule.argType !== 'option'"></el-option>
|
<el-option value label="空" :disabled="rule.argType === 'option'"></el-option>
|
</el-select>
|
|
<!-- 值 -->
|
<el-input
|
v-if="rule.operator_type !== 'option'"
|
size="mini"
|
v-model="rule.sdk_arg_value"
|
:style="rule.valid ? `margin:3px 5px;min-width:100px;width:7%` : `margin:3px 5px;min-width:100px;width:7%;border:1px solid red`"
|
@change="setValue(rule)"
|
></el-input>
|
|
<!-- 选项值 -->
|
<el-select
|
v-else
|
v-model="rule.valueObj"
|
value-key="value"
|
size="mini"
|
style="width:8%;min-width:100px"
|
@change="setValue(rule)"
|
>
|
<el-option
|
v-for="subitem in rule.valueOptions"
|
:key="subitem.value"
|
:label="subitem.name"
|
:value="subitem"
|
:title="subitem.name"
|
></el-option>
|
</el-select>
|
|
<!-- 单位 -->
|
<span style="display:inline-block;width:15px;margin-right:10px;">{{ rule.unit }}</span>
|
|
<!-- 新增、删除 按钮 -->
|
<el-button type="text" @click="addRule(index)" class="iconfont iconhebingxingzhuang"></el-button>
|
<el-button
|
type="text"
|
style="color: #F53D3D;"
|
class="iconfont iconshanchu11"
|
@click="groupRules.splice(index, 1)"
|
></el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<script>
|
import {
|
deleteCameraRules,
|
updateRuleDefence,
|
updateAlarmLevel
|
} from "@/api/camera";
|
|
export default {
|
name: "SceneRuleEditor",
|
props: {
|
Cameras: {
|
type: Array,
|
default: () => {
|
return []
|
}
|
},
|
isTemplate: {
|
type: Boolean,
|
default: false
|
},
|
isLinkRule: {
|
type: Boolean,
|
default: false
|
},
|
includeSdks: {
|
type: Array
|
},
|
ruleList: {
|
type: String,
|
default: "{}"
|
},
|
onSubmitRule: {
|
type: Function,
|
default: () => false
|
}
|
},
|
computed: {
|
allPolygonData() {
|
let polygon = [];
|
let cameras = [...this.Cameras];
|
|
for (let i = 0; i < cameras.length; i++) {
|
let polyOpt = cameras[i].polygonData.map(p => {
|
return {
|
defence_state: p.defence_state,
|
polygonId: p.id,
|
name: this.isLinkRule
|
? cameras[i].cameraName + ":" + p.name
|
: p.name,
|
|
cameraId: cameras[i].cameraId
|
};
|
});
|
|
polygon = polygon.concat(polyOpt);
|
}
|
return polygon;
|
}
|
},
|
watch: {
|
ruleList: {
|
handler(newVal, oldVal) {
|
this.editHandle(newVal);
|
},
|
deep: true
|
},
|
},
|
mounted() {
|
this.editHandle(this.ruleList);
|
},
|
data() {
|
return {
|
tasksTable: {},
|
groupRules: [],
|
sdksOption: [],
|
baseRule: {
|
camera_id: "",
|
id: "",
|
operator: "",
|
operator_type: "",
|
polygon_id: "",
|
rule_with_pre: "",
|
sdk_id: "",
|
sdk_arg_alias: "",
|
sdk_arg_value: "",
|
sdk_arg_defaultValue: "",
|
select_time_rule: "",
|
sdk_arg_type: "",
|
// task_id: "",
|
|
polygonObj: {},
|
taskObj: "",
|
|
sdkObj: {},
|
argObj: {},
|
operatorObj: {},
|
valueObj: {},
|
|
sdksOptions: [],
|
argsOptions: [],
|
argType: "",
|
computeOptions: [],
|
valueOptions: [],
|
|
sdkDesc: "",
|
argDesc: "",
|
operatorDesc: "",
|
typeDesc: "",
|
valueDesc: "",
|
|
unit: "",
|
value: "",
|
valid: true
|
},
|
};
|
},
|
methods: {
|
setSdksOptions(rule) {
|
rule.sdksOptions = this.includeSdks;
|
},
|
setOperator(rule) {
|
rule.operator = rule.operatorObj.value;
|
rule.operatorDesc = rule.operatorObj.name;
|
},
|
setValue(rule) {
|
rule.valid = true
|
|
if (rule.operator_type === "option") {
|
rule.sdk_arg_value = rule.valueObj.value ? rule.valueObj.value : "";
|
rule.typeDesc = "被选项";
|
rule.valueDesc = rule.valueObj.name ? rule.valueObj.name : "";
|
} else {
|
rule.typeDesc = "值";
|
rule.valueDesc = rule.sdk_arg_value;
|
}
|
this.valideArgValue(rule)
|
},
|
selectPolygonOption(rule) {
|
rule.polygon_id = rule.polygonObj.polygonId ? rule.polygonObj.polygonId : rule.polygon_id;
|
rule.camera_id = rule.polygonObj.cameraId ? rule.polygonObj.cameraId : rule.camera_id;
|
rule.group_id = this.group_id;
|
},
|
selectSDKOption(rule, resetArgs) {
|
rule.sdk_id = rule.sdkObj.id;
|
rule.sdkDesc = `<span style="background-color:RGB(183,183,183);">${rule.sdkObj.sdk_name}</span>`;
|
|
// 选项切换时需要刷新arg菜单项
|
this.selectArgTypeOption(rule, resetArgs)
|
},
|
selectArgTypeOption(rule, resetAlias) {
|
if (rule.sdk_arg_type == "") {
|
return
|
}
|
|
if (resetAlias) {
|
rule.sdk_arg_alias = "";
|
}
|
|
rule.argsOptions = rule.sdkObj.args;
|
|
// 根据arg类型显示参数, 当前全部归为 target
|
// if (rule.sdkObj.args) {
|
// rule.argsOptions = rule.sdkObj.args.filter(ele => {
|
// return ele.arg_type === rule.sdk_arg_type
|
// });
|
// } else {
|
// rule.argsOptions = [];
|
// }
|
|
rule.argObj = {};
|
},
|
selectArgsOption(rule, resetArgValue) {
|
// rule.operator_type = "";
|
// console.log(rule, '选择算法参数')
|
rule.sdk_arg_alias = rule.argObj.alias;
|
rule.argDesc = rule.argObj.name;
|
rule.sdk_arg_defaultValue = rule.argObj.default_value
|
rule.unit = rule.argObj.unit ? rule.argObj.unit : "";
|
//rule.default_value = rule.argObj.default_value ? Number(rule.argObj.default_value) : 0;
|
|
//console.log("置信度的默认值为",rule.sdk_arg_defaultValue)
|
// 保存值类型
|
rule.argType = rule.argObj.type;
|
if (rule.argType === "option") {
|
rule.operator_type = "option";
|
// 设置默认条件值
|
this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
|
if (opt.value == "==") {
|
rule.operatorObj = opt;
|
}
|
});
|
|
this.setOperator(rule);
|
|
this.selectValueOption(rule);
|
} else {
|
// 设置默认条件值
|
rule.operator_type = "value";
|
if (resetArgValue) {
|
rule.sdk_arg_value = ""
|
|
this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
|
if (opt.value == ">=") {
|
rule.operatorObj = opt;
|
}
|
});
|
} else {
|
// 编辑规则匹配
|
this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
|
if (opt.value == rule.operator) {
|
rule.operatorObj = opt;
|
}
|
});
|
}
|
this.setOperator(rule);
|
}
|
},
|
selectValueOption(rule) {
|
if (rule.sdk_arg_alias === "time_rule") {
|
rule.valueOptions = this.VideoManageData.TimeRules.map(r => {
|
return {
|
name: r.name,
|
value: r.id
|
};
|
});
|
} else if (rule.sdk_arg_alias === "compareBase") {
|
rule.valueOptions = this.VideoManageData.TagList.map(r => {
|
return {
|
name: r.tableName,
|
value: r.id
|
};
|
});
|
} else {
|
let ops = this.VideoManageData.Dictionary[rule.sdk_arg_alias]
|
if (ops && ops instanceof (Array)) {
|
rule.valueOptions = ops.map(r => {
|
return {
|
name: r.name,
|
value: r.value
|
}
|
})
|
}
|
}
|
},
|
valideArgValue(rule) {
|
if (rule.sdk_arg_value == "") {
|
this.$notify({
|
type: 'warning',
|
message: "参数设定值不能为空!"
|
})
|
rule.valid = false
|
return false
|
}
|
|
if (rule.argObj && rule.argObj.range) {
|
// 如果设置了算法默认值,则判断不能小于该值
|
if (rule.argObj.default_value) {
|
if (parseInt(rule.sdk_arg_value) < parseInt(rule.sdk_arg_defaultValue)) {
|
rule.valid = false
|
this.$notify({
|
type: "warning",
|
message: "参数设定值不能小于算法参数默认值 " + rule.sdk_arg_defaultValue
|
})
|
rule.valueDesc = rule.sdk_arg_value = rule.argObj.default_value;
|
rule.valid = false
|
return false;
|
}
|
}
|
|
// let re = /(?<=,).*?(?=]|\))/
|
let re = /.*,(\d+)/
|
let max = rule.argObj.range.match(re)[1]
|
// console.log(max,'获取范围最大值')
|
if (Number(rule.sdk_arg_value) > Number(max)) {
|
rule.valid = false
|
this.$notify({
|
type: 'warning',
|
message: "参数设定值不能大于" + max
|
})
|
return false
|
}
|
}
|
|
return true;
|
},
|
parataxis(rule_with_pre) {
|
let relation = "";
|
this.VideoManageData.Dictionary.RULECOMPUTEBETWEEN.forEach(pre => {
|
if (pre.value === rule_with_pre) {
|
relation = pre.name;
|
}
|
});
|
|
return relation;
|
},
|
|
generatDescription() {
|
let desc = "";
|
this.groupRules.forEach((r, index) => {
|
// console.log(r,index,'拼接')
|
if (index === 0) {
|
desc +=
|
|
r.sdkDesc +
|
r.argDesc +
|
r.operatorDesc +
|
r.valueDesc +
|
r.unit
|
} else {
|
desc +=
|
' ' + this.parataxis(r.rule_with_pre) + ' ' +
|
r.sdkDesc +
|
r.argDesc +
|
r.operatorDesc +
|
r.valueDesc +
|
r.unit
|
}
|
});
|
// console.log(desc,'拼接')
|
return desc;
|
},
|
createRule() {
|
if (!this.isTemplate && this.Cameras.length > 0) {
|
// 未选中摄像机或者未选中摄像机任务,不执行创建
|
if (!this.Cameras[0].cameraId)
|
return false;
|
}
|
|
if (this.isLinkRule && this.TreeDataPool.selectedNodes.length < 2) {
|
this.$notify({
|
type: "warning",
|
message: "请选择至少2个摄像机!"
|
})
|
return false;
|
}
|
|
this.group_id = "";
|
|
this.addRule(0);
|
},
|
cleanRule() {
|
this.groupRules.splice(0, this.groupRules.length);
|
},
|
addRule(index) {
|
let newRule = JSON.parse(JSON.stringify(this.baseRule));
|
newRule.sdksOptions = this.includeSdks;
|
if (!this.isLinkRule) {
|
// 设置默认全部区域
|
// if (!this.isTemplate) {
|
// newRule.polygonObj = this.allPolygonData[0];
|
// this.selectPolygonOption(newRule)
|
// }
|
|
// 设置算法
|
// newRule.sdksOptions = this.includeSdks;
|
// 设置默认算法
|
// newRule.sdkObj = newRule.sdksOptions[0]
|
// this.selectSDKOption(newRule, false)
|
|
// newRule.sdk_arg_type = "target"
|
// this.selectArgTypeOption(newRule, true)
|
}
|
|
// this.groupRules.push(newRule);
|
// 插入到指定位置
|
this.groupRules.splice(index + 1, 0, newRule);
|
},
|
editHandle(ruleTxt) {
|
if (ruleTxt.length < 1) {
|
return;
|
}
|
let ruleInfo = JSON.parse(ruleTxt);
|
this.editRule(ruleInfo)
|
// 如果是联动任务, 查询联动摄像机列表, 将树选中的列表更改为该条规则所需要的摄像机, 并备份当前的选中状态, 规则保存后恢复
|
// if (this.isLinkRule) {
|
// this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = [...this.TreeDataPool.selectedNodes]
|
// this.VideoRuleData.editLinkRuleRow = { ...ruleInfo }
|
|
// this.TreeDataPool.selectedNodes = ruleInfo.group_rules.map(r => {
|
// return r.camera_id
|
// })
|
// this.$nextTick(() => {
|
// setTimeout(() => {
|
// this.editRule(ruleInfo)
|
// }, 1000)
|
// })
|
// } else {
|
// this.editRule(ruleInfo)
|
// }
|
},
|
editRule(ruleGroup) {
|
this.group_id = "";
|
|
ruleGroup.forEach(rule => {
|
if (rule.group_id && rule.group_id != "") {
|
this.group_id = rule.group_id;
|
}
|
|
// 填充区域选项列表
|
this.allPolygonData.forEach(p => {
|
if (p.polygonId === rule.polygon_id) {
|
rule.polygonObj = p;
|
}
|
});
|
|
if (!rule.polygonObj) {
|
rule.polygonObj = {
|
cameraId: rule.camera_id,
|
defence_state: 1,
|
name: "未知区域",
|
polygonId: rule.polygon_id,
|
}
|
}
|
|
// 设置区域
|
this.selectPolygonOption(rule);
|
|
// 设置算法组
|
this.setSdksOptions(rule);
|
|
// 填充算法选项列表
|
if (rule.sdksOptions) {
|
rule.sdksOptions.forEach(s => {
|
if (s.id === rule.sdk_id) {
|
rule.sdkObj = s;
|
}
|
});
|
}
|
if (!rule.sdkObj || Object.keys(rule.sdkObj).length === 0) {
|
rule.sdkObj = {
|
id: rule.sdk_id,
|
sdk_name: "(已删除)",
|
args: [],
|
delete: true
|
}
|
rule.sdksOptions.push(rule.sdkObj)
|
}
|
|
this.selectSDKOption(rule, false);
|
// 规则保存时数据库不存参数类型,需要根据值反查
|
// rule.sdk_arg_type = ""
|
// if (rule.sdk_arg_alias === "time_rule") {
|
// rule.sdk_arg_type = "target"
|
// }
|
rule.sdk_arg_type = "target"
|
// rule.sdkObj.args.forEach(ele => {
|
// if (ele.alias === rule.sdk_arg_alias) {
|
// rule.sdk_arg_type = ele.arg_type
|
// }
|
// });
|
this.selectArgTypeOption(rule, false)
|
|
if (rule.argsOptions) {
|
rule.argsOptions.forEach(arg => {
|
if (arg.alias === rule.sdk_arg_alias) {
|
rule.argObj = arg;
|
}
|
});
|
this.selectArgsOption(rule, false);
|
}
|
|
this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
|
if (opt.value == rule.operator) {
|
rule.operatorObj = opt;
|
}
|
});
|
|
this.setOperator(rule);
|
this.selectValueOption(rule);
|
|
if (rule.operator_type == "option") {
|
rule.valueOptions.forEach(val => {
|
if (val.value === rule.sdk_arg_value) {
|
rule.valueObj = val;
|
}
|
});
|
}
|
if (!rule.valueObj) {
|
rule.valueObj = {
|
name: rule.sdk_arg_value,
|
value: rule.sdk_arg_value
|
}
|
}
|
this.setValue(rule);
|
});
|
this.$nextTick(() => {
|
this.groupRules = ruleGroup;
|
});
|
},
|
delRule(rule) {
|
this.$confirm("提示:删除后,该条规则将失效,是否删除?", {
|
center: true,
|
cancelButtonClass: "comfirm-class-cancle",
|
confirmButtonClass: "comfirm-class-sure"
|
})
|
.then(() => {
|
deleteCameraRules({ groupId: rule.group_id }).then(res => {
|
if (res && res.success) {
|
this.$notify({
|
type: "success",
|
message: "删除成功"
|
});
|
this.$emit("delete-rule");
|
} else {
|
this.$notify({
|
type: "error",
|
message: "删除失败!"
|
});
|
}
|
});
|
})
|
.catch(() => { });
|
},
|
submitRule() {
|
let groupRule = {};
|
let group_text = "";
|
|
if (this.isTemplate) {
|
groupRule.rules = this.groupRules.map(r => {
|
return {
|
sdk_id: r.sdk_id,
|
sdk_arg_alias: r.sdk_arg_alias,
|
operator: r.operator,
|
operator_type: r.operator_type,
|
sdk_arg_value: r.sdk_arg_value,
|
sort: 1,
|
rule_with_pre: r.rule_with_pre
|
};
|
})
|
} else {
|
groupRule.rules = this.groupRules.map(r => {
|
return {
|
camera_id: r.camera_id,
|
group_id: r.group_id,
|
id: r.id,
|
operator: r.operator,
|
operator_type: r.operator_type,
|
polygon_id: r.polygon_id,
|
rule_with_pre: r.rule_with_pre,
|
sdk_arg_alias: r.sdk_arg_alias,
|
sdk_arg_value: r.sdk_arg_value,
|
sdk_id: r.sdk_id,
|
};
|
})
|
}
|
|
groupRule.text = this.generatDescription();
|
groupRule.id = this.group_id;
|
return groupRule;
|
|
// 暂时先不验证
|
for (let i in this.groupRules) {
|
let rule = this.groupRules[i]
|
if (!rule.polygon_id || !rule.sdk_id || !rule.operator || !rule.operator_type || rule.sdk_arg_type == "") {
|
this.$notify({
|
type: "error",
|
message: "不允许配置不完整的规则,请检查是否有未选择项"
|
})
|
return;
|
}
|
if (!this.valideArgValue(rule)) {
|
return;
|
}
|
}
|
|
if (this.isLinkRule) {
|
// 判断规则中至少包含两摄像机
|
let cameraIds = Array.from(new Set(this.groupRules.map(r => {
|
return r.camera_id
|
})))
|
if (cameraIds.length < 2) {
|
this.$notify({
|
type: "error",
|
message: "需要2个不同摄像机才能组成联动规则"
|
})
|
return
|
}
|
|
// 联动规则编辑后,恢复之前选中的摄像机
|
// if (this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule.length) {
|
// this.TreeDataPool.selectedNodes = this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule
|
// this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = []
|
// }
|
}
|
|
this.onSubmitRule(payload);
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss">
|
.edit-rules-box {
|
width: 100%;
|
padding: 0px;
|
box-sizing: border-box;
|
.sub-task-rules-box {
|
width: 100%;
|
min-height: 50px;
|
border-top: 1px solid #eee;
|
padding-top: 7px;
|
|
box-sizing: border-box;
|
padding-bottom: 38px;
|
.task-rules-button {
|
text-align: right;
|
margin: 15px;
|
}
|
|
.el-select {
|
margin: 3px 8px;
|
min-width: 130px;
|
width: 12%;
|
}
|
}
|
|
.el-button--text {
|
text-decoration: unset;
|
}
|
|
p {
|
text-align: left;
|
// padding: 10px;
|
box-sizing: border-box;
|
}
|
|
.task-blank {
|
float: left;
|
font-family: PingFangSC-Regular;
|
font-size: 12px;
|
color: #cccccc;
|
margin-top: 5px;
|
}
|
|
.btn {
|
cursor: pointer;
|
color: #3d68e1;
|
margin-left: 10px;
|
font-size: 14px;
|
}
|
}
|
</style>
|