| | |
| | | <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 |
| | | > |
| | | <b style="font-size: 14px; line-height: 18px">AI任务</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 label="图标"> |
| | | <!-- 图片预览 --> |
| | | <div class="icon-preview-container"> |
| | | <el-image :src="sceneForm.iconUrl?sceneForm.iconUrl + '?t=' + timestamp:'/opt/smart/icon/task_icon.png'" fit="cover" /> |
| | | <!-- <el-image v-else src="@/assets/img/容器@1x.png" fit="cover" /> --> |
| | | <!-- <img style="width: 60px;" v-else src="@/assets/img/容器@1x.png" /> --> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item label="事件等级"> |
| | | <el-select |
| | | v-model="sceneForm.alarm_level" |
| | | placeholder="请选择" |
| | | size="mini" |
| | | style="width: 250px" |
| | | > |
| | | <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-select> |
| | | </el-form-item> |
| | | <el-form-item label="时间段"> |
| | | <el-select |
| | | v-model="sceneForm.workingTimes" |
| | | placeholder="请选择" |
| | | size="mini" |
| | | > |
| | | <el-option |
| | | v-for="item in VideoManageData.TimeRules" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | ></el-option> |
| | | <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> |
| | | <!-- <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> --> |
| | | |
| | | <!-- 预警规则 --> |
| | | <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.knowledgeOptions" :props="knowledgeProps" clearable |
| | | filterable placeholder="请选择" class="knowledge-cascader" :show-all-levels="false"></el-cascader> |
| | | </el-form-item> --> |
| | | |
| | | </div> |
| | | <div class="right"> |
| | | |
| | | <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-input |
| | | v-model="sceneForm.desc" |
| | | type="textarea" |
| | | size="mini" |
| | | ></el-input> |
| | | <!-- <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-select v-model="sceneForm.warningRules" placeholder="请选择" size="mini" filterable> |
| | | <el-option v-for="item in VideoManageData.ruleOptions" :key="item.ruleId" :label="item.fileName" |
| | | :value="item.ruleId"></el-option> |
| | | </el-select> --> |
| | | <ruleSelect :initial-rules="VideoManageData.ruleOptions" :selected-rule="currentRule" |
| | | @rule-selected="handleRuleSelect" @rule-created="handleRuleCreate" /> |
| | | </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-input v-model="sceneForm.desc" type="textarea" size="mini"></el-input> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="事件声音"> |
| | | <el-select |
| | |
| | | :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-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 :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 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="time_name" |
| | | align="center" |
| | | > |
| | | <el-table-column label="任务描述" prop="warningRule" align="center"> |
| | | <template slot-scope="scope"> |
| | | {{(scope.row.workingTime || []).map(r => r.labelName).join(' / ') || ''}} |
| | | </template> |
| | | {{(scope.row.warningRule || []).map(r => r.fileName).join(' / ') || ''}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="检测内容" |
| | | prop="checkContent" |
| | | align="center" |
| | | > |
| | | <el-table-column label="关联知识库" prop="knowledge" align="center"> |
| | | <template slot-scope="scope"> |
| | | {{(scope.row.checkContent || []).map(r => r.fileName).join(' / ') || ''}} |
| | | </template> |
| | | {{(scope.row.knowledge || []).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="备注" 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> |
| | |
| | | </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 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 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> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { saveCameraScene, deleteCameraScene,deleteCameraSceneTwo } from "@/api/scene"; |
| | | import { saveCameraScene, deleteCameraScene, deleteCameraSceneTwo } from "@/api/scene"; |
| | | import RuleEditor from "@/components/subComponents/RuleEditor"; |
| | | import SceneEditor from "./scene/Editor"; |
| | | import { getSoundList } from "@/api/event"; |
| | | import ruleSelect from "../components/ruleSelect/ruleSelect.vue"; |
| | | import { forEach } from "jszip"; |
| | | |
| | | export default { |
| | | name: "SceneRuleEditor", |
| | | components: { |
| | | SceneEditor, |
| | | ruleSelect, |
| | | }, |
| | | props: { |
| | | seletedCameras: { |
| | |
| | | this.editScene = false; |
| | | }, |
| | | }, |
| | | created() { |
| | | this.userInfo = sessionStorage.getItem("userInfo") && JSON.parse(sessionStorage.getItem("userInfo")) |
| | | }, |
| | | computed: { |
| | | isGb28182() { |
| | | return this.TreeDataPool.selectedNode.cameraType === 1 |
| | | } |
| | | }, |
| | | mounted() { |
| | | // window.addEventListener('resize', this.windowSizeChange) |
| | | this.getSounds(); |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | timestamp: Date.now(), // 时间戳用于强制刷新图片 |
| | | userInfo: {}, |
| | | currentRule: null,// 初始无选中规则 |
| | | knowledgeProps: { |
| | | multiple: true, // 支持多选 |
| | | value: 'id', // 指定选项值字段 |
| | | label: 'title', // 指定选项标签字段 |
| | | children: 'files' // 指定子选项字段(文件列表) |
| | | }, |
| | | editScene: false, |
| | | sceneTemplates: [], |
| | | sceneForm: { |
| | |
| | | }, |
| | | templateSdks: [], |
| | | templateRules: "", |
| | | ruleList: [], |
| | | sceneNameStore: [], |
| | | eventAudio: new Audio(), |
| | | soundList: [], |
| | |
| | | }; |
| | | }, |
| | | methods: { |
| | | handleRuleSelect(rule) { |
| | | // console.log('选中规则:', rule); |
| | | this.sceneForm.warningRules = [rule.ruleId] |
| | | this.sceneForm.ruleName = null |
| | | this.sceneForm.iconUrl = rule.iconUrl |
| | | // 更新时间戳强制刷新图片 |
| | | this.timestamp = Date.now(); |
| | | console.info(this.sceneForm.iconUrl) |
| | | // 执行预警判断逻辑 |
| | | }, |
| | | handleRuleCreate(newRule) { |
| | | // console.log('创建新规则:', newRule); |
| | | this.sceneForm.ruleName = newRule.fileName |
| | | this.sceneForm.warningRules = [] |
| | | this.sceneForm.rules = [] |
| | | // 将新规则保存到后端 |
| | | }, |
| | | getSoundById(id) { |
| | | if (id) { |
| | | let sound = this.soundList.find((item) => item.id == id); |
| | |
| | | time_rule_id: "", |
| | | voice: {}, |
| | | voiceId: "", |
| | | iconUrl:"" |
| | | }; |
| | | this.$refs.sceneEditor.cleanRule(); |
| | | this.$refs.sceneEditor.getSdkConnection(); |
| | | // this.$refs.sceneEditor.cleanRule(); |
| | | // this.$refs.sceneEditor.getSdkConnection(); |
| | | }, |
| | | handleCreate() { |
| | | if (this.linkRule && this.TreeDataPool.selectedNodes.length < 2) { |
| | |
| | | }, |
| | | 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.templateSdks = selectedTpl.sdks; |
| | | |
| | | this.templateRules = JSON.stringify(scene.rules); |
| | | this.$refs.sceneEditor.editHandle(this.templateRules); |
| | | this.sceneForm.iconUrl = this.VideoManageData.ruleOptions.find(rue => |
| | | rue.ruleId === scene.warningRule[0].ruleId |
| | | ).iconUrl |
| | | this.currentRule = this.sceneForm.warningRule[0] |
| | | console.info(this.currentRule) |
| | | // this.$refs.sceneEditor.editHandle(this.templateRules);//算法相关 |
| | | }, |
| | | |
| | | validateForm() { |
| | |
| | | message: "事件等级不能为空", |
| | | }); |
| | | return false; |
| | | } else if (!this.sceneForm.workingTimes) { |
| | | } 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() { |
| | | console.log(this.Camera) |
| | | if (!this.validateForm()) { |
| | | 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 : '' |
| | | // 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.checks = this.sceneForm.checkContents |
| | | this.sceneForm.checks = [this.VideoManageData.checkOptions[0].checkId] |
| | | this.sceneForm.rules = this.sceneForm.warningRules |
| | | this.sceneForm.workTimes = workTimes |
| | | // this.sceneForm.workTimes = workTimes |
| | | this.sceneForm.taskDescription = this.sceneForm.desc |
| | | this.sceneForm.knows = fileIds, |
| | | this.sceneForm.createUser = this.userInfo.id |
| | | this.sceneForm.type = this.isGb28182?1:0 |
| | | // console.info(this.sceneForm) |
| | | this.onSaveScene(this.sceneForm); |
| | | }, |
| | | |
| | |
| | | // console.info("groupRule:"+JSON.stringify(groupRule)) |
| | | deleteCameraSceneTwo( |
| | | { |
| | | taskId: groupRule.taskId |
| | | } |
| | | taskId: groupRule.taskId |
| | | } |
| | | ).then((res) => { |
| | | this.$emit("delete-rule"); |
| | | if (res && res.status === 200) { |
| | |
| | | } |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { }); |
| | | }, |
| | | cellStyle(obj) { |
| | | if (obj.column.label == "策略" || obj.column.label == "事件声音") { |
| | |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .icon-preview-container { |
| | | margin-right: 240px; |
| | | width: 60px; |
| | | height: 60px; |
| | | border: 1px dashed #d9d9d9; |
| | | border-radius: 6px; |
| | | cursor: pointer; |
| | | position: relative; |
| | | overflow: hidden; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | |
| | | .el-image { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .el-icon-plus { |
| | | font-size: 28px; |
| | | color: #8c939d; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #409EFF; |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | // min-width: 82px; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .el-form-item__content { |
| | | text-align: left; |
| | | |
| | | .el-input, |
| | | .el-select { |
| | | width: 400px !important; |
| | | } |
| | | } |
| | | |
| | | textarea { |
| | | height: 92px; |
| | | height: 72px; |
| | | width: 400px; |
| | | } |
| | | } |
| | | |
| | | .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; |
| | |
| | | .el-input__suffix { |
| | | right: 8px; |
| | | } |
| | | |
| | | span { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .cell { |
| | | padding-left: 0 !important; |
| | | |
| | | i { |
| | | outline: none !important; |
| | | } |
| | | } |
| | | } |
| | | .el-table th.el-table__cell > .cell { |
| | | |
| | | .el-table th.el-table__cell>.cell { |
| | | padding-right: 0; |
| | | } |
| | | } |