<template>
|
<div class="scene-edit-container">
|
<div class="scene-title">
|
<b style="font-size: 14px; line-height: 18px">督查任务</b>
|
<el-button type="primary" size="mini" @click="handleCreate" style="margin-left: 90%"
|
v-show="!editScene && TreeDataPool.selectedNode.type !== 'MENU'">+ 添加任务</el-button>
|
</div>
|
|
<el-form ref="form" label-width="80px" v-show="editScene">
|
<div class="flex-form">
|
<div class="left">
|
<el-form-item label="任务名称">
|
<el-input v-model="sceneForm.scene_name" size="mini" maxlength="15"></el-input>
|
</el-form-item>
|
<el-form-item label="事件等级">
|
<el-select v-model="sceneForm.alarm_level" placeholder="请选择" size="mini" style="width: 250px">
|
<el-option label="一级" :value="1"></el-option>
|
<el-option label="二级" :value="2"></el-option>
|
<el-option label="三级" :value="3"></el-option>
|
<el-option label="四级" :value="4"></el-option>
|
<el-option label="五级" :value="5"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="时间段">
|
<el-select v-model="sceneForm.workTimeId" placeholder="请选择" size="mini">
|
<el-option v-for="item in VideoManageData.TimeRules" :key="item.id" :label="item.name"
|
:value="item.id"></el-option>
|
</el-select>
|
</el-form-item>
|
<!-- 检测内容 -->
|
<el-form-item label="检测内容">
|
<el-select v-model="sceneForm.checkContents" multiple placeholder="请选择" size="mini">
|
<el-option v-for="item in VideoManageData.checkOptions" :key="item.checkId" :label="item.fileName"
|
:value="item.checkId"></el-option>
|
</el-select>
|
</el-form-item>
|
|
|
</div>
|
<div class="right">
|
<el-form-item label="任务描述">
|
<el-input v-model="sceneForm.desc" type="textarea" size="mini"></el-input>
|
</el-form-item>
|
<!-- 预警规则 -->
|
<el-form-item label="预警规则">
|
<el-select v-model="sceneForm.warningRules" placeholder="请选择" size="mini" multiple>
|
<el-option v-for="item in VideoManageData.ruleOptions" :key="item.ruleId" :label="item.fileName"
|
:value="item.ruleId"></el-option>
|
</el-select>
|
</el-form-item>
|
<!-- 知识库 -->
|
<el-form-item label="知识库" size="mini">
|
<el-cascader v-model="sceneForm.knowsList" :options="VideoManageData.knowsList" :props="knowledgeProps"
|
clearable filterable placeholder="请选择" class="knowledge-cascader" :show-all-levels="false"></el-cascader>
|
</el-form-item>
|
<!-- <el-form-item label="事件声音">
|
<el-select
|
v-model="sceneForm.voice"
|
placeholder="空"
|
size="small"
|
value-key="id"
|
@change="selSound"
|
>
|
<el-option
|
v-for="item in soundList"
|
:key="item.id"
|
:label="item.name"
|
:value="item"
|
></el-option>
|
</el-select>
|
<span
|
@click="togglePlayer"
|
style="cursor: pointer; margin-left: 20px"
|
v-show="sceneForm.voiceId.length"
|
>
|
<i
|
v-if="togglePlay"
|
class="el-icon-video-play"
|
style="font-size: 26px; vertical-align: middle; color: #409eff"
|
></i>
|
<i
|
v-else
|
class="el-icon-video-pause"
|
style="font-size: 26px; vertical-align: middle; color: #409eff"
|
></i>
|
</span>
|
</el-form-item> -->
|
</div>
|
</div>
|
|
<!-- <scene-editor
|
ref="sceneEditor"
|
:isLinkRule="linkRule"
|
:Cameras="seletedCameras"
|
:ruleList="templateRules"
|
@sdkNameChange="getSceneName"
|
></scene-editor> -->
|
|
|
<el-form-item style="width: 60%; min-width: 1048px">
|
<el-button size="mini" @click="editScene = false">取消</el-button>
|
<el-button type="primary" size="mini" @click="saveSceneRule">保存</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!-- 规则列表 -->
|
<div class="edit-rule-table" v-show="!editScene">
|
<div class="task-rules-table-box">
|
<el-table :data="tableRuleList" border style="width: 100%" :cell-style="cellStyle"
|
:header-cell-style="{ background: '#f8f8f8', color: '#222222' }">
|
<el-table-column label="序号" type="index" align="center"></el-table-column>
|
<el-table-column label="任务名称" prop="scene_name" align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="事件等级" align="center">
|
<template slot-scope="scope">
|
<span>{{ scope.row.alarm_level | alarmLevel }}</span>
|
</template>
|
</el-table-column>
|
<!-- <el-table-column
|
label="策略"
|
prop="group_text"
|
align="center"
|
min-width="350px"
|
>
|
<template slot-scope="scope">
|
<span v-html="scope.row.group_text"></span>
|
</template>
|
</el-table-column>workTimeId -->
|
<el-table-column label="时间段" prop="time_name" align="center">
|
<template slot-scope="scope">
|
<!-- {{(scope.row.workingTime || []).map(r => r.labelName).join(' / ') || ''}} -->
|
<span v-for="(tag, idx) in VideoManageData.TimeRules.filter(t => t.id === scope.row.workTimeId)"
|
:key="idx">
|
{{ tag.name }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="检测内容" prop="checkContent" align="center">
|
<template slot-scope="scope">
|
{{(scope.row.checkContent || []).map(r => r.fileName).join(' / ') || ''}}
|
</template>
|
</el-table-column>
|
<el-table-column label="预警规则" prop="warningRule" align="center">
|
<template slot-scope="scope">
|
{{(scope.row.warningRule || []).map(r => r.fileName).join(' / ') || ''}}
|
</template>
|
</el-table-column>
|
<el-table-column label="知识库" prop="knowledge" align="center">
|
<template slot-scope="scope">
|
{{(scope.row.knowledge || []).map(r => r.fileName).join(' / ') || ''}}
|
</template>
|
</el-table-column>
|
<el-table-column label="描述" prop="desc" align="center" min-width="120"></el-table-column>
|
<!-- <el-table-column label="状态" align="center" width="90">
|
<template slot-scope="scope">
|
<el-switch v-model="scope.row.defence_state" @change="updateDefence(scope.row)"></el-switch>
|
</template>
|
</el-table-column>-->
|
<!-- <el-table-column label="事件声音" align="center">
|
<template slot-scope="scope">
|
<span>{{ getSoundById(scope.row.voiceId) }}</span>
|
</template>
|
</el-table-column> -->
|
<el-table-column label="操作" fixed="right" align="center">
|
<template slot-scope="scope">
|
<el-tooltip content="编辑" :hide-after="700" placement="top" popper-class="atooltip">
|
<i class="iconfont iconbianji1 btn-icon" style="font-size: 28px" @click="handleEdit(scope.row)"></i>
|
</el-tooltip>
|
<el-tooltip content="删除" :hide-after="700" placement="top" popper-class="atooltipgroup_">
|
<i class="iconfont iconshanchu4 btn-icon" style="font-size: 28px; color: red"
|
@click="handleDelScene(scope.row)"></i>
|
</el-tooltip>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { saveCameraScene, deleteCameraScene, deleteCameraSceneTwo } from "@/api/scene";
|
import RuleEditor from "@/components/subComponents/RuleEditor";
|
import SceneEditor from "./scene/Editor";
|
import { getSoundList } from "@/api/event";
|
import { forEach } from "jszip";
|
|
export default {
|
name: "SceneRuleEditor",
|
components: {
|
SceneEditor,
|
},
|
props: {
|
seletedCameras: {
|
type: Array,
|
default: () => {
|
return [];
|
},
|
},
|
tableRuleList: {
|
type: Array,
|
default: () => {
|
return [];
|
},
|
},
|
onSaveScene: {
|
type: Function,
|
default: () => false,
|
},
|
linkRule: {
|
type: Boolean,
|
default: false,
|
},
|
},
|
filters: {
|
alarmLevel(level) {
|
switch (level) {
|
case 1:
|
return "一级";
|
case 2:
|
return "二级";
|
case 3:
|
return "三级";
|
case 4:
|
return "四级";
|
case 5:
|
return "五级";
|
}
|
},
|
},
|
watch: {
|
tableRuleList(n, o) {
|
this.editScene = false;
|
},
|
},
|
mounted() {
|
// window.addEventListener('resize', this.windowSizeChange)
|
this.getSounds();
|
this.eventAudio.addEventListener("ended", () => {
|
this.togglePlay = true;
|
});
|
},
|
data() {
|
return {
|
knowledgeProps: {
|
multiple: true, // 支持多选
|
value: 'id', // 指定选项值字段
|
label: 'title', // 指定选项标签字段
|
children: 'files' // 指定子选项字段(文件列表)
|
},
|
editScene: false,
|
sceneTemplates: [],
|
sceneForm: {
|
alarm_level: 1,
|
enable: true,
|
scene_name: "",
|
desc: "",
|
template_id: "",
|
time_rule_id: "",
|
voice: {},
|
voiceId: "",
|
},
|
templateSdks: [],
|
templateRules: "",
|
ruleList: [],
|
sceneNameStore: [],
|
eventAudio: new Audio(),
|
soundList: [],
|
togglePlay: true,
|
};
|
},
|
methods: {
|
getSoundById(id) {
|
if (id) {
|
let sound = this.soundList.find((item) => item.id == id);
|
return sound.name;
|
} else {
|
return "";
|
}
|
},
|
getSounds() {
|
let _this = this;
|
getSoundList()
|
.then((res) => {
|
if (res.success) {
|
//_this.soundList = [{ id: "", name: "空", path: "" }].concat(res.data.list)
|
_this.soundList = [{ id: "", name: "空", path: "" }].concat(
|
res.data
|
);
|
}
|
})
|
.catch((e) => console.log(e));
|
},
|
selSound(sound) {
|
this.soundPath = sound.path;
|
this.sceneForm.voiceId = sound.id;
|
this.togglePlay = true;
|
this.eventAudio.pause();
|
this.$forceUpdate();
|
// this.eventAudio.
|
},
|
togglePlayer() {
|
console.log(this.soundPath);
|
if (!this.soundPath) {
|
this.$notify({
|
type: "info",
|
message: "请先选择一个声音!",
|
});
|
return false;
|
}
|
this.eventAudio.src = "/httpImage/" + this.soundPath;
|
if (this.togglePlay) {
|
this.eventAudio.play();
|
this.togglePlay = false;
|
} else {
|
this.eventAudio.pause();
|
this.togglePlay = true;
|
}
|
// this.togglePlay = !this.togglePlay
|
},
|
bubbleSort(arr) {
|
for (var i = arr.length - 1; i > 0; i--) {
|
for (var j = 0; j < i; j++) {
|
if (arr[j] > arr[j + 1]) {
|
let temp = arr[j];
|
arr[j] = arr[j + 1];
|
arr[j + 1] = temp;
|
}
|
}
|
}
|
return arr;
|
},
|
getSceneName(sdk_name) {
|
this.sceneNameStore.push(sdk_name);
|
|
if (!this.sceneForm.scene_name.trim()) {
|
this.sceneForm.scene_name = sdk_name;
|
}
|
// }else if(this.sceneForm.scene_name == store[store.length-2]){
|
// //场景名称取的是上一次传过来的算法名称,则须更新为最新传来的算法名
|
// this.sceneForm.scene_name = sdk_name
|
// }
|
},
|
cleanForm() {
|
this.sceneForm = {
|
alarm_level: 1,
|
enable: true,
|
scene_name: "",
|
desc: "",
|
template_id: "",
|
time_rule_id: "",
|
voice: {},
|
voiceId: "",
|
};
|
this.$refs.sceneEditor.cleanRule();
|
this.$refs.sceneEditor.getSdkConnection();
|
},
|
handleCreate() {
|
if (this.linkRule && this.TreeDataPool.selectedNodes.length < 2) {
|
this.$notify({
|
type: "warning",
|
message: "请选择至少2个摄像机!",
|
});
|
return false;
|
} else if (
|
!this.linkRule &&
|
this.TreeDataPool.treeActiveName != "dataStack" &&
|
this.TreeDataPool.selectedNodes.length < 1
|
) {
|
this.$notify({
|
type: "warning",
|
message: `请选择1个摄像机!`,
|
});
|
return false;
|
} else if (
|
this.TreeDataPool.treeActiveName == "dataStack" &&
|
!this.DataStackPool.selectedDir.id
|
) {
|
this.$notify({
|
type: "warning",
|
message: `请先选择数据栈文件夹!`,
|
});
|
return false;
|
}
|
this.editScene = true;
|
this.cleanForm();
|
|
//初始化场景名称
|
var pattern = /^场景\s*\d+\s*$/;
|
var tempArr = [];
|
this.tableRuleList.forEach((scene) => {
|
if (pattern.test(scene.scene_name)) {
|
tempArr.push(Number(scene.scene_name.substring(2).trim()));
|
}
|
});
|
let latest =
|
tempArr.length > 0
|
? this.bubbleSort(tempArr)[tempArr.length - 1] + 1
|
: 1;
|
|
this.sceneForm.scene_name = "场景" + latest;
|
//初始化时间段
|
this.sceneForm.time_rule_id = this.VideoManageData.TimeRules[0].id;
|
},
|
handleEdit(scene) {
|
this.sceneForm = JSON.parse(JSON.stringify(scene));
|
// 修正知识库文件转换逻辑
|
if (scene.knowledge) {
|
const convertKnowledge = scene.knowledge.map(file => {
|
const library = this.VideoManageData.knowsList.find(lib =>
|
lib.files.some(f => f.id === file.id)
|
)
|
return library ? [library.id, file.id] : null
|
}).filter(item => item !== null) || []
|
this.sceneForm.knowsList = convertKnowledge
|
// console.info("know:" + JSON.stringify(convertKnowledge))
|
}
|
// this.originSceneInfo = JSON.parse(JSON.stringify(scene));
|
this.sceneForm.voice = this.soundList.find((o) => o.id === scene.voiceId);
|
|
this.editScene = true;
|
let selectedTpl = {};
|
this.sceneTemplates.forEach((t) => {
|
if (t.id == this.sceneForm.template_id) {
|
selectedTpl = t;
|
}
|
});
|
this.templateSdks = selectedTpl.sdks;
|
|
this.templateRules = JSON.stringify(scene.rules);
|
// this.$refs.sceneEditor.editHandle(this.templateRules);//算法相关
|
},
|
|
validateForm() {
|
if (!this.sceneForm.scene_name.trim()) {
|
this.$notify({
|
type: "warning",
|
message: "任务名不能为空",
|
});
|
return false;
|
} else if (!this.sceneForm.alarm_level) {
|
this.$notify({
|
type: "warning",
|
message: "事件等级不能为空",
|
});
|
return false;
|
} else if (!this.sceneForm.workTimeId) {
|
this.$notify({
|
type: "warning",
|
message: "时间段不能为空",
|
});
|
return false;
|
} else if (!this.sceneForm.checkContents) {
|
this.$notify({
|
type: "warning",
|
message: "检测内容不能为空",
|
});
|
return false;
|
} else if (!this.sceneForm.warningRules) {
|
this.$notify({
|
type: "warning",
|
message: "预警规则不能为空",
|
});
|
return false;
|
}
|
// else if (!this.sceneForm.knowsList) {
|
// this.$notify({
|
// type: "warning",
|
// message: "知识库不能为空",
|
// });
|
// return false;
|
// }
|
return true;
|
},
|
saveSceneRule() {
|
if (!this.validateForm()) {
|
return;
|
}
|
// let editorResp = this.$refs.sceneEditor.submitRule();
|
// if (!editorResp) {
|
// return;
|
// }
|
// this.sceneForm.rules = editorResp.rules;
|
// this.sceneForm.id = editorResp.id;
|
// this.sceneForm.group_text = editorResp.text;
|
// const workTimes = [this.sceneForm.workingTimes].map(id => {
|
// const timeOption = this.VideoManageData.TimeRules.find(opt => opt.id === id)
|
// return {
|
// labelId: id,
|
// labelName: timeOption ? timeOption.name : ''
|
// }
|
// })
|
let fileIds = []
|
if (this.sceneForm.knowsList) {
|
fileIds = this.sceneForm.knowsList.map(
|
path => {
|
// 提取最后一级的文件ID并转换为数字
|
const id = path[path.length - 1];
|
return Number(id); // 或者使用 parseInt(id) 或 +id
|
}
|
)
|
}
|
this.sceneForm.taskName = this.sceneForm.scene_name
|
this.sceneForm.eventLevel = this.sceneForm.alarm_level
|
this.sceneForm.checks = this.sceneForm.checkContents
|
this.sceneForm.rules = this.sceneForm.warningRules
|
// this.sceneForm.workTimes = workTimes
|
this.sceneForm.taskDescription = this.sceneForm.desc
|
this.sceneForm.knows = fileIds,
|
this.onSaveScene(this.sceneForm);
|
},
|
|
handleDelScene(groupRule) {
|
let _this = this;
|
this.$confirm("提示:删除后,该条任务将失效,是否删除?", {
|
center: true,
|
cancelButtonClass: "comfirm-class-cancle",
|
confirmButtonClass: "comfirm-class-sure",
|
})
|
.then(() => {
|
// console.info("groupRule:"+JSON.stringify(groupRule))
|
deleteCameraSceneTwo(
|
{
|
taskId: groupRule.taskId
|
}
|
).then((res) => {
|
this.$emit("delete-rule");
|
if (res && res.status === 200) {
|
// console.info("删除成功")
|
this.$notify({
|
type: "success",
|
message: "删除成功",
|
});
|
_this.$root.$children[0].$children[0].querySearchAsync("camera");
|
} else {
|
this.$notify({
|
type: "error",
|
message: "删除失败!",
|
});
|
}
|
});
|
})
|
.catch(() => { });
|
},
|
cellStyle(obj) {
|
if (obj.column.label == "策略" || obj.column.label == "事件声音") {
|
return "text-align:left;padding-left:8px;";
|
}
|
},
|
},
|
};
|
</script>
|
|
<style lang="scss">
|
.scene-edit-container {
|
.scene-title {
|
height: 30px;
|
text-align: left;
|
margin: 10px 0px;
|
}
|
|
.flex-form {
|
display: flex;
|
width: 80%;
|
padding-left: 25px;
|
|
.left,
|
.right {
|
width: 43.3%;
|
min-width: 550px;
|
|
.el-form-item {
|
margin-bottom: 16px;
|
}
|
|
.el-form-item__label {
|
text-align: left;
|
}
|
|
.el-form-item__content {
|
text-align: left;
|
|
.el-input,
|
.el-select {
|
width: 400px !important;
|
}
|
}
|
|
textarea {
|
height: 92px;
|
}
|
}
|
|
.right {
|
padding-top: 6px;
|
}
|
}
|
|
.edit-rule-table {
|
.task-rules-table-box {
|
width: 98%;
|
padding: 0px;
|
box-sizing: border-box;
|
}
|
|
.el-form-item {
|
width: calc(100% - 30px);
|
}
|
|
.el-input__inner {
|
border: 0px !important;
|
border-radius: 2px;
|
padding: 0 22px;
|
background-color: transparent;
|
}
|
|
.el-input__suffix {
|
right: 8px;
|
}
|
|
span {
|
cursor: pointer;
|
}
|
|
.cell {
|
padding-left: 0 !important;
|
|
i {
|
outline: none !important;
|
}
|
}
|
}
|
|
.el-table th.el-table__cell>.cell {
|
padding-right: 0;
|
}
|
}
|
</style>
|