From 46566d05cb156d40323078133191595d2a2f11c4 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期四, 10 十月 2024 17:27:04 +0800
Subject: [PATCH] 巡查任务管理界面开发中

---
 src/components/list-item/ItemScene.vue            |   19 +
 src/components/search-option/FYInfoSearch.vue     |  126 ++++++++++
 src/styles/element/base.scss                      |    2 
 src/views/fysp/task/components/CompMonitorObj.vue |   91 +++++++
 src/components/list-item/ItemMonitorObj.vue       |   52 ++++
 src/api/fysp/taskApi.js                           |    7 
 src/components.d.ts                               |    6 
 src/constants/menu.js                             |    5 
 src/views/fysp/task/MonitorObjEdit.vue            |  175 ++++++++++++++
 src/router/index.js                               |   13 +
 src/views/fysp/task/TaskManage.vue                |  182 +++++++++++++++
 11 files changed, 674 insertions(+), 4 deletions(-)

diff --git a/src/api/fysp/taskApi.js b/src/api/fysp/taskApi.js
index fbdb714..401d008 100644
--- a/src/api/fysp/taskApi.js
+++ b/src/api/fysp/taskApi.js
@@ -9,6 +9,13 @@
   },
 
   /**
+   * 鑾峰彇鎬讳换鍔$殑鐩戠鍦烘櫙鐗堟湰淇℃伅
+   */
+  fetchMonitorObjectVersion(taskId) {
+    return $fysp.get(`monitorobjectversion/task/${taskId}`).then((res) => res.data);
+  },
+
+  /**
    * 鏌ヨ鎬讳换鍔�
    * @param {Object} param
    * @returns
diff --git a/src/components.d.ts b/src/components.d.ts
index 578dfa8..34bf963 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -9,8 +9,10 @@
   export interface GlobalComponents {
     BaseContentLayout: typeof import('./components/core/BaseContentLayout.vue')['default']
     BasePanelLayout: typeof import('./components/core/BasePanelLayout.vue')['default']
+    CompInfoSearch: typeof import('./components/search-option/CompInfoSearch.vue')['default']
     CompQuickSet: typeof import('./components/search-option/CompQuickSet.vue')['default']
     Content: typeof import('./components/core/Content.vue')['default']
+    copy: typeof import('./components/list-item/ItemScene copy.vue')['default']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElBacktop: typeof import('element-plus/es')['ElBacktop']
@@ -18,6 +20,7 @@
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
     ElCard: typeof import('element-plus/es')['ElCard']
     ElCascader: typeof import('element-plus/es')['ElCascader']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
@@ -65,12 +68,14 @@
     ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     Footer: typeof import('./components/core/Footer.vue')['default']
     FormCol: typeof import('./components/layout/FormCol.vue')['default']
     FYBgTaskCard: typeof import('./components/bg-task/FYBgTaskCard.vue')['default']
     FYBgTaskDialog: typeof import('./components/bg-task/FYBgTaskDialog.vue')['default']
     FYBgTaskItem: typeof import('./components/bg-task/FYBgTaskItem.vue')['default']
     FYForm: typeof import('./components/form/FYForm.vue')['default']
+    FYInfoSearch: typeof import('./components/search-option/FYInfoSearch.vue')['default']
     FYList: typeof import('./components/table/FYList.vue')['default']
     FYOptionLocation: typeof import('./components/search-option/FYOptionLocation.vue')['default']
     FYOptionOnlineStatus: typeof import('./components/search-option/FYOptionOnlineStatus.vue')['default']
@@ -83,6 +88,7 @@
     FYSearchBar: typeof import('./components/search-option/FYSearchBar.vue')['default']
     FYTable: typeof import('./components/table/FYTable.vue')['default']
     Header: typeof import('./components/core/Header.vue')['default']
+    ItemMonitorObj: typeof import('./components/list-item/ItemMonitorObj.vue')['default']
     ItemScene: typeof import('./components/list-item/ItemScene.vue')['default']
     ItemUser: typeof import('./components/list-item/ItemUser.vue')['default']
     MenuItems: typeof import('./components/core/MenuItems.vue')['default']
diff --git a/src/components/list-item/ItemMonitorObj.vue b/src/components/list-item/ItemMonitorObj.vue
new file mode 100644
index 0000000..70c32a2
--- /dev/null
+++ b/src/components/list-item/ItemMonitorObj.vue
@@ -0,0 +1,52 @@
+<template>
+  <!-- <el-card shadow="hover"> -->
+  <div class="wrapper">
+    <div>
+      <el-text>{{ item.displayid }}銆�</el-text>
+      <el-text truncated class="w-250px">{{ item.sensename }}</el-text>
+    </div>
+    <!-- <div>
+      <el-text>鍦板潃锛歿{ item.location }}</el-text>
+    </div> -->
+    <el-row justify="space-between" style="margin-top: 4px">
+      <el-space>
+        <el-tag type="info" effect="plain" size="small">
+          {{ item.sceneType }}
+        </el-tag>
+        <el-tag type="info" effect="plain" size="small">
+          璁″垝鐩戠娆℃暟锛歿{ item.monitornum }}
+        </el-tag>
+      </el-space>
+      <slot :item="item"></slot>
+      <!-- <el-button size="small" type="success" @click="add">娣诲姞</el-button> -->
+    </el-row>
+  </div>
+  <!-- </el-card> -->
+</template>
+<script setup>
+/**
+ * 鐩戠瀵硅薄
+ */
+
+
+const props = defineProps({
+  item: {
+    type: Object,
+    default: () => {}
+  }
+});
+
+const emit = defineEmits(['add']);
+
+function add() {
+  emit('add', props.item);
+}
+</script>
+<style scoped>
+.wrapper {
+  width: 300px;
+  border: 1px solid var(--el-border-color);
+  border-radius: var(--el-border-radius-base);
+  padding: 4px 8px;
+}
+</style>
diff --git a/src/components/list-item/ItemScene.vue b/src/components/list-item/ItemScene.vue
index e6759d1..e333f30 100644
--- a/src/components/list-item/ItemScene.vue
+++ b/src/components/list-item/ItemScene.vue
@@ -10,14 +10,19 @@
     </div> -->
     <el-row justify="space-between" style="margin-top: 4px">
       <el-space>
-        <el-tag type="primary" effect="plain" size="small">
+        <el-tag type="info" effect="plain" size="small">
           {{ item.districtname }}
         </el-tag>
-        <el-tag type="primary" effect="plain" size="small">
+        <el-tag type="info" effect="plain" size="small">
           {{ item.type }}
         </el-tag>
+        <el-tag :type="item.extension1 == '0' ? 'info' : 'success'" size="small">
+          {{ onlineFormat(item.extension1) }}
+        </el-tag>
       </el-space>
-      <el-button size="small" type="success" @click="add">娣诲姞</el-button>
+      <slot>
+        <el-button size="small" type="success" @click="add">娣诲姞</el-button>
+      </slot>
     </el-row>
   </div>
   <!-- </el-card> -->
@@ -35,6 +40,14 @@
 function add() {
   emit('add', props.item);
 }
+
+function onlineFormat(s) {
+  if (s == '0') {
+    return '涓嬬嚎';
+  } else {
+    return '涓婄嚎';
+  }
+}
 </script>
 <style scoped>
 .wrapper {
diff --git a/src/components/search-option/FYInfoSearch.vue b/src/components/search-option/FYInfoSearch.vue
new file mode 100644
index 0000000..bfa47d6
--- /dev/null
+++ b/src/components/search-option/FYInfoSearch.vue
@@ -0,0 +1,126 @@
+<template>
+  <FYSearchBar @search="search" :loading="loading">
+    <template #options>
+      <FYOptionText v-bind="$attrs" v-model:value="searchText" width="200px"></FYOptionText>
+    </template>
+  </FYSearchBar>
+  <div>
+    <el-scrollbar v-if="data.length > 0" :height="scrollHeight" class="item-box" :loading="loading">
+      <el-space direction="vertical" alignment="start" fill style="width: 100%">
+        <div v-for="(item, index) in data" :key="index">
+          <slot :row="item"></slot>
+        </div>
+      </el-space>
+    </el-scrollbar>
+    <el-empty v-else description="鏆傛棤璁板綍" />
+  </div>
+  <el-pagination
+    v-if="pageShow && data.length > 0"
+    size="small"
+    ref="paginationRef"
+    class="el-pagination"
+    v-model:current-page="currentPage"
+    v-model:page-size="pageSize"
+    :page-sizes="pageSizes"
+    :background="true"
+    layout="total, sizes, prev, pager, next"
+    :total="total"
+  />
+</template>
+
+<script>
+import { usePagination } from '@/composables/pagination';
+
+/**
+ * 甯︽湁鍒嗛〉閫昏緫鐨勪俊鎭绱㈠垪琛�
+ */
+export default {
+  setup() {
+    // 鍒嗛〉閫昏緫
+    const { currentPage, pageSize, addPageEvent } = usePagination();
+    return { currentPage, pageSize, addPageEvent };
+  },
+  props: {
+    // label: {
+    //   type: String,
+    //   default: '妫�绱㈤」'
+    // },
+    // placeholder: {
+    //   type: String,
+    //   default: '杈撳叆鍏抽敭瀛楁绱�'
+    // },
+    // 鏁版嵁鍒楄〃
+    data: {
+      type: Array,
+      default: () => {
+        return [];
+      }
+    },
+    // 鏌ヨ鍑芥暟
+    onSearch: {
+      type: Function,
+      default: () => {}
+    },
+    // 鏄惁鏄剧ず鍒嗛〉
+    pageShow: {
+      type: Boolean,
+      default: true
+    },
+    // 姣忛〉鍙�夋暟閲�
+    pageSizes: {
+      type: Array,
+      default: () => {
+        return [10, 20, 50, 100];
+      }
+    },
+    // 鎬绘暟鎹噺
+    total: {
+      type: Number,
+      default: 0
+    },
+    scrollHeight: {
+      type: String,
+      default: '38vh'
+    }
+  },
+  data() {
+    return {
+      searchText: '',
+      loading: false
+    };
+  },
+  watch: {},
+  methods: {
+    async search() {
+      this.loading = true;
+      const param = {
+        text: this.searchText,
+        page: this.currentPage,
+        pageSize: this.pageSize
+      };
+      await this.onSearch(param);
+      this.loading = false;
+    }
+  },
+  mounted() {
+    this.addPageEvent(this.search);
+  }
+};
+</script>
+<style scoped>
+.select-box {
+  border: 1px solid var(--el-border-color);
+  border-radius: var(--el-border-radius-base);
+  padding: 0 8px;
+}
+.item-box {
+  /* border: 1px solid var(--el-border-color);
+  border-radius: var(--el-border-radius-base);
+  margin-top: 20px; */
+}
+.el-pagination {
+  /* background-color: var(--el-color-white); */
+  border-top: 1px solid rgba(0, 0, 0, 0.096);
+  /* background-color: aliceblue; */
+}
+</style>
diff --git a/src/constants/menu.js b/src/constants/menu.js
index e1a1c52..6633452 100644
--- a/src/constants/menu.js
+++ b/src/constants/menu.js
@@ -15,6 +15,11 @@
   //   ]
   // },
   {
+    path: '/fysp/task/manage',
+    icon: 'CircleCheck',
+    name: '鐩戠浠诲姟'
+  },
+  {
     path: '/fysp/procheck',
     icon: 'CircleCheck',
     name: '闂瀹℃牳'
diff --git a/src/router/index.js b/src/router/index.js
index f08c0ce..747a2cd 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -60,6 +60,19 @@
     component: () => import('@/views/fysp/scenereport/StorageReport.vue')
   },
   {
+    //鐩戠浠诲姟
+    name: 'taskmanage',
+    path: '/fysp/task/manage',
+    component: () => import('@/views/fysp/task/TaskManage.vue'),
+    meta: { keepAlive: false }
+  },
+  {
+    //鐩戠浠诲姟鍦烘櫙缂栬緫
+    name: 'monitorObjEdit',
+    path: '/fysp/task/edit',
+    component: () => import('@/views/fysp/task/MonitorObjEdit.vue')
+  },
+  {
     //闂瀹℃牳
     name: 'procheck',
     path: '/fysp/procheck',
diff --git a/src/styles/element/base.scss b/src/styles/element/base.scss
index 4347524..6a2dabe 100644
--- a/src/styles/element/base.scss
+++ b/src/styles/element/base.scss
@@ -71,7 +71,7 @@
   default: var(--el-component-size-default),
   large: var(--el-component-size-large)
 );
-$ws: (20px, 40px, 60px, 100px, 150px, 300px);
+$ws: (20px, 40px, 60px, 100px, 150px, 250px, 300px);
 @each $name, $value in $csize {
   .w-#{$name} {
     width: #{$value};
diff --git a/src/views/fysp/task/MonitorObjEdit.vue b/src/views/fysp/task/MonitorObjEdit.vue
new file mode 100644
index 0000000..1cd37c6
--- /dev/null
+++ b/src/views/fysp/task/MonitorObjEdit.vue
@@ -0,0 +1,175 @@
+<template>
+  <el-page-header @back="$router.back()" class="page-header">
+    <template #content>
+      <span> 鎬讳换鍔$紪杈� </span>
+    </template>
+  </el-page-header>
+  <el-divider />
+  <el-row gutter="20">
+    <el-col :span="16">
+      <div>
+        <el-text>宸查�夊満鏅�</el-text>
+      </div>
+      <el-divider />
+      <CompMonitorObj :data="curMonitorObjList" @tab-change="changeSceneType" :showDelete="true">
+        <!-- <template #default="{ item }">
+          <el-button size="small" type="danger" @click="deleteMov(item)">绉婚櫎</el-button>
+        </template> -->
+      </CompMonitorObj>
+    </el-col>
+    <el-col :span="8">
+      <div>
+        <el-text>鍙�夊満鏅�</el-text>
+      </div>
+      <el-divider />
+      <FYInfoSearch
+        label=""
+        placeholder="璇疯緭鍏ュ満鏅悕绉板叧閿瓧"
+        :data="showSceneList"
+        :on-search="searchScene"
+        :total="total"
+        scroll-height="70vh"
+        :page-show="false"
+      >
+        <template #default="{ row, click }">
+          <ItemScene :item="row">
+            <el-button-group>
+              <el-button size="small" type="primary" @click="insertDialog = true">鎻掑叆</el-button>
+              <el-button size="small" type="primary" @click="addDialog = true">鏂板</el-button>
+            </el-button-group>
+          </ItemScene>
+        </template>
+      </FYInfoSearch>
+    </el-col>
+  </el-row>
+
+  <el-dialog v-model="insertDialog" title="鎻掑叆鍦烘櫙鑷崇┖浣欑紪鍙�" width="500">
+    <div>浠ヤ笅涓哄彲閫夌殑绌轰綑缂栧彿</div>
+    <el-radio-group v-model="selectedIndex" size="default">
+      <el-radio-button v-for="item in valibleIndex" :key="item" :label="item" :value="item" />
+    </el-radio-group>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="insertDialog = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="insertDialog = false"> 纭 </el-button>
+      </div>
+    </template>
+  </el-dialog>
+  <el-dialog v-model="addDialog" title="鏂板鍦烘櫙缂栧彿椤哄欢" width="500">
+    <div>椤哄欢缂栧彿涓�:{{ lastIndex }}</div>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="addDialog = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="addDialog = false"> 纭 </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+import CompMonitorObj from './components/CompMonitorObj.vue';
+import svUserApi from '@/api/fysp/userApi';
+import sceneApi from '@/api/fysp/sceneApi';
+
+export default {
+  components: { CompMonitorObj },
+  props: {},
+  data() {
+    return {
+      // 鐩戠鍦烘櫙
+      curMonitorObjList: [],
+      // 琛屾斂鍖哄垝
+      area: {},
+      // 鎵�鏈夊満鏅�
+      sceneList: [],
+      total: 0,
+
+      // 褰撳墠绛涢�夌殑鍦烘櫙绫诲瀷
+      curSceneType: undefined,
+
+      insertDialog: false,
+      selectedIndex: undefined,
+      addDialog: false
+    };
+  },
+  computed: {
+    // 褰撳墠鍦烘櫙绫诲瀷涓嬬殑灞曠ず鍦烘櫙
+    showSceneList() {
+      return this.sceneList.filter((v) => {
+        const index = this.curMonitorObjList.findIndex((o) => {
+          return o.sguid == v.guid;
+        });
+        return index == -1 && v.type == this.curSceneType;
+      });
+    },
+    showMonitorObjList() {
+      return this.curMonitorObjList.filter((v) => {
+        return v.sceneType == this.curSceneType;
+      });
+    },
+    // 褰撳墠鍦烘櫙绫诲瀷涓嬬殑鍙彃鍏ョ紪鍙�
+    valibleIndex() {
+      // 鍘熷垪琛ㄥ凡缁忔寜鐓х紪鍙烽『搴忔帓鍒�
+      let index = 1;
+      const indexList = [];
+      this.showMonitorObjList.forEach((l) => {
+        while (l.displayid > index) {
+          indexList.push(index);
+          index++;
+        }
+        index++;
+      });
+      return indexList;
+    },
+    lastIndex() {
+      const len = this.showMonitorObjList.length;
+      if (len > 0) {
+        return this.showMonitorObjList[len - 1].displayid + 1;
+      } else {
+        return undefined;
+      }
+    }
+  },
+  methods: {
+    // 鏌ヨ
+    searchScene({ text, page, pageSize }) {
+      this.area.sceneName = text;
+      return sceneApi.searchScene(this.area, 1, 10000).then((res) => {
+        if (res.success) {
+          // 鏌ヨ缁撴灉
+          this.sceneList = res.data;
+          // 鎬绘暟鎹噺
+          this.total = res.head.totalCount;
+        }
+      });
+    },
+    changeSceneType(tabName) {
+      this.curSceneType = tabName;
+    },
+    deleteMov(item) {
+    },
+    insertMov() {},
+    addMov() {}
+  },
+  mounted() {
+    // 鐩戠鍦烘櫙淇℃伅
+    this.curMonitorObjList = JSON.parse(decodeURIComponent(this.$route.query.data));
+    // 鏍规嵁鎬讳换鍔¤幏鍙栬鏀垮尯鍒掍俊鎭�
+    const task = JSON.parse(decodeURIComponent(this.$route.query.task));
+    this.area = {
+      provincecode: task.provincecode,
+      provincename: task.provincename,
+      citycode: task.citycode,
+      cityname: task.cityname,
+      districtcode: task.districtcode,
+      districtname: task.districtname,
+      towncode: task.towncode,
+      townname: task.townname,
+      online: true
+    };
+    this.searchScene({ text: '' });
+  }
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/fysp/task/TaskManage.vue b/src/views/fysp/task/TaskManage.vue
new file mode 100644
index 0000000..839a8b9
--- /dev/null
+++ b/src/views/fysp/task/TaskManage.vue
@@ -0,0 +1,182 @@
+<template>
+  <BaseContentLayout>
+    <template #header>
+      <FYSearchBar @search="search">
+        <template #options>
+          <!-- 鍖哄幙 -->
+          <FYOptionLocation
+            :allOption="true"
+            :level="3"
+            :checkStrictly="false"
+            v-model:value="formSearch.locations"
+          ></FYOptionLocation>
+        </template>
+        <!-- <template #buttons>
+          <slot name="buttons"></slot>
+        </template> -->
+      </FYSearchBar>
+    </template>
+    <template #aside>
+      <SideList :items="tasks" :loading="sideLoading" @item-click="chooseTask"></SideList>
+    </template>
+    <template #main>
+      <ToolBar
+        :title="curTask.title"
+        :descriptions="taskStatus"
+        :buttons="buttons"
+        :loading="mainLoading"
+      ></ToolBar>
+      <el-scrollbar
+        v-if="curMonitorObjList.length > 0"
+        class="el-scrollbar"
+        v-loading="mainLoading"
+      >
+        <div><el-text>鐩戠璁″垝</el-text></div>
+        <el-divider></el-divider>
+        <el-button type="primary" size="small" @click="editTask">鍦烘櫙璋冩暣</el-button>
+        <div><el-text>鐩戠鍦烘櫙</el-text></div>
+        <CompMonitorObj :data="curMonitorObjList"></CompMonitorObj>
+        <!-- <div><el-text>鐩戠鍦烘櫙</el-text></div>
+        <div>
+          <el-space wrap>
+            <ItemMonitorObj
+              v-for="item in curMonitorObjList"
+              :key="item.movid"
+              :item="item"
+            ></ItemMonitorObj>
+          </el-space>
+        </div> -->
+      </el-scrollbar>
+      <el-empty v-else description="鏆傛棤璁板綍" v-loading="mainLoading" />
+    </template>
+  </BaseContentLayout>
+</template>
+
+<script>
+import taskApi from '@/api/fysp/taskApi';
+import CompMonitorObj from './components/CompMonitorObj.vue';
+export default {
+  components: { CompMonitorObj },
+  data() {
+    return {
+      formSearch: {
+        _locations: {},
+        searchText: '',
+        _scenetype: {},
+        online: {}
+      },
+      // 宸︿晶鑿滃崟鏍忓姞杞界姸鎬�
+      sideLoading: false,
+      // 鍙充晶鍐呭鏍忓姞杞界姸鎬�
+      mainLoading: false,
+      // 浠诲姟鍒楄〃
+      tasks: [],
+      // 褰撳墠浠诲姟鐨勭洃绠″璞�
+      curMonitorObjList: [],
+      //褰撳墠閫変腑鐨勪换鍔�
+      curTask: {},
+      //鎿嶄綔鎸夐挳
+      buttons: [
+        {
+          name: '璁″垝璋冩暣',
+          color: 'success'
+        },
+        {
+          name: '鍦烘櫙璋冩暣',
+          color: 'warning'
+        }
+      ]
+    };
+  },
+  computed: {
+    // 鎬讳换鍔$姸鎬佺粺璁�
+    taskStatus() {
+      return [
+        { name: '鍦烘櫙鏁�', value: 100 },
+        { name: '鏈贰鏌�', value: 0 },
+        { name: '宸插贰鏌�', value: 0 }
+      ];
+    }
+  },
+  methods: {
+    search(formSearch) {
+      this.sideLoading = true;
+      this.mainLoading = true;
+      this.curMonitorObjList = [];
+      this.curTask = {};
+      taskApi.getTopTask().then((res) => {
+        const list = res.map((r) => {
+          const t = this.getTaskType(r);
+          return {
+            type: t,
+            title: r.name,
+            categoly: this.$fm.formatYM(r.starttime),
+            data: r
+          };
+        });
+        this.tasks = list;
+        if (list.length == 0) {
+          this.sideLoading = false;
+          this.mainLoading = false;
+        }
+      });
+    },
+    //鑾峰彇浠诲姟鐨勫畬鎴愭儏鍐�
+    getTaskType(s) {
+      let type = 0;
+      switch (s.runingstatus) {
+        case '鏈墽琛�':
+          type = 0;
+          break;
+        case '姝e湪鎵ц':
+          type = 1;
+          break;
+        case '宸茬粨鏉�':
+          type = 2;
+          break;
+        default:
+          type = 0;
+          break;
+      }
+      return type;
+    },
+    chooseTask(task) {
+      this.sideLoading = false;
+      this.mainLoading = true;
+      taskApi
+        .fetchMonitorObjectVersion(task.data.tguid)
+        .then((res) => {
+          this.curMonitorObjList = res;
+          this.curTask = task;
+        })
+        .finally(() => {
+          this.mainLoading = false;
+        });
+    },
+    editTask() {
+      this.$router.push({
+        name: 'monitorObjEdit',
+        query: {
+          data: encodeURIComponent(JSON.stringify(this.curMonitorObjList)),
+          task: encodeURIComponent(JSON.stringify(this.curTask.data))
+        }
+      });
+    }
+  },
+  mounted() {
+    this.search();
+  }
+};
+</script>
+
+<style scoped>
+.select-box {
+  /* border: 1px solid var(--el-border-color);
+  border-radius: var(--el-border-radius-base);
+  padding: 0 8px; */
+}
+
+.el-scrollbar {
+  height: calc((100vh - 60px * 2 - 20px * 2 - var(--height-toolbar)));
+}
+</style>
diff --git a/src/views/fysp/task/components/CompMonitorObj.vue b/src/views/fysp/task/components/CompMonitorObj.vue
new file mode 100644
index 0000000..804274d
--- /dev/null
+++ b/src/views/fysp/task/components/CompMonitorObj.vue
@@ -0,0 +1,91 @@
+<template>
+  <el-tabs v-model="activeName" type="border-card" @tab-change="tabChange">
+    <el-tab-pane
+      v-for="item in tabDataList"
+      :key="item.title"
+      :label="item.title"
+      :name="item.title"
+    >
+      <!-- <div> -->
+      <el-space wrap>
+        <ItemMonitorObj v-for="obj in item.children" :key="obj.movid" :item="obj">
+          <template #default="{ item }">
+            <!-- <slot :item="item"></slot> -->
+            <el-button v-if="showDelete" size="small" type="danger" @click="deleteMov(item)"
+              >绉婚櫎</el-button
+            >
+          </template>
+        </ItemMonitorObj>
+      </el-space>
+      <!-- </div> -->
+    </el-tab-pane>
+  </el-tabs>
+</template>
+
+<script>
+const defaultTabName = '鍏ㄩ儴';
+export default {
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    // 鏄惁娣诲姞榛樿鐨勫叏閮ㄩ�夐」
+    allOption: Boolean,
+    showDelete: Boolean
+  },
+  emits: ['tabChange'],
+  data() {
+    return {
+      activeName: defaultTabName
+    };
+  },
+  computed: {
+    tabDataList() {
+      const itemMap = new Map();
+      this.data.forEach((t) => {
+        itemMap.has(t.sceneType) ? itemMap.get(t.sceneType).push(t) : itemMap.set(t.sceneType, [t]);
+      });
+      const list = [];
+      if (this.allOption) {
+        list.push({
+          title: defaultTabName,
+          children: this.data
+        });
+      }
+      for (const [key, value] of itemMap) {
+        list.push({
+          title: key,
+          children: value
+        });
+      }
+      return list;
+    }
+  },
+  watch: {
+    tabDataList: {
+      handler(nV, oV) {
+        if (nV != oV && nV.length > 0) {
+          this.activeName = nV[0].title;
+          this.tabChange(this.activeName);
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    tabChange(tabName) {
+      this.$emit('tabChange', tabName);
+    },
+    deleteMov(item) {
+      const tab = this.tabDataList.find((v) => {
+        return v.title == this.activeName;
+      });
+      const i = tab.children.indexOf(item);
+      tab.children.splice(i, 1);
+    }
+  }
+};
+</script>
+
+<style scoped></style>

--
Gitblit v1.9.3