瀏覽代碼

电子灾害地图 对接接口

Hwf 9 月之前
父節點
當前提交
6d730dee8f

+ 13 - 0
src/api/globalMap/index.ts

@@ -96,3 +96,16 @@ export const getVideoInfo = (params) => {
     data: params
   });
 };
+
+// 定点分析列表查询
+export const getEmergencyRescuePointInfoList = (params) => {
+  return request({
+    url: '/api/gateway/v2/get_emergency_rescue_point_info_list',
+    method: 'post',
+    data: {
+      query: {
+        ...params
+      }
+    }
+  });
+};

+ 2 - 8
src/types/components.d.ts

@@ -24,7 +24,7 @@ declare module 'vue' {
     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']
@@ -40,16 +40,14 @@ declare module 'vue' {
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     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']
     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']
-    ElSegmented: typeof import('element-plus/es')['ElSegmented']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
@@ -57,11 +55,7 @@ declare module 'vue' {
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     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']
     FooterSection: typeof import('./../components/FooterSection/index.vue')['default']

+ 334 - 11
src/views/comprehensiveGuarantee/electronicDisasterMapManage/index.vue

@@ -28,6 +28,41 @@
     </div>
     <div v-show="!!selectData.longitude && !!selectData.latitude" class="search-box">
       <div class="search-title">{{ selectData.event_title }}</div>
+      <div class="search-item">
+        <div class="text1">选择救灾资源</div>
+        <el-select
+          v-model="queryParams.dataType"
+          class="custom-select select-box"
+          placeholder="请选择"
+          popper-class="custom-select-popper"
+          :teleported="false"
+        >
+          <el-option v-for="item in disaster_relief_material" :key="item.value" :label="item.label" :value="item.value"></el-option>
+        </el-select>
+      </div>
+      <div class="search-item2">
+        <el-input v-model="queryParams.keyword" class="custom-input2" placeholder="请输入关键字搜索" style="width: 200px" />
+        <div class="common-btn-primary" @click="getList">搜索</div>
+      </div>
+      <div class="search-item3">
+        <el-checkbox v-model="checked1">自定义距离</el-checkbox>
+        <el-input v-model="distance" class="custom-input2" placeholder="自定义距离(公里)" style="width: 200px" />
+      </div>
+
+      <div class="list2">
+        <div>总数: {{ total }}个</div>
+        <div class="list-content">
+          <div v-for="(item, index) in dataList" :key="index" class="list-item">
+            <div class="text1">{{ item.name }}</div>
+            <div class="text-box">
+              <div class="text2">{{ item.address }}</div>
+              <div class="text3" @click="handleRoutes(item)">路线</div>
+            </div>
+
+          </div>
+        </div>
+      </div>
+      <div class="text2"></div>
       <div v-for="(item, index) in routeData" :key="index" class="route-item" @click="drawRoute(item)">
         {{ item.policy }} | {{ item.distance / 1000 }}公里
       </div>
@@ -39,18 +74,44 @@
 // 初始化地图
 import { useAMap } from '@/hooks/AMap/useAMap';
 import { getEventActiveList } from '@/api/duty/eventing';
-import { getPointInfo } from '@/api/globalMap';
-import { iconList } from '@/views/globalMap/data/mapData';
+import { getEmergencyRescuePointInfoList, getPointInfo, getPointInfoList } from '@/api/globalMap';
+import { iconList, pointDetailTemplate } from '@/views/globalMap/data/mapData';
+import { getDictLabel } from '@/utils/dict';
+import {
+  getBuildingProjectDetails,
+  getChemicalcompanyDetails,
+  getChemicalWarehouseDetails,
+  getConstructionSitesDetails,
+  getEmergencyDisasterInfoOfficerDetails,
+  getEmergencyExpertDetails,
+  getEmergencyShelterTypeDetails,
+  getEmergencyTransportResourcesDetails,
+  getGasolinestationDetails,
+  getHospitalDetails,
+  getMajorHazardSourceDetails,
+  getMidmapDzzhDetails,
+  getMiningcompanyDetails,
+  getMiningOperationsDetails,
+  getRainbowDetails,
+  getSchoolDetails,
+  getShipRealtilmePositionDetails,
+  getStationInfoDetails,
+  getTouristAttractionDetails,
+  getUAVDetails,
+  getWarehouseDetails,
+  getWaterloggedRoadsDetails,
+  getYardSitesDetails
+} from '@/api/globalMap/spatialAnalysis';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { emergency_resource } = toRefs<any>(proxy?.useDict('emergency_resource'));
+const { emergency_resource, disaster_relief_material } = toRefs<any>(proxy?.useDict('emergency_resource', 'disaster_relief_material'));
 // 应急资源
 let expand = ref(true);
 let AMap, map, driving;
 let end = ref([110.925176, 21.678993]);
 let routeData = ref([]);
 let routeLine, startMarker, endMarker;
-const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker } = useAMap({
+const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker, showInfo, hideInfo } = useAMap({
   el: 'aMap2',
   key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
   version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
@@ -69,7 +130,58 @@ const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker } = useAMa
     //构造路线导航类
     driving = new AMap.Driving({});
   },
-  onMarkerClick: (data) => {}
+  onMarkerClick: (data) => {
+    // 多点位
+    if (data.type === '1') {
+      let path = [];
+      props.pointType.forEach((item) => {
+        path.push(item.component);
+      });
+      getPointInfoList({
+        option: path.toString(),
+        longitude: data.longitude.toString(),
+        latitude: data.latitude.toString()
+      }).then((res) => {
+        const data2 = res.data.list;
+        let content = document.createElement('div');
+        // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
+        content.className = 'point-info';
+        let content2 = '';
+        content2 += '<div class="title-box"><div class="gradient-text">多点位信息</div></div>';
+        content2 += '<div class="icon1"></div>';
+        content2 += '<div class="icon2"></div>';
+        content2 += '<div class="icon3"></div>';
+        content2 += '<div class="icon4"></div>';
+        content.innerHTML = content2;
+        let tableBox = document.createElement('div');
+        tableBox.className = 'table-box';
+        let table = document.createElement('div');
+        table.className = 'table';
+        table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
+        data2.forEach((item) => {
+          item.longitude = data.longitude;
+          item.latitude = data.latitude;
+          const div = document.createElement('div');
+          div.className = 'point-item point-item-hover';
+          div.innerHTML =
+            '<div class="td4">' + getDictLabel(point_type.value, item.dataType.toString()) + '</div><div class="td4">' + item.name + '</div>';
+          div.addEventListener('click', () => {
+            handlePointDetails(item);
+          });
+          table.appendChild(div);
+        });
+        tableBox.appendChild(table);
+        content.appendChild(tableBox);
+        let closeBtn = document.createElement('div');
+        closeBtn.className = 'close';
+        closeBtn.onclick = hideInfo;
+        content.appendChild(closeBtn);
+        showInfo(content, [data.longitude, data.latitude], true);
+      });
+    } else {
+      handlePointDetails(data);
+    }
+  }
 });
 let eventList = ref([]);
 let selectData = ref({
@@ -78,20 +190,30 @@ let selectData = ref({
   latitude: ''
 });
 let selectMarker;
+let checked1 = ref(false);
+let distance = ref('');
+let queryParams = reactive({
+  keyword: '',
+  dataType: ''
+});
+let total = ref(0);
+let dataList = ref([]);
 const toSelect = () => {
   map.on('click', handleClickMap);
 };
 const handleClickMap = (e) => {
   map.off('click', handleClickMap);
-  selectEvent({
-    longitude: e.lnglat.getLng(),
-    latitude: e.lnglat.getLat()
-  }, true);
+  selectEvent(
+    {
+      longitude: e.lnglat.getLng(),
+      latitude: e.lnglat.getLat()
+    },
+    true
+  );
 };
 // 选中事件
 const selectEvent = (item, unFitView) => {
   selectData.value = item;
-  calculateRoutes([item.longitude, item.latitude], end.value, 0);
   if (!!selectMarker) {
     selectMarker.setMap(null);
     selectMarker = null;
@@ -111,6 +233,11 @@ const selectEvent = (item, unFitView) => {
     map.setFitView([selectMarker]);
   }
 };
+const handleRoutes = (item) => {
+  const start = [item.longitude, item.latitude];
+  const end = [selectData.value.longitude, selectData.value.latitude];
+  calculateRoutes(start, end, 0);
+};
 // 计算并展示三条路线
 const calculateRoutes = (start, end, index) => {
   if (index >= 3) {
@@ -202,6 +329,186 @@ const parseRouteToPath = (route) => {
 
   return path;
 };
+const handlePointDetails = (data) => {
+  let methodList = {
+    '1': getEmergencyExpertDetails,
+    '2': getWarehouseDetails,
+    '3': getEmergencyShelterTypeDetails,
+    '4': getWaterloggedRoadsDetails,
+    '5': getSchoolDetails,
+    '6': getHospitalDetails,
+    '7': getGasolinestationDetails,
+    '8': getMiningcompanyDetails,
+    // '9': getChemicalcompanyDetails,
+    '10': getShipRealtilmePositionDetails,
+    '11': getChemicalcompanyDetails,
+    '12': getChemicalcompanyDetails,
+    '13': getChemicalcompanyDetails,
+    '14': getChemicalcompanyDetails,
+    '15': getUAVDetails,
+    '16': getRainbowDetails,
+    '17': getMidmapDzzhDetails,
+    '18': getMiningOperationsDetails,
+    '21': getBuildingProjectDetails,
+    '22': getChemicalWarehouseDetails,
+    '23': getMajorHazardSourceDetails,
+    '24': getStationInfoDetails,
+    '25': getYardSitesDetails,
+    '26': getTouristAttractionDetails,
+    '27': getConstructionSitesDetails,
+    '28': getEmergencyTransportResourcesDetails,
+    '29': getEmergencyDisasterInfoOfficerDetails
+  };
+  let titleList = {
+    '1': '专家信息',
+    '2': '物资与装备仓库信息',
+    '3': '避难所信息',
+    '4': '易涝点信息',
+    '5': '学校信息',
+    '6': '医院信息',
+    '7': '加油站信息',
+    '8': '非煤矿山企业信息',
+    '9': '危化企业信息',
+    '10': '船舶动态信息',
+    '11': '危险化学品经营企业信息',
+    '12': '危险化学品生产企业信息',
+    '13': '危险化学品使用企业(使用许可)信息',
+    '14': '化工企业(不发使用许可)信息',
+    '15': '无人机信息',
+    '16': '雨窝点',
+    '17': '地质灾害隐患点',
+    '18': '矿山施工',
+    '19': '工矿商贸',
+    '20': '气象灾害防御重点单位',
+    '21': '建筑工程',
+    '22': '储罐信息',
+    '23': '重大危险源',
+    '24': '客运站',
+    '25': '堆场',
+    '26': '旅游场所',
+    '27': '在建工地',
+    '28': '运输资源',
+    '29': '灾害信息员'
+  };
+  let method = methodList[data.dataType];
+  let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
+  if (!method) return;
+  method(data.id).then((res) => {
+    if (!!pointDetailTemplate[data.dataType]) {
+      let div = document.createElement('div');
+      // div.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
+      div.className = 'point-info';
+      let titleDom = document.createElement('div');
+      titleDom.className = 'title-box';
+      titleDom.innerHTML = '<div class="gradient-text">' + title + '</div></div>';
+      div.appendChild(titleDom);
+      if (data.dataType === 2) {
+        let btnBox = document.createElement('div');
+        let btn = document.createElement('div');
+        btnBox.className = 'flex';
+        btn.className = 'btn';
+        btn.innerHTML = '<div class="video-icon"></div><div>物资详情</div>';
+        btn.onclick = () => {
+          emits('handleShowWarehouse', data);
+        };
+        btnBox.appendChild(btn);
+        div.appendChild(btnBox);
+      } else if (data.dataType === 4) {
+        let btnBox = document.createElement('div');
+        let btn = document.createElement('div');
+        btnBox.className = 'flex';
+        btn.className = 'btn';
+        btn.innerHTML = '<div class="video-icon"></div><div>附近视频</div>';
+        btn.onclick = () => {
+          emits('handleShowVideo', data);
+        };
+        btnBox.appendChild(btn);
+        div.appendChild(btnBox);
+      }
+      let icon1 = document.createElement('div');
+      icon1.className = 'icon1';
+      let icon2 = document.createElement('div');
+      icon2.className = 'icon2';
+      let icon3 = document.createElement('div');
+      icon3.className = 'icon3';
+      let icon4 = document.createElement('div');
+      icon4.className = 'icon4';
+      div.appendChild(icon1);
+      div.appendChild(icon2);
+      div.appendChild(icon3);
+      div.appendChild(icon4);
+      let table = document.createElement('div');
+      table.className = 'table-box';
+      let content = '';
+      content += '<div class="table">';
+      const newData = filterTd(res.rows[0], data.dataType);
+      newData.forEach((item) => {
+        if (item.type === 'shortText') {
+          content += '<div class="tr">';
+          item.data.forEach((item2) => {
+            content += '<div class="point-item">';
+            content += '<div class="td1">' + item2.label + '</div><div class="td2">' + item2.value + '</div>';
+            content += '</div>';
+          });
+          content += '</div>';
+        } else {
+          content += '<div class="point-item2">';
+          content += '<div class="td1">' + item.data[0].label + '</div><div class="td2">' + item.data[0].value + '</div>';
+          content += '</div>';
+        }
+      });
+      content += '</div>';
+      table.innerHTML = content;
+      div.appendChild(table);
+      let closeBtn = document.createElement('div');
+      closeBtn.className = 'close';
+      closeBtn.onclick = hideInfo;
+      div.appendChild(closeBtn);
+      showInfo(div, [data.longitude, data.latitude], true);
+    }
+  });
+};
+const filterTd = (obj, dataType) => {
+  let data = [];
+  let tempData = {};
+  let i = 0;
+  for (let key in obj) {
+    let keyLabel = pointDetailTemplate[dataType][key];
+    if (!!keyLabel) {
+      if (i === 2) {
+        i = 0;
+      }
+      const value = !!obj[key] ? obj[key] : '';
+      if (value && value.length > 8) {
+        if (i === 0) {
+          data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
+          i = 0;
+        } else {
+          tempData = { type: 'longText', data: [{ label: keyLabel, value: value }] };
+        }
+      } else {
+        if (i === 0) {
+          data.push({ type: 'shortText', data: [{ label: keyLabel, value: value }] });
+        } else {
+          data[data.length - 1].data.push({ label: keyLabel, value: value });
+        }
+        i++;
+        if (!!tempData && JSON.stringify(tempData) !== '{}') {
+          data.push(tempData);
+          tempData = {};
+          i = 0;
+        }
+      }
+    }
+  }
+  if (!!tempData && JSON.stringify(tempData) !== '{}') {
+    data.push(tempData);
+  }
+  if (data[data.length - 1].data && data[data.length - 1].data.length === 1 && data[data.length - 1].type === 'shortText') {
+    data[data.length - 1].data[1] = { label: '', value: '' };
+  }
+  return data;
+};
 const handleClick = (item) => {
   item.checked = !item.checked;
   let path = [];
@@ -237,6 +544,21 @@ const handleClick = (item) => {
     addMarker(data);
   });
 };
+// 搜索列表
+const getList = () => {
+  const params = {
+    dataType: queryParams.dataType,
+    keyword: queryParams.keyword,
+    distance: ''
+  };
+  if (checked1.value) {
+    params.distance = distance.value;
+  }
+  getEmergencyRescuePointInfoList(params).then((res) => {
+    dataList.value = res.rows;
+    total.value = res.total;
+  });
+};
 const initData = () => {
   getEventActiveList().then((res) => {
     eventList.value = res.data;
@@ -253,6 +575,7 @@ onUnmounted(() => {
 </script>
 
 <style lang="scss" scoped>
+@import '@/components/Map/map.scss';
 .map-container {
   width: 100%;
   height: 100%;
@@ -382,7 +705,7 @@ onUnmounted(() => {
     }
   }
 }
-.amap-icon img{
+.amap-icon img {
   width: 25px;
   height: 34px;
 }