src/pages/cameraAccess/components/SceneRule.vue
@@ -1,7 +1,7 @@
<template>
  <div class="scene-edit-container">
    <div class="scene-title">
      <b style="font-size: 14px; line-height: 18px">督查任务</b>
      <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>
@@ -9,8 +9,13 @@
    <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 v-if="sceneForm.iconUrl" :src="sceneForm.iconUrl" 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">
@@ -22,36 +27,47 @@
            </el-select>
          </el-form-item>
          <el-form-item label="时间段">
            <el-select v-model="sceneForm.workingTimes" placeholder="请选择" size="mini">
            <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-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> -->
        </div>
        <div class="right">
          <el-form-item label="任务描述">
            <el-input v-model="sceneForm.desc" type="textarea" size="mini"></el-input>
          <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.warningRules" placeholder="请选择" size="mini" multiple>
          <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-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-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
@@ -124,28 +140,31 @@
            <template slot-scope="scope">
              <span v-html="scope.row.group_text"></span>
            </template>
          </el-table-column> -->
          </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(' / ') || ''}}
              <!-- {{(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">
          <!-- <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">
          </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">
          <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>
@@ -178,11 +197,14 @@
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: {
@@ -236,6 +258,7 @@
  },
  data() {
    return {
      currentRule:null,// 初始无选中规则
      knowledgeProps: {
        multiple: true, // 支持多选
        value: 'id',    // 指定选项值字段
@@ -256,7 +279,6 @@
      },
      templateSdks: [],
      templateRules: "",
      ruleList: [],
      sceneNameStore: [],
      eventAudio: new Audio(),
      soundList: [],
@@ -264,6 +286,19 @@
    };
  },
  methods: {
    handleRuleSelect(rule) {
      // console.log('选中规则:', rule);
      this.sceneForm.warningRules = [rule.ruleId]
      this.sceneForm.ruleName = null
      // 执行预警判断逻辑
    },
    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);
@@ -346,8 +381,8 @@
        voice: {},
        voiceId: "",
      };
      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) {
@@ -422,6 +457,11 @@
      this.templateSdks = selectedTpl.sdks;
      this.templateRules = JSON.stringify(scene.rules);
      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);//算法相关 
    },
@@ -438,31 +478,34 @@
          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.workingTimes) {
      }
      // 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;
      }
      //  else if (!this.sceneForm.knowsList) {
      //   this.$notify({
      //     type: "warning",
      //     message: "知识库不能为空",
      //   });
      //   return false;
      // }
      return true;
    },
    saveSceneRule() {
@@ -476,27 +519,33 @@
      // 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 fileIds = this.sceneForm.knowsList.map(
        path => {
          // 提取最后一级的文件ID并转换为数字
          const id = path[path.length - 1];
          return Number(id); // 或者使用 parseInt(id) 或 +id
        }
      )
      // 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,
      // console.info(this.sceneForm)
        this.onSaveScene(this.sceneForm);
    },
@@ -542,6 +591,34 @@
</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;
@@ -565,6 +642,8 @@
      .el-form-item__label {
        text-align: left;
        // min-width: 82px;
        font-size: 13px;
      }
      .el-form-item__content {
@@ -577,7 +656,8 @@
      }
      textarea {
        height: 92px;
        height: 72px;
        width: 400px;
      }
    }