Browse Source

Merge remote-tracking branch 'origin/dev' into dev

zhangyihao 5 months ago
parent
commit
d2ba639788

+ 10 - 0
src/api/emergencyCommandMap/communication.ts

@@ -0,0 +1,10 @@
+import request from '@/utils/request';
+
+// 获取融合通信链接
+export function getStartMiniParan(data) {
+  return request({
+    url: '/api/videoResource/avcon/get_start_mini_param',
+    method: 'post',
+    data: data
+  });
+}

+ 48 - 2
src/api/globalMap/onlinePlotting.ts

@@ -32,7 +32,7 @@ export const updatePatternInfo = (data) => {
   });
 };
 
-// 预案
+// 预案新
 export const createPattern = (data) => {
   return request({
     url: '/api/pattern/create',
@@ -49,7 +49,6 @@ export const createCollaboration = (data) => {
     data: data
   });
 };
-
 // 开启协同
 export const startCollaboration = (data) => {
   return request({
@@ -151,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/map/rightMenu/onlinePlotting/switch1.png


BIN
src/assets/images/map/rightMenu/onlinePlotting/switch2.png


+ 3 - 2
src/components/Map/company-map.vue

@@ -44,7 +44,6 @@
 </template>
 
 <script>
-
 import AMapLoader from '@amap/amap-jsapi-loader'
 
 export default {
@@ -179,6 +178,9 @@ export default {
         longitude: position[0],
         latitude: position[1]
       }
+      window._AMapSecurityConfig = {
+        securityJsCode: '4868bc1b8fac7d9e54e7279ed556879a'
+      };
       const AMap = await AMapLoader.load({
         key: '9c5041381e5e824f9ee324d8f7a40150',     // 申请好的Web端开发者Key,首次调用 load 时必填
         version: '2.0',      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
@@ -227,7 +229,6 @@ export default {
           this.$emit("confirm", { lnglat: lnglat, address: result.regeocode.formattedAddress });
         }
       })
-
     },
     setMarks(lnglat) {//添加标记
       if (this.marker) this.map.remove(this.marker);

+ 1 - 1
src/components/Map/index.vue

@@ -516,7 +516,7 @@ defineExpose({
     text-align: left !important;
     padding-left: 20px;
     color: #eaf3fc;
-    font-size: vw(32);
+    font-size: 12px;
     font-family: 'SourceHanSansCN';
   }
   :deep(.amap-scale-edgeleft),

+ 10 - 4
src/types/components.d.ts

@@ -22,12 +22,11 @@ declare module 'vue' {
     DistributionMap: typeof import('./../components/Map/YztMap/DistributionMap.vue')['default']
     DrawMap: typeof import('./../components/Map/YztMap/DrawMap.vue')['default']
     Editor: typeof import('./../components/Editor/index.vue')['default']
-    ElAnchor: typeof import('element-plus/es')['ElAnchor']
-    ElAnchorLink: typeof import('element-plus/es')['ElAnchorLink']
     ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
     ElBadge: typeof import('element-plus/es')['ElBadge']
     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']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
@@ -42,7 +41,9 @@ declare module 'vue' {
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
+    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
+    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
@@ -51,14 +52,19 @@ declare module 'vue' {
     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']
     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']
+    ElTag: typeof import('element-plus/es')['ElTag']
     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']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']

+ 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 - 7
src/utils/olMap/olMap.ts

@@ -285,25 +285,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];

+ 5 - 8
src/views/comprehensiveGuarantee/MaterialReserveManagement/MaterialInformationDetails.vue

@@ -81,7 +81,9 @@
             </el-col>
             <el-col :span="12">
               <el-form-item label="分类名称:" prop="category_name">
-                <el-input v-model="form.category_name" disabled class="custom-disabled" />
+                <el-select v-model="form.category_name" disabled class="custom-disabled">
+                  <el-option v-for="(item, index) in material_type" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="12">
@@ -92,7 +94,7 @@
             <el-col :span="12">
               <el-form-item label="物资类型:" prop="material_type_id">
                 <el-select v-model="form.material_type_id" disabled class="custom-disabled">
-                  <el-option v-for="(item, index) in materialTypeList" :key="index" :label="item.material_category_name" :value="item.id" />
+                  <el-option v-for="(item, index) in material_type" :key="index" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
@@ -251,7 +253,7 @@ const props = defineProps({
   id: String
 });
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { disaster_type, material_source } = toRefs<any>(proxy?.useDict('disaster_type', 'material_source'));
+const { disaster_type, material_source, material_classification, material_type } = toRefs<any>(proxy?.useDict('disaster_type', 'material_source', 'material_classification', 'material_type'));
 const baseUrl = import.meta.env.VITE_APP_BASE_API + import.meta.env.VITE_APP_BASE_DOWNLOAD_API;
 const emits = defineEmits(['close']);
 
@@ -297,7 +299,6 @@ const form = ref({
   remarks: ''
 });
 let godownList = ref([]);
-let materialTypeList = ref([]);
 let materialWarehouseRootList = ref([]);
 const closeDialog = () => {
   emits('close');
@@ -306,9 +307,6 @@ onMounted(() => {
   getMaterialWarehouseRootList().then((res) => {
     materialWarehouseRootList.value = res.data;
   });
-  getMaterialTypeList().then((res) => {
-    materialTypeList.value = res.data;
-  });
   getMaterialWarehouseList().then((res) => {
     godownList.value = res.data;
   });
@@ -316,7 +314,6 @@ onMounted(() => {
     form.value = res.data;
   });
 })
-
 </script>
 
 <style lang="scss" scoped>

+ 1 - 1
src/views/comprehensiveGuarantee/MaterialReserveManagement/MaterialStatistics.vue

@@ -53,7 +53,7 @@
 </template>
 <script lang="ts" setup>
 import { graphic } from 'echarts';
-import { getCountDate, getMaterialDate, getMaterialList } from '@/api/comprehensiveGuarantee/MaterialReserveManagement/MaterialStatistics';
+import { getCountDate, getMaterialDate, getMaterialList } from '@/api/comprehensiveGuarantee/materialReserveManagement/MaterialStatistics';
 let totalData = ref({
   'warehouseNum': '',
   'goodsNum': ''

+ 22 - 12
src/views/comprehensiveGuarantee/MaterialReserveManagement/addMaterialInformation.vue

@@ -75,7 +75,9 @@
             </el-col>
             <el-col :span="12">
               <el-form-item label="分类名称:" prop="category_name">
-                <el-input v-model="form.category_name" placeholder="请输入分类名称" />
+                <el-select v-model="form.category_name" placeholder="请选择分类名称">
+                  <el-option v-for="(item, index) in material_classification" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="12">
@@ -86,7 +88,7 @@
             <el-col :span="12">
               <el-form-item label="物资类型:" prop="material_type_id">
                 <el-select v-model="form.material_type_id" placeholder="请选择物资类型">
-                  <el-option v-for="(item, index) in materialTypeList" :key="index" :label="item.material_category_name" :value="item.id" />
+                  <el-option v-for="(item, index) in material_type" :key="index" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
@@ -229,12 +231,11 @@
 </template>
 <script setup lang="ts">
 import { getMaterialWarehouseList } from '@/api/comprehensiveGuarantee/materialReserveManagement/godownManagement';
-import { getMaterialTypeList } from '@/api/comprehensiveGuarantee/materialReserveManagement/typesMaterialsManagement';
 import { getMaterialWarehouseRootList } from '@/api/comprehensiveGuarantee/materialReserveManagement/warehouseManagement';
 import { createMaterial, getMaterialInfo, updateMaterial } from '@/api/comprehensiveGuarantee/materialReserveManagement/materialInformation';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { disaster_type, material_source } = toRefs<any>(proxy?.useDict('disaster_type', 'material_source'));
+const { disaster_type, material_source, material_classification, material_type } = toRefs<any>(proxy?.useDict('disaster_type', 'material_source', 'material_classification', 'material_type'));
 const emits = defineEmits(['close']);
 const buttonLoading = ref(false);
 const props = defineProps({
@@ -286,12 +287,12 @@ const data = reactive({
   },
   rules: {
     material_name: [{ required: true, message: '物资名称不能为空', trigger: 'blur' }],
-    warehouse_id: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
-    inventory: [{ required: true, message: '库存不能为空', trigger: 'blur' }],
+    warehouse_id: [{ required: true, message: '请选择仓库', trigger: 'change' }],
+    inventory: [{ required: true, message: '请选择库存', trigger: 'change' }],
     specification: [{ required: true, message: '规格不能为空', trigger: 'blur' }],
     model: [{ required: true, message: '型号不能为空', trigger: 'blur' }],
-    category_name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
-    material_type_id: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
+    category_name: [{ required: true, message: '请选择分类名称', trigger: 'change' }],
+    material_type_id: [{ required: true, message: '请选择物资类型', trigger: 'change' }],
     unit_name: [{ required: true, message: '计量单位名称不能为空', trigger: 'blur' }],
     brand_name: [{ required: true, message: '品牌名称不能为空', trigger: 'blur' }],
     length: [{ required: true, message: '长度不能为空', trigger: 'blur' }],
@@ -326,7 +327,6 @@ const data = reactive({
 
 const { form, rules } = toRefs(data);
 let godownList = ref([]);
-let materialTypeList = ref([]);
 let materialWarehouseRootList = ref([]);
 const closeDialog = () => {
   emits('close');
@@ -346,6 +346,19 @@ const submitForm = async (formEl) => {
           emits('close', true);
         });
       }
+    } else {
+      nextTick(() => {
+        let isError = document.getElementsByClassName('is-error');
+        isError[0].scrollIntoView({
+          // 滚动到指定节点
+          // 值有start,center,end,nearest,当前显示在视图区域中间
+          block: 'center',
+          // 值有auto、instant,smooth,缓动动画(当前是慢速的)
+          behavior: 'smooth'
+        });
+      });
+      proxy.$modal.msgError('表单校验失败');
+      return false;
     }
   });
 };
@@ -354,9 +367,6 @@ onMounted(() => {
   getMaterialWarehouseRootList().then((res) => {
     materialWarehouseRootList.value = res.data;
   });
-  getMaterialTypeList().then((res) => {
-    materialTypeList.value = res.data;
-  });
   getMaterialWarehouseList().then((res) => {
     godownList.value = res.data;
   });

+ 19 - 1
src/views/emergencyCommandMap/LeftSection/Communication.vue

@@ -92,7 +92,7 @@
           <div class="icon2"></div>
           <div class="text">电话呼叫</div>
         </div>
-        <div class="btn">
+        <div class="btn" @click="handleStartMeeting">
           <div class="icon3"></div>
           <div class="text">发起会议</div>
         </div>
@@ -103,6 +103,7 @@
 
 <script lang="ts" setup>
 import { Search } from '@element-plus/icons-vue';
+import { getStartMiniParan } from '@/api/emergencyCommandMap/communication';
 
 let activeIndex = ref(0);
 const options = ref([{ name: '全部', value: '全部' }]);
@@ -251,6 +252,23 @@ const deleteItem = (item) => {
     }
   }
 };
+// 发起会议
+const handleStartMeeting = () => {
+  const data = {
+    userid: 'mmyj0006@mm.zw.yj',
+    password: '123',
+    roomid: '',
+    'dev-list': [{ id: 'hh@mm.zw.yj', avtype: 'av' }]
+  };
+  getStartMiniParan(data).then((res) => {
+    // 创建一个a标签元素
+    const a = document.createElement('a');
+    // 设置a标签的href属性
+    a.href = res.data;
+    // 触发点击事件
+    a.click();
+  });
+};
 </script>
 
 <style lang="scss" scoped>

+ 3 - 0
src/views/globalMap/RightMenu/GridPointRainfall.vue

@@ -23,6 +23,9 @@ const handleClose = () => {
 };
 let AMap, geocoder;
 onMounted(() => {
+  window._AMapSecurityConfig = {
+    securityJsCode: '4868bc1b8fac7d9e54e7279ed556879a'
+  };
   AMapLoader.load({
     key: '9c5041381e5e824f9ee324d8f7a40150', // 申请好的Web端开发者Key,首次调用 load 时必填
     version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15

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

@@ -0,0 +1,134 @@
+<template>
+  <Dialog custom-show :title="!id ? '新增分类' : '修改分类'" class="custom-dialog" @close="handleCancel" @confirm="submitForm(classFormRef)">
+    <el-form ref="classFormRef" :model="form" :rules="rules">
+      <el-form-item label="分类名称:" label-width="80px" prop="name">
+        <el-input v-model="form.name" class="custom-input2" placeholder="请输入分类名称" />
+      </el-form-item>
+      <el-form-item label="分类值:" label-width="80px" prop="value">
+        <el-input v-model="form.value" class="custom-input2" placeholder="请输入分类值" />
+      </el-form-item>
+      <el-form-item label="图标:" label-width="80px" 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="80px" prop="size.0">
+        <el-input v-model="form.size[0]" class="custom-input2" placeholder="请输入图标宽度" />
+      </el-form-item>
+      <el-form-item label="图标高度:" label-width="80px" prop="size.1">
+        <el-input v-model="form.size[1]" class="custom-input2" placeholder="请输入图标高度" />
+      </el-form-item>
+      <el-form-item label="排序:" label-width="80px" prop="order_num">
+        <el-input v-model="form.order_num" class="custom-input2" placeholder="请输入排序" />
+      </el-form-item>
+      <el-form-item label="状态:" label-width="80px" 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>
+.custom-dialog {
+  :deep(.el-form) {
+    .el-form-item__label {
+      color: #fff !important;
+      font-weight: bold !important;
+      margin-right: 5px !important;
+    }
+  }
+  .upload-box {
+    :deep(.el-upload__tip) {
+      color: #ffffff !important;
+    }
+  }
+}
+</style>

+ 62 - 167
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" size="small" 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"
@@ -87,7 +87,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">
@@ -97,7 +97,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" />
@@ -105,6 +105,9 @@
                 </div>
               </div>
             </div>
+            <div v-if="showSetting" class="tab" @click="handleShowAddClass">
+              <el-icon color="#7495b4" :size="35"><Plus /></el-icon>
+            </div>
           </div>
         </div>
       </div>
@@ -165,6 +168,8 @@
       </div>
     </div>
   </div>
+  <!--添加修改分类弹窗-->
+  <EditClassDialog v-if="showAddDialog" v-model="showAddDialog" :id="selectEditId" :templateId="selectTemplateId" @updateData="getTemplateTreeData" />
   <!--添加文字-->
   <TextEdit v-if="showTextEdit" v-model="showTextEdit" @add-text="addText" />
   <!--绘制提示信息-->
@@ -186,14 +191,18 @@ import { nanoid } from 'nanoid';
 import { deepClone } from '@/utils';
 import { useHistory } from '@/hooks/useHistory';
 import {
+  changeVisibleClassification,
+  closeCollaboration,
+  createCollaboration,
+  deleteClassificationCreate,
   deletePatternById,
   getPatternInfo,
   getPatternList,
-  closeCollaboration,
-  createCollaboration
+  getTemplateTree
 } from '@/api/globalMap/onlinePlotting';
-import TextEdit from '@/views/globalMap/RightMenu/OnlinePlotting/TextEdit.vue';
-import EditDialog from '@/views/globalMap/RightMenu/OnlinePlotting/EditDialog.vue';
+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';
@@ -206,8 +215,8 @@ const getMapUtils = inject('getMapUtils');
 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({
@@ -221,152 +230,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: [55, 29] },
-          { name: '烟点', value: 'marker', image: getImageUrl('smokePoint'), icon: 'smokePoint', size: [55, 29] },
-          { name: '已灭火点', value: 'marker', image: getImageUrl('extinguishedPoint'), icon: 'extinguishedPoint', size: [55, 29] }
-        ]
-      },
-      {
-        name: '火线',
-        value: 'firewire',
-        children: [
-          { name: '火线', value: 'marker', image: getImageUrl('firewire'), icon: 'firewire', size: [55, 29] },
-          { name: '受控火线', value: 'marker', image: getImageUrl('controlledfireline'), icon: 'controlledfireline', size: [55, 29] },
-          { name: '已灭火线', value: 'marker', image: getImageUrl('extinguishedline'), icon: 'extinguishedline', size: [55, 29] },
-          { name: '强火线', value: 'marker', image: getImageUrl('StrongFrontline'), icon: 'StrongFrontline', size: [55, 29] },
-          { name: '中火线', value: 'marker', image: getImageUrl('ZhongxianLine'), icon: 'ZhongxianLine', size: [55, 29] },
-          { name: '弱火线', value: 'marker', image: getImageUrl('WeakFrontline'), icon: 'WeakFrontline', size: [55, 29] }
-        ]
-      },
-      {
-        name: '火场',
-        value: 'fireGround',
-        children: [
-          { name: '火场', value: 'marker', image: getImageUrl('fireground'), icon: 'fireground', size: [55, 29] },
-          { name: '受控火场', value: 'marker', image: getImageUrl('controlledfireground'), icon: 'controlledfireground', size: [55, 29] },
-          { name: '已灭火场', value: 'marker', image: getImageUrl('extinguishedfireground'), icon: 'extinguishedfireground', size: [55, 29] }
-        ]
-      },
-      {
-        name: '箭头',
-        value: 'arrow',
-        children: [
-          { name: '曲箭头', value: 'marker', image: getImageUrl('curvedarrow'), icon: 'curvedarrow', size: [55, 29] },
-          { name: '直箭头', value: 'marker', image: getImageUrl('straightarrow1'), icon: 'straightarrow1', size: [55, 29] },
-          { name: '细箭头', value: 'marker', image: getImageUrl('thinarrow'), icon: 'thinarrow', size: [55, 29] }
-        ]
-      },
-      // {
-      //   name: '导航',
-      //   value: 'navigation',
-      //   children: [
-      //     { name: '导航', value: 'marker', image: getImageUrl('navigation'), icon: 'navigation', size: [55, 29] }
-      //   ]
-      // },
-      {
-        name: '扑救队伍',
-        value: 'firefightingTeam',
-        children: [
-          { name: '指挥中心', value: 'marker', image: getImageUrl('commandcentre'), icon: 'commandcentre', size: [55, 29] },
-          { name: '分指中心', value: 'marker', image: getImageUrl('dividingcenter'), icon: 'dividingcenter', size: [55, 29] },
-          { name: '集结地', value: 'marker', image: getImageUrl('rendezvous'), icon: 'rendezvous', size: [55, 29] },
-          { name: '军队', value: 'marker', image: getImageUrl('army'), icon: 'army', size: [55, 29] },
-          { name: '武警', value: 'marker', image: getImageUrl('armedpolice'), icon: 'armedpolice', size: [55, 29] },
-          { name: '森林警察', value: 'marker', image: getImageUrl('forestpoliceman'), icon: 'forestpoliceman', size: [55, 29] },
-          { name: '扑火队伍', value: 'marker', image: getImageUrl('firefightingteam'), icon: 'firefightingteam', size: [55, 29] },
-          // { name: '扑火队伍路线', value: 'marker', image: getImageUrl('Firefightingteamroute'), icon: 'Firefightingteamroute', size: [55, 29] }
-        ]
-      },
-      {
-        name: '飞机车辆',
-        value: 'aircraftVehicles',
-        children: [
-          { name: '固定翼', value: 'marker', image: getImageUrl('fixedwing'), icon: 'fixedwing', size: [55, 29] },
-          { name: '直升机', value: 'marker', image: getImageUrl('helicopter'), icon: 'helicopter', size: [55, 29] },
-          { name: '无人机', value: 'marker', image: getImageUrl('UAV'), icon: 'UAV', size: [55, 29] },
-          { name: '指挥车', value: 'marker', image: getImageUrl('commandvehicle'), icon: 'commandvehicle', size: [55, 29] },
-          { name: '飞机航线设置', value: 'marker', image: getImageUrl('aircraftroutesetting'), icon: 'aircraftroutesetting', size: [55, 29] },
-          { name: '直升机航线设置', value: 'marker', image: getImageUrl('helicopterroutesetting'), icon: 'helicopterroutesetting', size: [55, 29] }
-        ]
-      },
-      {
-        name: '基础设置',
-        value: 'basicSetting',
-        children: [
-          { name: '航站', value: 'marker', image: getImageUrl('terminal'), icon: 'terminal', size: [55, 29] },
-          { name: '起降点', value: 'marker', image: getImageUrl('takeoffandlandingpoint'), icon: 'takeoffandlandingpoint', size: [55, 29] },
-          { name: '取水点', value: 'marker', image: getImageUrl('waterpoint'), icon: 'waterpoint', size: [55, 29] },
-          { name: '瞭望塔', value: 'marker', image: getImageUrl('watchtower'), icon: 'watchtower', size: [55, 29] },
-          { name: '物资库', value: 'marker', image: getImageUrl('materialwarehouse'), icon: 'materialwarehouse', size: [55, 29] },
-
-        ]
-      },
-      // {
-      //   name: '其他',
-      //   value: 'other',
-      //   children: [
-      //     { name: '危险区域', value: 'marker', image: getImageUrl('dangerousarea'), icon: 'dangerousarea', size: [55, 29] },
-      //     { name: '隔离带开采', value: 'marker', image: getImageUrl('Isolationzonemining'), icon: 'Isolationzonemining', size: [55, 29] },
-      //     { name: '应急庇护场所', value: 'marker', image: getImageUrl('emergencyshelter'), icon: 'emergencyshelter', size: [55, 29] },
-      //     { name: '风力风向', value: 'marker', image: getImageUrl('windspeedanddirection'), icon: 'windspeedanddirection', size: [55, 29] },
-      //     { name: '测距', value: 'marker', image: getImageUrl('ranging'), icon: 'ranging', size: [55, 29] },
-      //     { name: '大风', value: 'marker', image: getImageUrl('strongwind'), icon: 'strongwind', size: [55, 29] },
-      //     { name: '人工降雨', value: 'marker', image: getImageUrl('artificialrainfall'), icon: 'artificialrainfall', size: [55, 29] },
-      //     { name: '台风', value: 'marker', image: getImageUrl('typhoon'), icon: 'typhoon', size: [55, 29] }
-      //   ]
-      // }
-    ]
+    children: []
   },
   {
     name: '历史预案',
@@ -422,6 +286,40 @@ 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;
@@ -901,6 +799,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) => {
@@ -909,15 +812,6 @@ const handleShowSetting = (item, index) => {
     });
   });
 };
-const handleShowSwitch = (item) => {
-  item.showSetting = false;
-};
-const handleMenuItemHide = (item) => {
-  item.showSetting = false;
-};
-const handleMenuItemDelete = (item) => {
-  item.showSetting = false;
-};
 let dataURL = ref('');
 // 页面元素转图片
 const handleScreenshot = () => {
@@ -969,6 +863,7 @@ const handleSendData = (data) => {
   }
 };
 onMounted(() => {
+  getTemplateTreeData();
   getList();
 });
 </script>
@@ -1258,7 +1153,7 @@ onMounted(() => {
             display: inline-block;
             width: 12px;
             height: 12px;
-            background: url('@/assets/images/map/rightMenu/onlinePlotting/switch1.png') no-repeat;
+            background: url('@/assets/images/map/rightMenu/onlinePlotting/switch2.png') no-repeat;
             background-size: 100% 100%;
             margin-right: 6px;
           }
@@ -1290,7 +1185,7 @@ onMounted(() => {
             color: #00fde7;
             background: #1e3b77;
             .icon-switch {
-              background: url('@/assets/images/map/rightMenu/onlinePlotting/switch2.png') no-repeat;
+              background: url('@/assets/images/map/rightMenu/onlinePlotting/switch1.png') no-repeat;
               background-size: 100% 100%;
             }
             .icon-eye {

+ 3 - 0
src/views/routineCommandMap/PositionMap.vue

@@ -225,6 +225,9 @@ const updateForm = (position) => {
 };
 const initMap = () => {
   let position = [110.925175, 21.678955];
+  window._AMapSecurityConfig = {
+    securityJsCode: '4868bc1b8fac7d9e54e7279ed556879a'
+  };
   AMapLoader.load({
     key: '9c5041381e5e824f9ee324d8f7a40150', // 申请好的Web端开发者Key,首次调用 load 时必填
     version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15