Forráskód Böngészése

实时标绘 分类增删查改

Hwf 5 hónapja
szülő
commit
37b235b07f

+ 47 - 0
src/api/globalMap/onlinePlotting.ts

@@ -150,3 +150,50 @@ export const updateGroupVisible = (groupId, visible) => {
     }
   });
 };
+
+// 模板分类树
+export const getTemplateTree = (params) => {
+  return request({
+    url: '/api/pattern/classification/templateTree',
+    method: 'get',
+    params: params
+  });
+};
+// 数据详情查询
+export const getClassificationInfo = (id) => {
+  return request({
+    url: '/api/pattern/classification/info/' + id,
+    method: 'get'
+  });
+};
+// 数据详情查询
+export const updateClassificationInfo = (id, data) => {
+  return request({
+    url: '/api/pattern/classification/update/' + id,
+    method: 'put',
+    data: data
+  });
+};
+// 数据创建
+export const getClassificationCreate = (data) => {
+  return request({
+    url: '/api/pattern/classification/create',
+    method: 'post',
+    data: data
+  });
+};
+// 分类删除
+export const deleteClassificationCreate = (id) => {
+  return request({
+    url: '/api/pattern/classification/delete/' + id,
+    method: 'delete'
+  });
+};
+// 分类显隐
+export const changeVisibleClassification = (data) => {
+  return request({
+    url: '/api/pattern/classification/changeVisible',
+    method: 'put',
+    data: data
+  });
+};

BIN
src/assets/images/delete.png


+ 9 - 0
src/components/FileUpload/index.vue

@@ -344,4 +344,13 @@ const handleDownload = (file: any) => {
 .ele-upload-list__item-content-action .el-link {
   margin-right: 10px;
 }
+.delete-icon {
+  width: 32px;
+  height: 32px;
+  background: url('@/assets/images/delete.png') no-repeat;
+  background-size: 100% 100%;
+  cursor: pointer;
+  margin-left: 7.5px;
+  display: inline-block;
+}
 </style>

+ 7 - 7
src/store/modules/permission.ts

@@ -25,15 +25,15 @@ export const usePermissionStore = defineStore('permission', () => {
     leftMenu: [
       { label: '全域地图', path: '/globalMap', path2: '/globalMap2', type: '1', checked: false },
       { label: '一图作战', path: '/', path2: '/index2', type: '1', checked: false },
-      { label: '总体态势', path: 'http://19.155.220.218/#/considerable-web/overallSituation?type=full', path2: 'http://19.155.220.218/#/considerable-web/overallSituation?type=large', type: '2', checked: false },
-      { label: '非煤矿山', path: 'http://19.155.220.218/#/considerable-web/noCoalMine?type=full', path2: 'http://19.155.220.218/#/considerable-web/noCoalMine?type=large', type: '2', checked: false },
-      { label: '粉尘防爆', path: 'http://19.155.220.218/#/considerable-web/dustIgnitionPproof?type=full', path2: 'http://19.155.220.218/#/considerable-web/dustIgnitionPproof?type=large', type: '2', checked: false }
+      { label: '总体态势', path: 'http://19.155.220.218/#/considerable-web/overallSituation?type=full', path2: 'http://19.155.220.218/#/considerable-web/overallSituation?type=full', type: '2', checked: false },
+      { label: '非煤矿山', path: 'http://19.155.220.218/#/considerable-web/noCoalMine?type=full', path2: 'http://19.155.220.218/#/considerable-web/noCoalMine?type=full', type: '2', checked: false },
+      { label: '粉尘防爆', path: 'http://19.155.220.218/#/considerable-web/dustIgnitionPproof?type=full', path2: 'http://19.155.220.218/#/considerable-web/dustIgnitionPproof?type=full', type: '2', checked: false }
     ],
     rightMenu: [
-      { label: '地质灾害', path: 'http://19.155.220.218/#/considerable-web/geologicalDisaster?type=full', path2: 'http://19.155.220.218/#/considerable-web/geologicalDisaster?type=large', type: '2', checked: false },
-      { label: '森林防火', path: 'http://19.155.220.218/#/considerable-web/forestFireproof?type=full', path2: 'http://19.155.220.218/#/considerable-web/forestFireproof?type=large', type: '2', checked: false },
-      { label: '三防', path: 'http://19.155.220.218/#/considerable-web/threeProofings?type=full', path2: 'http://19.155.220.218/#/considerable-web/threeProofings?type=large', type: '2', checked: false },
-      { label: '危化品', path: 'http://19.155.220.218/#/considerable-web/hazardousChemicals?type=full', path2: 'http://19.155.220.218/#/considerable-web/hazardousChemicals?type=large', type: '2', checked: false }
+      { label: '地质灾害', path: 'http://19.155.220.218/#/considerable-web/geologicalDisaster?type=full', path2: 'http://19.155.220.218/#/considerable-web/geologicalDisaster?type=full', type: '2', checked: false },
+      { label: '森林防火', path: 'http://19.155.220.218/#/considerable-web/forestFireproof?type=full', path2: 'http://19.155.220.218/#/considerable-web/forestFireproof?type=full', type: '2', checked: false },
+      { label: '三防', path: 'http://19.155.220.218/#/considerable-web/threeProofings?type=full', path2: 'http://19.155.220.218/#/considerable-web/threeProofings?type=full', type: '2', checked: false },
+      { label: '危化品', path: 'http://19.155.220.218/#/considerable-web/hazardousChemicals?type=full', path2: 'http://19.155.220.218/#/considerable-web/hazardousChemicals?type=full', type: '2', checked: false }
     ]
   });
   const activeMenu = ref('left');

+ 18 - 0
src/types/components.d.ts

@@ -21,6 +21,7 @@ declare module 'vue' {
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElCard: typeof import('element-plus/es')['ElCard']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
@@ -37,22 +38,34 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
+    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElPopover: typeof import('element-plus/es')['ElPopover']
+    ElRadio: typeof import('element-plus/es')['ElRadio']
+    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
     ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
     ElSlider: typeof import('element-plus/es')['ElSlider']
+    ElStep: typeof import('element-plus/es')['ElStep']
+    ElSteps: typeof import('element-plus/es')['ElSteps']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
+    ElTable: typeof import('element-plus/es')['ElTable']
+    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTabPane: typeof import('element-plus/es')['ElTabPane']
+    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElText: typeof import('element-plus/es')['ElText']
     ElTimeline: typeof import('element-plus/es')['ElTimeline']
     ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
+    ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
+    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     FooterSection: typeof import('./../components/FooterSection/index.vue')['default']
@@ -63,6 +76,7 @@ declare module 'vue' {
     HikvisionPlayer: typeof import('./../components/HKVideo/hikvision-player.vue')['default']
     HKVideo: typeof import('./../components/HKVideo/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
+    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']
@@ -97,6 +111,10 @@ declare module 'vue' {
     VideoContainer2: typeof import('./../components/HKVideo/video-container2.vue')['default']
     VideoTagEdit: typeof import('./../components/VideoTagEdit/index.vue')['default']
     YMap: typeof import('./../components/Map/YMap.vue')['default']
+    YMapold: typeof import('./../components/Map/YMapold.vue')['default']
     YztMap: typeof import('./../components/Map/YztMap/index.vue')['default']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

+ 12 - 0
src/types/onlinePlotting.ts

@@ -0,0 +1,12 @@
+interface ClassParams {
+  template_id?: string;
+  name: string;
+  value: string;
+  image: string;
+  icon: string;
+  order_num: string;
+  visible: string;
+  size: number[];
+  fileList?: any[];
+  visible?: string;
+}

+ 5 - 8
src/utils/olMap/olMap.ts

@@ -286,26 +286,23 @@ export class olMap {
   /**
    *
    * @param {Geojon} chaozhou 根据geojson对象创建Featrue对象
-   * @param {String} layerName 图层名称
    * @returns VectorLayer
    */
-
-  createVecByJson(json, layerName = '') {
+  createVecByJson(json, options) {
     const format = new GeoJSON();
     const fs = format.readFeatures(json);
-    this.removeMask2();
-    this.maskLayer = new VectorLayer({
+    const converLayer = new VectorLayer({
       source: new VectorSource(),
       style: new Style({
         fill: new Fill({
-          color: 'rgba(16, 36, 59, 0.65)'
+          color: options.fillColor ? options.fillColor : 'rgba(16, 36, 59, 0.65)'
         }),
         stroke: new Stroke({
-          color: 'rgba(38, 138, 185, 1)',
+          color: options.strokeColor ? options.strokeColor : 'rgba(38, 138, 185, 1)',
           width: 2
         })
       }),
-      zIndex: 99
+      zIndex: options.zIndex ? options.zIndex : 99
     });
     this.map.addLayer(this.maskLayer);
     const extent = [-180, -90, 180, 90];

+ 119 - 0
src/views/globalMap/RightMenu/OnlinePlotting/EditClassDialog.vue

@@ -0,0 +1,119 @@
+<template>
+  <Dialog custom-show :title="!id ? '新增分类' : '修改分类'" @close="handleCancel" @confirm="submitForm(classFormRef)">
+    <el-form ref="classFormRef" :model="form" :rules="rules">
+      <el-form-item label="分类名称:" label-width="200px" prop="name">
+        <el-input v-model="form.name" class="custom-input2" placeholder="请输入分类名称" />
+      </el-form-item>
+      <el-form-item label="分类值:" label-width="200px" prop="value">
+        <el-input v-model="form.value" class="custom-input2" placeholder="请输入分类值" />
+      </el-form-item>
+      <el-form-item label="图标:" label-width="200px" prop="fileList">
+        <FileUpload v-model="form.fileList" :file-type="['jpg', 'jpeg', 'png']" :limit="1" :file-size="20" :is-show-tip="false" class="upload-box" />
+      </el-form-item>
+      <el-form-item label="图标宽度:" label-width="200px" prop="size.0">
+        <el-input v-model="form.size[0]" class="custom-input2" placeholder="请输入图标宽度" />
+      </el-form-item>
+      <el-form-item label="图标高度:" label-width="200px" prop="size.1">
+        <el-input v-model="form.size[1]" class="custom-input2" placeholder="请输入图标高度" />
+      </el-form-item>
+      <el-form-item label="排序:" label-width="200px" prop="order_num">
+        <el-input v-model="form.order_num" class="custom-input2" placeholder="请输入排序" />
+      </el-form-item>
+      <el-form-item label="状态:" label-width="200px" prop="visible">
+        <el-select
+          v-model="form.visible"
+          placeholder="请选择"
+          class="custom-select"
+          size="large"
+          popper-class="custom-select-popper"
+          :teleported="false"
+          clearable
+        >
+          <el-option v-for="item in show_status" :key="item.value" :label="item.label" :value="item.value"></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+  </Dialog>
+</template>
+
+<script lang="ts" setup name="EditClassDialog">
+import { getClassificationCreate, getClassificationInfo, updateClassificationInfo } from '@/api/globalMap/onlinePlotting';
+import { FormInstance } from 'element-plus';
+import { deepClone } from '@/utils';
+import { toRefs } from 'vue';
+
+const props = defineProps({
+  modelValue: String,
+  id: String,
+  templateId: String
+});
+const emits = defineEmits(['update:modelValue', 'updateData']);
+const proxy = getCurrentInstance()?.proxy;
+const { show_status } = toRefs<any>(proxy?.useDict('show_status'));
+let classFormRef = ref();
+const form = ref<ClassParams>({
+  name: '',
+  value: '',
+  image: '',
+  icon: '',
+  order_num: '',
+  visible: '1',
+  fileList: [],
+  size: []
+});
+const rules = ref({
+  name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
+  value: [{ required: true, message: '分类值不能为空', trigger: 'blur' }],
+  image: [{ required: true, message: '图标不能为空', trigger: 'blur' }]
+});
+
+// 取消
+const handleCancel = () => {
+  emits('update:modelValue');
+};
+//提交
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  await formEl.validate((valid) => {
+    if (valid) {
+      const data = deepClone(form.value);
+      data.image = data.fileList[0].url;
+      data.icon = data.fileList[0].name;
+      data.template_id = props.templateId;
+      delete data.fileList;
+      if (!data.order_num) {
+        delete data.order_num;
+      }
+      if (!data.visible) {
+        delete data.visible;
+      }
+      if (!!props.id) {
+        updateClassificationInfo(props.id, data).then(() => {
+          emits('updateData');
+          emits('update:modelValue');
+        });
+      } else {
+        getClassificationCreate(data).then(() => {
+          emits('updateData');
+          emits('update:modelValue');
+        });
+      }
+    }
+  });
+};
+onMounted(() => {
+  if (props.id) {
+    getClassificationInfo(props.id).then((res) => {
+      res.data.fileList = [
+        {
+          name: res.data.icon,
+          url: res.data.image
+        }
+      ];
+      form.value = res.data;
+    });
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 72 - 193
src/views/globalMap/RightMenu/OnlinePlotting/index.vue

@@ -39,7 +39,7 @@
           </div>
         </div>
         <div v-show="showSetting" class="box-item">
-          <div class="btn" @click="showSetting = false">
+          <div class="btn" @click="handleQuitSetting">
             <div class="revoke-icon"></div>
             退出设置
           </div>
@@ -79,7 +79,7 @@
               <el-color-picker v-model="mouseToolState.color" popper-class="custom-color-picker" show-alpha />
             </div>
           </div>
-          <div class="tab-list">
+          <div v-if="menu[menuActive1] && menu[menuActive1].children && menu[menuActive1].children[menuActive2]" class="tab-list">
             <div
               v-for="(item, index) in menu[menuActive1].children[menuActive2].children"
               :key="index"
@@ -88,7 +88,7 @@
               @click="clickTab3(item, index)"
             >
               <div :class="menuActive3 === index ? 'checked2' : 'checked1'"></div>
-              <img :src="item.image" class="icon" />
+              <img :src="getImageUrl(item.image)" class="icon" />
               {{ item.name }}
               <div v-if="!!showSetting" class="setting-btn" @click="handleShowSetting(item)" />
               <div v-if="item.showSetting" class="setting-menu">
@@ -98,7 +98,7 @@
                 </div>
                 <div class="menu-item" @click="handleMenuItemHide(item)">
                   <i class="icon-eye" />
-                  <span>{{ item.hide ? '隐藏' : '显示' }}</span>
+                  <span>{{ item.visible === '0' ? '隐藏' : '显示' }}</span>
                 </div>
                 <div class="menu-item" @click="handleMenuItemDelete(item)">
                   <i class="icon-delete" />
@@ -106,6 +106,9 @@
                 </div>
               </div>
             </div>
+            <div v-if="showSetting" class="tab" @click="handleShowAddClass">
+              <el-icon color="#7495b4" :size="80"><Plus /></el-icon>
+            </div>
           </div>
         </div>
       </div>
@@ -166,6 +169,14 @@
       </div>
     </div>
   </div>
+  <!--添加修改分类弹窗-->
+  <EditClassDialog
+    v-if="showAddDialog"
+    :id="selectEditId"
+    v-model="showAddDialog"
+    :template-id="selectTemplateId"
+    @update-data="getTemplateTreeData"
+  />
   <!--添加文字-->
   <TextEdit v-model="showTextEdit" @add-text="addText" />
   <!--绘制提示信息-->
@@ -186,9 +197,19 @@
 import { nanoid } from 'nanoid';
 import { deepClone } from '@/utils';
 import { useHistory } from '@/hooks/useHistory';
-import { closeCollaboration, createCollaboration, deletePatternById, getPatternInfo, getPatternList } from '@/api/globalMap/onlinePlotting';
-import TextEdit from '@/views/globalMap/RightMenu/OnlinePlotting/TextEdit.vue';
-import EditDialog from '@/views/globalMap/RightMenu/OnlinePlotting/EditDialog.vue';
+import {
+  changeVisibleClassification,
+  closeCollaboration,
+  createCollaboration,
+  deleteClassificationCreate,
+  deletePatternById,
+  getPatternInfo,
+  getPatternList,
+  getTemplateTree
+} from '@/api/globalMap/onlinePlotting';
+import EditClassDialog from './EditClassDialog.vue';
+import TextEdit from './TextEdit.vue';
+import EditDialog from './EditDialog.vue';
 import { Search } from '@element-plus/icons-vue';
 import html2canvas from 'html2canvas';
 import LayerDetail from './LayerDetail.vue';
@@ -201,8 +222,8 @@ const getMap = inject('getMap');
 const containerScale = inject('containerScale');
 const { currentState, commit, undo, history, future } = useHistory();
 const emits = defineEmits(['getCollaborationData']);
-const getImageUrl = (name) => {
-  return new URL(`../../../../assets/images/map/rightMenu/onlinePlotting/icon/${name}.png`, import.meta.url).href;
+const getImageUrl = (name: string) => {
+  return import.meta.env.VITE_APP_BASE_API + import.meta.env.VITE_APP_BASE_DOWNLOAD_API + name;
 };
 let drawing = ref(false);
 const mouseToolState = ref<MouseTool>({
@@ -216,181 +237,7 @@ const menuActive3 = ref<string | number>('');
 const menu = ref([
   {
     name: '标绘工具',
-    children: [
-      {
-        name: '基本工具',
-        value: 'basicTools',
-        children: [
-          // {
-          //   name: '直箭头',
-          //   value: 'straightArrow',
-          //   image: getImageUrl('straightArrow')
-          // },
-          {
-            name: '矩形',
-            value: 'rectangle',
-            image: getImageUrl('rectangle')
-          },
-          {
-            name: '任意面',
-            value: 'polygon',
-            image: getImageUrl('polygon')
-          },
-          {
-            name: '任意线',
-            value: 'anyLine',
-            image: getImageUrl('anyLine')
-          },
-          {
-            name: '圆',
-            value: 'circle',
-            image: getImageUrl('circle')
-          },
-          {
-            name: '直线',
-            value: 'straightLine',
-            image: getImageUrl('straightLine')
-          },
-          {
-            name: '文字',
-            value: 'text',
-            image: getImageUrl('text')
-          },
-          {
-            name: '面积',
-            value: 'measureArea',
-            image: getImageUrl('measureArea')
-          }
-        ]
-      },
-      {
-        name: '火点',
-        value: 'firePoint',
-        children: [
-          { name: '起火点', value: 'marker', image: getImageUrl('firePoint'), icon: 'firePoint', size: [48, 32] },
-          { name: '烟点', value: 'marker', image: getImageUrl('smokePoint'), icon: 'smokePoint', size: [48, 32] },
-          { name: '已灭火点', value: 'marker', image: getImageUrl('extinguishedPoint'), icon: 'extinguishedPoint', size: [48, 32] }
-        ]
-      },
-      {
-        name: '火线',
-        value: 'firewire',
-        children: [
-          { name: '火线', value: 'marker', image: getImageUrl('firewire'), icon: 'firewire', size: [48, 32] },
-          { name: '受控火线', value: 'marker', image: getImageUrl('controlledfireline'), icon: 'controlledfireline', size: [48, 32] },
-          { name: '已灭火线', value: 'marker', image: getImageUrl('extinguishedline'), icon: 'extinguishedline', size: [48, 32] },
-          { name: '强火线', value: 'marker', image: getImageUrl('StrongFrontline'), icon: 'StrongFrontline', size: [48, 32] },
-          { name: '中火线', value: 'marker', image: getImageUrl('ZhongxianLine'), icon: 'ZhongxianLine', size: [48, 32] },
-          { name: '弱火线', value: 'marker', image: getImageUrl('WeakFrontline'), icon: 'WeakFrontline', size: [48, 32] }
-        ]
-      },
-      {
-        name: '火场',
-        value: 'fireGround',
-        children: [
-          { name: '火场', value: 'marker', image: getImageUrl('fireground'), icon: 'fireground', size: [48, 32] },
-          {
-            name: '受控火场',
-            value: 'marker',
-            image: getImageUrl('controlledfireground'),
-            icon: 'controlledfireground',
-            size: [48, 32]
-          },
-          {
-            name: '已灭火场',
-            value: 'marker',
-            image: getImageUrl('extinguishedfireground'),
-            icon: 'extinguishedfireground',
-            size: [48, 32]
-          }
-        ]
-      },
-      {
-        name: '箭头',
-        value: 'arrow',
-        children: [
-          { name: '曲箭头', value: 'marker', image: getImageUrl('curvedarrow'), icon: 'curvedarrow', size: [48, 32] },
-          { name: '直箭头', value: 'marker', image: getImageUrl('straightarrow1'), icon: 'straightarrow1', size: [48, 32] },
-          { name: '细箭头', value: 'marker', image: getImageUrl('thinarrow'), icon: 'thinarrow', size: [48, 32] }
-        ]
-      },
-      // {
-      //   name: '导航',
-      //   value: 'navigation',
-      //   children: [
-      //     { name: '导航', value: 'marker', image: getImageUrl('navigation'), icon: 'navigation', size: [166, 88] }
-      //   ]
-      // },
-      {
-        name: '扑救队伍',
-        value: 'firefightingTeam',
-        children: [
-          { name: '指挥中心', value: 'marker', image: getImageUrl('commandcentre'), icon: 'commandcentre', size: [48, 32] },
-          { name: '分指中心', value: 'marker', image: getImageUrl('dividingcenter'), icon: 'dividingcenter', size: [48, 32] },
-          { name: '集结地', value: 'marker', image: getImageUrl('rendezvous'), icon: 'rendezvous', size: [48, 32] },
-          { name: '军队', value: 'marker', image: getImageUrl('army'), icon: 'army', size: [48, 32] },
-          { name: '武警', value: 'marker', image: getImageUrl('armedpolice'), icon: 'armedpolice', size: [48, 32] },
-          { name: '森林警察', value: 'marker', image: getImageUrl('forestpoliceman'), icon: 'forestpoliceman', size: [48, 32] },
-          { name: '扑火队伍', value: 'marker', image: getImageUrl('firefightingteam'), icon: 'firefightingteam', size: [48, 32] }
-          // { name: '扑火队伍路线', value: 'marker', image: getImageUrl('Firefightingteamroute'), icon: 'Firefightingteamroute', size: [48, 32] }
-        ]
-      },
-      {
-        name: '飞机车辆',
-        value: 'aircraftVehicles',
-        children: [
-          { name: '固定翼', value: 'marker', image: getImageUrl('fixedwing'), icon: 'fixedwing', size: [48, 32] },
-          { name: '直升机', value: 'marker', image: getImageUrl('helicopter'), icon: 'helicopter', size: [48, 32] },
-          { name: '无人机', value: 'marker', image: getImageUrl('UAV'), icon: 'UAV', size: [48, 32] },
-          { name: '指挥车', value: 'marker', image: getImageUrl('commandvehicle'), icon: 'commandvehicle', size: [48, 32] },
-          {
-            name: '飞机航线设置',
-            value: 'marker',
-            image: getImageUrl('aircraftroutesetting'),
-            icon: 'aircraftroutesetting',
-            size: [48, 32]
-          },
-          {
-            name: '直升机航线设置',
-            value: 'marker',
-            image: getImageUrl('helicopterroutesetting'),
-            icon: 'helicopterroutesetting',
-            size: [48, 32]
-          }
-        ]
-      },
-      {
-        name: '基础设置',
-        value: 'basicSetting',
-        children: [
-          { name: '航站', value: 'marker', image: getImageUrl('terminal'), icon: 'terminal', size: [48, 32] },
-          {
-            name: '起降点',
-            value: 'marker',
-            image: getImageUrl('takeoffandlandingpoint'),
-            icon: 'takeoffandlandingpoint',
-            size: [48, 32]
-          },
-          { name: '取水点', value: 'marker', image: getImageUrl('waterpoint'), icon: 'waterpoint', size: [48, 32] },
-          { name: '瞭望塔', value: 'marker', image: getImageUrl('watchtower'), icon: 'watchtower', size: [48, 32] },
-          { name: '物资库', value: 'marker', image: getImageUrl('materialwarehouse'), icon: 'materialwarehouse', size: [48, 32] }
-        ]
-      }
-      // {
-      //   name: '其他',
-      //   value: 'other',
-      //   children: [
-      //     { name: '危险区域', value: 'marker', image: getImageUrl('dangerousarea'), icon: 'dangerousarea', size: [166, 88] },
-      //     { name: '隔离带开采', value: 'marker', image: getImageUrl('Isolationzonemining'), icon: 'Isolationzonemining', size: [166, 88] },
-      //     { name: '应急庇护场所', value: 'marker', image: getImageUrl('emergencyshelter'), icon: 'emergencyshelter', size: [166, 88] },
-      //     { name: '风力风向', value: 'marker', image: getImageUrl('windspeedanddirection'), icon: 'windspeedanddirection', size: [166, 88] },
-      //     { name: '测距', value: 'marker', image: getImageUrl('ranging'), icon: 'ranging', size: [166, 88] },
-      //     { name: '大风', value: 'marker', image: getImageUrl('strongwind'), icon: 'strongwind', size: [166, 88] },
-      //     { name: '人工降雨', value: 'marker', image: getImageUrl('artificialrainfall'), icon: 'artificialrainfall', size: [166, 88] },
-      //     { name: '台风', value: 'marker', image: getImageUrl('typhoon'), icon: 'typhoon', size: [166, 88] }
-      //   ]
-      // }
-    ]
+    children: []
   },
   {
     name: '历史预案',
@@ -446,6 +293,39 @@ const tipTitle = computed(() => {
   return res;
 });
 
+// 获取模板分类树
+const getTemplateTreeData = () => {
+  getTemplateTree({ visible: showSetting.value ? '' : '1'}).then((res) => {
+    menu.value[0].children = res.data;
+  });
+};
+let showAddDialog = ref(false);
+let selectTemplateId = ref('');
+let selectEditId = ref('');
+// 显示现在分类弹窗
+const handleShowAddClass = () => {
+  selectTemplateId.value = menu.value[menuActive1.value].children[menuActive2.value].template_id;
+  selectEditId.value = '';
+  showAddDialog.value = true;
+};
+const handleShowSwitch = (item) => {
+  selectTemplateId.value = menu.value[menuActive1.value].children[menuActive2.value].template_id;
+  item.showSetting = false;
+  selectEditId.value = item.classification_id;
+  showAddDialog.value = true;
+};
+const handleMenuItemHide = (item) => {
+  item.showSetting = false;
+  changeVisibleClassification({ classification_id: item.classification_id, visible: item.visible === '0' ? '1' : '0' }).then(() => {
+    getTemplateTreeData();
+  });
+};
+const handleMenuItemDelete = (item) => {
+  item.showSetting = false;
+  deleteClassificationCreate(item.classification_id).then(() => {
+    getTemplateTreeData();
+  });
+};
 // 点击一级菜单
 const clickTab = (value: number) => {
   menuActive1.value = value;
@@ -810,6 +690,7 @@ const handleQuery = () => {
   queryParams.page = 1;
   getList();
 };
+// 获取预案列表
 const getList = () => {
   // if (menuActive1.value === 1 && menu.value[menuActive1.value].name == '历史预案') {
   getPatternList(queryParams).then((res) => {
@@ -935,6 +816,11 @@ const handleShowDialog = () => {
 let showSetting = ref(false);
 const handleOpenSetting = () => {
   showSetting.value = true;
+  getTemplateTreeData();
+};
+const handleQuitSetting = () => {
+  showSetting.value = false;
+  getTemplateTreeData();
 };
 const handleShowSetting = (item, index) => {
   menu.value[0].children.forEach((menu2) => {
@@ -943,15 +829,7 @@ const handleShowSetting = (item, index) => {
     });
   });
 };
-const handleShowSwitch = (item) => {
-  item.showSetting = false;
-};
-const handleMenuItemHide = (item) => {
-  item.showSetting = false;
-};
-const handleMenuItemDelete = (item) => {
-  item.showSetting = false;
-};
+
 const handleSendData = (data) => {
   const { type, content } = data;
   if (type === 'update') {
@@ -1004,6 +882,7 @@ let handleShowLayer = () => {
   showLayer.value = true;
 };
 onMounted(() => {
+  getTemplateTreeData();
   getList();
 });
 </script>