Prechádzať zdrojové kódy

配置地图、响应统计

Hwf 1 týždeň pred
rodič
commit
a42872923c

+ 18 - 0
src/api/globalMap/layerConfig/index.ts

@@ -117,3 +117,21 @@ export const getLayerMenuType = () => {
     method: 'get'
   });
 };
+
+// 配置地图列表
+export const getLayerDtList = (params) => {
+  return request({
+    url: '/api/layerConfiguration/zt/dt/list',
+    method: 'get',
+    params
+  });
+};
+
+// 专题地图列表更新
+export const updateLayerDtList = (id, data) => {
+  return request({
+    url: `/api/layerConfiguration/zt/${id}/dt/update`,
+    method: 'put',
+    data: data
+  });
+};

BIN
src/assets/images/edit.png


BIN
src/assets/images/edit3.png


+ 0 - 1
src/components/ImageUpload/index.vue

@@ -40,7 +40,6 @@
 </template>
 
 <script setup lang="ts">
-import { listByIds, delOss } from '@/api/system/oss';
 import { propTypes } from '@/utils/propTypes';
 import { globalHeaders } from '@/utils/request';
 import { compressAccurately } from 'image-conversion';

+ 5 - 5
src/layout/components/Sidebar/Logo.vue

@@ -85,10 +85,10 @@ const sideTheme = computed(() => settingsStore.sideTheme);
     }
   }
 
-  &.collapse {
-    .sidebar-logo {
-      margin-right: 0px;
-    }
-  }
+  //&.collapse {
+  //  .sidebar-logo {
+  //    margin-right: 0px;
+  //  }
+  //}
 }
 </style>

+ 1 - 1
src/main.ts

@@ -52,7 +52,7 @@ app.use(router);
 app.use(store);
 app.use(i18n);
 app.use(VXETable);
-app.use(print)
+app.use(print);
 app.use(plugins);
 // 自定义指令
 directive(app);

+ 6 - 2
src/store/modules/map.ts

@@ -1,5 +1,5 @@
 import { PointType } from '@/api/globalMap/type';
-import { listMenu2 } from '@/api/system/menu';
+import { listMenu } from '@/api/system/menu';
 
 export const useMapStore = defineStore('map', () => {
   const mapState = reactive({
@@ -50,6 +50,8 @@ export const useMapStore = defineStore('map', () => {
   const updateMenu = ref({});
   // 需要更新灾害点坐标
   const updateAddress = ref([]);
+  // 专题地图列表
+  const ztMapList = ref([]);
   // 设置地图加载完成状态
   const setMapLoaded = (loaded: boolean) => {
     mapLoaded.value = loaded;
@@ -141,7 +143,7 @@ export const useMapStore = defineStore('map', () => {
   };
   // 初始化左侧菜单数据
   const initMenuData = () => {
-    listMenu2().then((res: any) => {
+    listMenu().then((res: any) => {
       const data = res.data ? res.data : [];
       data.forEach((item: any) => {
         item.show = true;
@@ -158,6 +160,7 @@ export const useMapStore = defineStore('map', () => {
         });
       });
       menuData.value = data;
+      ztMapList.value = res.zt;
     });
   };
   // 取消勾选左侧所有菜单
@@ -209,6 +212,7 @@ export const useMapStore = defineStore('map', () => {
   return {
     mapState,
     menuData,
+    ztMapList,
     menuState,
     mapLoaded,
     activeMap,

+ 65 - 0
src/views/dataFilling/StatisticalAnalysis.vue

@@ -0,0 +1,65 @@
+<template>
+  <el-dialog title="统计分析" ref="formDialogRef" v-model="visible" width="750px" destroy-on-close append-to-body @before-close="handleClose">
+    <div style="font-size: 16px; font-weight: bold; margin: -15px 0 10px">响应统计</div>
+    <el-table :data="responseList">
+      <el-table-column label="响应启动时间" align="center" prop="" />
+      <el-table-column label="各单位响应确认时间" align="center" prop="" />
+      <el-table-column label="各单位到达时间" align="center" prop="" />
+      <el-table-column label="到达人数" align="center" prop="" />
+      <el-table-column label="调用车辆数量" align="center" prop="" />
+      <el-table-column label="携带装备数量" align="center" prop="" />
+      <el-table-column label="携带物资数量" align="center" prop="" />
+    </el-table>
+    <div style="font-size: 16px; font-weight: bold; margin: 10px 0">事件统计</div>
+    <el-table :data="eventList">
+      <el-table-column label="事件影响范围" align="center" prop="" />
+      <el-table-column label="疏散人数" align="center" prop="" />
+      <el-table-column label="伤亡人数/受伤人数" align="center" prop="" />
+      <el-table-column label="损失情况" align="center" prop="" />
+      <el-table-column label="任务完成率" align="center" prop="">
+        <template #default="{ row }">
+          {{ row.complete_rate === 0 ? row.complete_rate : `${row.complete_rate}%` }}
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup name="StatisticalAnalysis">
+import BigNumber from 'bignumber.js';
+
+interface Props {
+  modelValue: boolean;
+}
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false
+});
+const emits = defineEmits(['update:modelValue']);
+const visible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(newValue) {
+    emits('update:modelValue', newValue);
+  }
+});
+const handleClose = () => {
+  emits('update:modelValue', false);
+};
+const responseList = ref([]);
+const eventList = ref([]);
+</script>
+
+<style lang="scss" scoped>
+.summary-row {
+  font-weight: bold;
+  display: flex;
+  width: 100%;
+  td {
+    text-align: center;
+    padding: 18px 10px;
+    word-break: break-all;
+    flex: 1;
+  }
+}
+</style>

+ 15 - 14
src/views/dataFilling/fillingManage.vue

@@ -47,6 +47,7 @@
                   <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
                   <el-button icon="Refresh" @click="resetQuery">重置</el-button>
                   <el-button type="warning" plain icon="Download" :disabled="multiple" @click="exportTableData">导出</el-button>
+                  <el-button type="primary" icon="Help" @click="handleShowAnalysis">统计分析</el-button>
                 </el-col>
               </el-row>
             </el-form>
@@ -66,7 +67,7 @@
           <el-table-column label="截止填报时间" align="center" prop="end_time" />
           <el-table-column label="状态" align="center" prop="status">
             <template #default="scope">
-              {{ scope.row.status === 1 ? '禁用' : scope.row.status === 0 ? "在用" : "废止" }}
+              {{ scope.row.status === 1 ? '禁用' : scope.row.status === 0 ? '在用' : '废止' }}
             </template>
           </el-table-column>
           <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
@@ -87,8 +88,9 @@
       </div>
     </div>
     <FillingAdd v-if="fillingAddState.show" :event-id="fillingAddState.eventId" @close="handleCancel" />
-    <fillingIssued v-if="issuedState.show" :id="issuedState.id" @close="handleEditClose" @confirm="handleSure" @refresh="fetchFillList"></fillingIssued>
+    <fillingIssued v-if="issuedState.show" :id="issuedState.id" @close="handleEditClose" @confirm="handleSure" @refresh="fetchFillList" />
     <TableDetails v-if="tableDetailsState.show" :event-id="tableDetailsState.eventId" @close="handleCancel" />
+    <StatisticalAnalysis v-model="showAnalysis" />
   </div>
 </template>
 
@@ -104,6 +106,7 @@ import { deepClone } from '@/utils';
 import { addDateRange2, parseTime } from '@/utils/ruoyi';
 import { fillList } from '@/api/dataFilling/datafilling';
 import { download2 } from '@/utils/request';
+import StatisticalAnalysis from '@/views/dataFilling/StatisticalAnalysis.vue';
 
 const loading = ref(true);
 const showSearch = ref(true);
@@ -244,10 +247,6 @@ const handleSelectionChange = (selection) => {
   }
 };
 
-const handleTimeChange = () => {
-  // selectedTimeLabel.value = value ? `${value[0]} 至 ${value[1]}` : '请选择时间';
-};
-
 const baseUrl = import.meta.env.VITE_APP_BASE_API;
 const exportTableData = () => {
   fillingTable(ids.value[0]);
@@ -263,8 +262,6 @@ const handlePagination = ({ page, limit }) => {
 const handleIssue = (row) => {
   // issuedState.show = true;
   // issuedState.id = row.report_id;
-
-
   // 检查是否有report_id
   // if (!row.report_id) {
   //   console.error('报告ID不存在,无法下发');
@@ -273,11 +270,10 @@ const handleIssue = (row) => {
   // // 构造下发请求的URL
   // const releaseUrl = `${row.report_id}`;
   // 发起下发请求
-  fillingRelease(row.report_id)
-    .then(() => {
-      proxy.$modal.msgSuccess('发布成功');
-      fetchFillList();
-    })
+  fillingRelease(row.report_id).then(() => {
+    proxy.$modal.msgSuccess('发布成功');
+    fetchFillList();
+  });
 };
 const handleEditClose = () => {
   issuedState.show = false;
@@ -286,5 +282,10 @@ const handleSure = () => {
   issuedState.show = false;
   queryParams.value.page = 1;
   fetchFillList();
-}
+};
+let showAnalysis = ref(false);
+// 显示统计分析
+const handleShowAnalysis = () => {
+  showAnalysis.value = true;
+};
 </script>

+ 0 - 1
src/views/dataManagement/DataImport.vue

@@ -74,7 +74,6 @@ const dialogVisible = computed({
 });
 
 const handleClose = () => {
-  debugger
   emits('update:modelValue', false);
 };
 const number = ref(0);

+ 8 - 4
src/views/dataManagement/index.vue

@@ -69,6 +69,7 @@ import AddDataManagement from './AddDataManagement.vue';
 import DataImport from './DataImport.vue';
 import { deleteDataManagerInfo, getDataManagerDataList, getDataManagerInfo, getDataManagerList } from '@/api/dataManagement/dataManagement';
 import { parseTime } from '@/utils/ruoyi';
+import { deepClone } from '@/utils';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const queryParams = reactive({
@@ -114,7 +115,7 @@ const handleView = (row: any) => {
 };
 // 打开修改
 const handleUpdate = (row: any) => {
-  dataManagementAddState.data = row;
+  dataManagementAddState.data = deepClone(row);
   dataManagementAddState.show = true;
 };
 // 关闭
@@ -140,16 +141,18 @@ const removeItem = (item) => {
 
 // 数据选择变化
 const onDataTypeChange = () => {
-  const index = type.value.findIndex((row) => row.value === queryParams.dataType);
+  const index = type.value.findIndex((row) => row.id === queryParams.dataType);
   if (index !== -1) {
     importUrl.value = '/api/dataManager/generate_import_template/' + queryParams.dataType;
     fileName.value = type.value[index].layer_name;
+    dataUpdateTime.value = parseTime(type.value[index].data_update_time);
+    dataSourceUnit.value = type.value[index].data_resouce;
   }
   queryParams.page = 1;
   getList();
 };
 const parseTableTime = () => {
-  if (tableHeader.value.length > 0 && tableData.value.length > 0) return;
+  if (tableHeader.value.length == 0 || tableData.value.length == 0) return;
   tableHeader.value.forEach((row) => {
     let pattern = '';
     if (row.data_type === 'datetime') {
@@ -157,7 +160,6 @@ const parseTableTime = () => {
     } else if (row.data_type === 'date') {
       pattern = '{y}-{m}-{d}';
     }
-
     if (pattern) {
       tableData.value.forEach((item) => {
         if (item[row.column_name]) {
@@ -193,6 +195,8 @@ const loadData = () => {
     queryParams.dataType = type.value[0].id;
     importUrl.value = '/api/dataManager/generate_import_template/' + queryParams.dataType;
     fileName.value = type.value[0].layer_name;
+    dataUpdateTime.value = parseTime(type.value[0].data_update_time);
+    dataSourceUnit.value = type.value[0].data_resouce;
     getList();
   });
 };

+ 1 - 2
src/views/duty/eventing/StatisticalAnalysis.vue

@@ -1,6 +1,6 @@
 <template>
   <el-dialog title="统计分析" ref="formDialogRef" v-model="visible" width="750px" destroy-on-close append-to-body @before-close="handleClose">
-    <div style="font-size: 16px; font-weight: bold; margin: 10px 0">事件统计报表</div>
+    <div style="font-size: 16px; font-weight: bold; margin: -15px 0 10px">事件统计报表</div>
     <el-table :data="eventCasualtiesList">
       <el-table-column label="行政区划" align="center" prop="area_name" />
       <el-table-column label="受灾人数(人)" align="center" prop="injuries" />
@@ -68,7 +68,6 @@ const visible = computed({
   }
 });
 const handleClose = () => {
-  debugger
   emits('update:modelValue', false);
 };
 const eventCasualtiesList = ref([]);

+ 1 - 1
src/views/emergencyCommandMap/LeftSection/index.vue

@@ -392,7 +392,7 @@ defineExpose({
       display: inline-block;
       width: 20px;
       height: 20px;
-      background: url('@/assets/images/edit.png') no-repeat;
+      background: url('@/assets/images/edit3.png') no-repeat;
       background-size: 100% 100%;
       cursor: pointer;
       margin-left: 6px;

+ 27 - 8
src/views/globalMap/SwitchMapTool.vue

@@ -21,17 +21,36 @@
 
 <script lang="ts" setup name="SwitchMapTool">
 import useMapStore from '@/store/modules/map';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { zt_dt } = toRefs<any>(proxy?.useDict('zt_dt'));
 
 const mapStore = useMapStore();
+const route = useRoute();
 const emits = defineEmits(['switchMap']);
-const mapData = ref([
-  { name: '卫星图', key: 'satellite' },
-  { name: '业务图', key: 'vectorgraph' },
-  { name: '地形图', key: 'satellite3' },
-  { name: '流域图', key: 'satellite2' },
-  { name: '影像图', key: 'imageMap' },
-  { name: '简版图', key: 'imageMap2' }
-]);
+const mapData = computed(() => {
+  if (zt_dt.value && mapStore.ztMapList.length > 0) {
+    const path = route.path;
+    let zt = '';
+    if (path === '/globalMap' || path === '/globalMap2') {
+      zt = '全域地图';
+    } else if (['/index', '/index2', '/emergencyCommandMap', '/emergencyCommandMap2'].includes(path)) {
+      zt = '一图作战';
+    }
+    let res = [];
+    for (let i = 0; i < mapStore.ztMapList.length; i++) {
+      if (mapStore.ztMapList[i].zt === zt) {
+        const data = mapStore.ztMapList[i].data;
+        res = zt_dt.value.filter((item) => {
+          return data.includes(item.value);
+        });
+        break;
+      }
+    }
+    return res;
+  } else {
+    return [];
+  }
+});
 let open = ref(false);
 const selectItem = (key: string) => {
   if (mapStore.activeMap === key) return;

+ 54 - 3
src/views/globalMap/layerConfiguration.vue

@@ -43,6 +43,22 @@
         <el-col :span="1.5">
           <el-button type="danger" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
         </el-col>
+        <el-col v-if="queryParams.ZT" :span="6">
+          <el-form-item label="配置地图:">
+            <el-select
+              v-model="mapListSetting"
+              v-loading="updateStatus"
+              multiple
+              collapse-tags
+              collapse-tags-tooltip
+              placeholder="请选择"
+              style="width: 240px"
+              @change="handleUpdateLayerDtList"
+            >
+              <el-option v-for="item in zt_dt" :key="item.value" :label="item.label" :value="item.value" />
+            </el-select>
+          </el-form-item>
+        </el-col>
       </el-row>
 
       <el-table
@@ -180,7 +196,16 @@
 </template>
 
 <script setup name="LayerConfiguration" lang="ts">
-import { addLayerMenu, delLayerMenu, getLayerMenu, LayerlistMenu, updateLayerMenu, getLayerMenuType } from '@/api/globalMap/layerConfig';
+import {
+  addLayerMenu,
+  delLayerMenu,
+  getLayerMenu,
+  LayerlistMenu,
+  updateLayerMenu,
+  getLayerMenuType,
+  getLayerDtList,
+  updateLayerDtList
+} from '@/api/globalMap/layerConfig';
 import { MenuVO } from '@/api/globalMap/layerConfig/types';
 
 interface MenuOptionsType {
@@ -192,10 +217,12 @@ interface MenuOptionsType {
 // 菜单类型
 const menuTypeList = ref([]);
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { listing_status, topic_type, layer_configuration_template, point_type } = toRefs<any>(
-  proxy?.useDict('listing_status', 'topic_type', 'layer_configuration_template', 'point_type')
+const { listing_status, topic_type, layer_configuration_template, point_type, zt_dt } = toRefs<any>(
+  proxy?.useDict('listing_status', 'topic_type', 'layer_configuration_template', 'point_type', 'zt_dt')
 );
 
+const updateStatus = ref(false);
+const mapListSetting = ref();
 const menuList = ref<MenuVO[]>([]);
 const loading = ref(true);
 const showSearch = ref(true);
@@ -357,6 +384,30 @@ const getTypeList = () => {
     menuTypeList.value = res.data;
   });
 };
+watch(
+  () => queryParams.ZT,
+  (newVal) => {
+    if (newVal) {
+      handleGetLayerList();
+    } else {
+      mapListSetting.value = '';
+    }
+  }
+);
+
+const handleGetLayerList = () => {
+  getLayerDtList({ ZT: queryParams.ZT }).then((res) => {
+    mapListSetting.value = res.data;
+  });
+};
+
+const handleUpdateLayerDtList = () => {
+  updateStatus.value = true;
+  updateLayerDtList(queryParams.ZT, { dt: mapListSetting.value }).finally(() => {
+    updateStatus.value = false;
+  });
+};
+
 onMounted(() => {
   getList();
   getTypeList();