Przeglądaj źródła

图例点击取消、修复定时请求bug

Hwf 3 miesięcy temu
rodzic
commit
5f7f6ae935

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

@@ -47,7 +47,6 @@ watch(
 
 // 加载事件
 const load = () => {
-  const that = this;
   if (!myChart.value || Object.keys(myChart.value).length === 0) {
     myChart.value = echarts.init(canvas.value);
   }

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

@@ -27,7 +27,6 @@ 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']
     ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
     ElCol: typeof import('element-plus/es')['ElCol']
@@ -46,32 +45,25 @@ declare module 'vue' {
     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']
     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']
     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']
     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']
-    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
@@ -84,8 +76,6 @@ 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']
-    IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
-    IEpCaretTop: typeof import('~icons/ep/caret-top')['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']

+ 21 - 76
src/views/emergencyCommandMap/RightSection/JointDuty.vue

@@ -34,7 +34,7 @@
         <img :src="qrCodeUrl" alt="" style="width: 300px; height: 300px" />
       </div>
       <div class="flex" style="margin-top: 20px">
-        <div class="common-btn-primary" v-print="printObj">打印</div>
+        <div v-print="printObj" class="common-btn-primary">打印</div>
         <div class="common-btn-primary" @click="handleDownLoad">下载</div>
       </div>
     </div>
@@ -44,20 +44,6 @@
 <script lang="ts" setup>
 import { getCheckinList } from '@/api/emergencyCommandMap/JointDuty';
 const route = useRoute();
-const tableHeader = reactive([
-  {
-    name: '值守单位',
-    key: 'dept_name'
-  },
-  {
-    name: '值守人员',
-    key: 'nick_name'
-  },
-  {
-    name: '联系方式',
-    key: 'phone'
-  }
-]);
 const listData = ref([]);
 let eventId = ref('');
 let qrCodeUrl = ref('');
@@ -70,17 +56,6 @@ const showQrCode = ref(false);
 const handleShowQrCode = () => {
   showQrCode.value = true;
 };
-const base64ToBlob = (code) => {
-  let parts = code.split(';base64,');
-  let contentType = parts[0].split(':')[1];
-  let raw = window.atob(parts[1]);
-  let rawLength = raw.length;
-  let uInt8Array = new Uint8Array(rawLength);
-  for (let i = 0; i < rawLength; ++i) {
-    uInt8Array[i] = raw.charCodeAt(i);
-  }
-  return new Blob([uInt8Array], { type: contentType });
-};
 // 下载
 const handleDownLoad = () => {
   let image = new Image();
@@ -102,66 +77,36 @@ const handleDownLoad = () => {
   };
 };
 
-
 // 设置定时器
 const fetchInterval = process.env.NODE_ENV === 'development' ? 60000 : 1500; // 每60秒刷新一次(刷新太频繁影响调试)
 
-const nextFetchData = ()=> {
-  setTimeout(()=>{
-    getCheckinList(eventId.value).then((res) => {
+let timer;
+let isMounted = ref(false);
+const nextFetchData = () => {
+  getCheckinList(eventId.value)
+    .then((res) => {
       listData.value = res.data;
-      nextFetchData();
+    })
+    .finally(() => {
+      if (isMounted.value) {
+        timer = setTimeout(nextFetchData, fetchInterval);
+      }
     });
-  }, fetchInterval)
 };
 
 onMounted(() => {
   eventId.value = route.query.event_id as string;
-  /*
-  listData.value = [
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    },
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    },
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    },
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    },
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    },
-    {
-      dept_name: '市应急局',
-      nick_name: '张平安',
-      phone: '13856642378',
-      duties: '职务'
-    }
-  ];
-  getCheckinList(eventId.value).then((res) => {
-     listData.value = res.data;
-  });
-  */
-  qrCodeUrl.value = import.meta.env.VITE_APP_BASE_API2 + 'api/qrcode/event/checkin?event_id=' + eventId.value;
+  isMounted.value = true;
   nextFetchData();
+  qrCodeUrl.value = import.meta.env.VITE_APP_BASE_API2 + 'api/qrcode/event/checkin?event_id=' + eventId.value;
+});
+
+onUnmounted(() => {
+  isMounted.value = false;
+  if (!!timer) {
+    clearTimeout(timer);
+    timer = null;
+  }
 });
 </script>
 

+ 26 - 44
src/views/emergencyCommandMap/RightSection/RenWuGenZong.vue

@@ -81,18 +81,22 @@ const showMoreEventManageList = () => {
   eventManageState.showListDialog = true;
 };
 
+let timer;
+let isMounted = ref(false);
 // 请求数据
-const fetchData = async () => {
-  try {
-    console.log('请求任务数据:', props.eventId);
-    const res = await selectTask({ event_code: props.eventId });
-    res.data.forEach((item) => {
-      item.update_time = parseTime(item.update_time);
+const fetchData = (unNeedTimeout?: boolean) => {
+  selectTask({ event_code: props.eventId })
+    .then((res) => {
+      res.data.forEach((item) => {
+        item.update_time = parseTime(item.update_time);
+      });
+      dataList.value = res.data;
+    })
+    .finally(() => {
+      if (isMounted.value && !unNeedTimeout) {
+        timer = setTimeout(fetchData, fetchInterval);
+      }
     });
-    dataList.value = res.data;
-  } catch (error) {
-    console.error('请求任务数据失败:', error);
-  }
 };
 
 const openUpdateDialog = (task) => {
@@ -102,7 +106,7 @@ const openUpdateDialog = (task) => {
 
 const handleUpdateSuccess = (updatedData) => {
   console.log('任务进度更新成功:', updatedData);
-  fetchData(); // 重新加载任务列表
+  fetchData(true); // 重新加载任务列表
 };
 const handleLeaderInstruction = (item) => {
   // 处理领导批示逻辑
@@ -113,53 +117,31 @@ const toggleExpand = (item) => {
   item.isExpanded = !item.isExpanded;
 };
 
-const toggleScroll = () => {
-  showScroll.value = !showScroll.value;
-};
-
 // 设置定时器
 const fetchInterval = process.env.NODE_ENV === 'development' ? 60000 : 3000; // 每60秒刷新一次(刷新太频繁影响调试)
-let intervalId: any | null = null;
-
-const startFetchingData = () => {
-  if (!intervalId) {
-    intervalId = setInterval(() => {
-      fetchData();
-    }, fetchInterval);
-  }
-};
-
-const stopFetchingData = () => {
-  if (intervalId) {
-    clearInterval(intervalId);
-    intervalId = null;
-  }
-};
-
 // 在组件挂载时开始定时获取数据
 onMounted(() => {
-  if (props.eventId) {
-    fetchData();
-    startFetchingData();
-  }
+  isMounted.value = true;
 });
 
 // 在组件卸载时清除定时器
 onUnmounted(() => {
-  stopFetchingData();
+  isMounted.value = false;
+  if (!!timer) {
+    clearTimeout(timer);
+    timer = null;
+  }
 });
-
 watch(
   () => props.eventId,
-  (newValue) => {
-    if (newValue) {
+  () => {
+    if (props.eventId) {
       fetchData();
-      startFetchingData();
-    } else {
-      stopFetchingData();
     }
   },
-  { immediate: true }
+  {
+    immediate: true
+  }
 );
 </script>
 

+ 1 - 2
src/views/emergencyCommandMap/RightSection/RightTop.vue

@@ -48,9 +48,8 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref, reactive } from 'vue';
 import { taskList } from '@/api/duty/eventing';
-import RenWuGenZong from '@/views/emergencyCommandMap/RightSection/RenWuGenZong.vue'; // 确保 eventing.ts 的路径正确
+import RenWuGenZong from './RenWuGenZong.vue';
 
 const props = defineProps<{
   eventId?: string; // 使用可选属性

+ 31 - 8
src/views/globalMap/RightMenu/LayerAnalysis.vue

@@ -21,10 +21,10 @@
       <div class="box2">
         <div class="box2-title">类型统计</div>
         <div class="box2-right">
-          <Chart :option="chartOption2" style="width: 250px; height: 100%" />
+          <Chart ref="chartRef" :option="chartOption2" style="width: 250px; height: 100%" />
           <div class="legend-box">
-            <div v-for="(item, index) in legendData" :key="index" class="legend-item">
-              <span class="dot" :style="{ backgroundColor: getColor(index) }"></span>{{ item.name }}:{{ item.value }}
+            <div v-for="(item, index) in legendData" :key="index" class="legend-item" @click="handleClickLegend(item)">
+              <span class="dot" :style="{ backgroundColor: getColor(item.checked, index) }"></span>{{ item.name }}:{{ item.value }}
             </div>
           </div>
         </div>
@@ -69,14 +69,17 @@ import BigNumber from 'bignumber.js';
 import useMapStore from '@/store/modules/map';
 
 const mapStore = useMapStore();
-let colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
+let chartRef = ref();
+let colorList = ['#00dc98', '#ff3349', '#10b3ff', '#ef9330', '#f6e900', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
 let dataList = ref([]);
 let legendData = ref([]);
 let chartOption1 = reactive(option4);
 let chartOption2 = reactive(option5);
 
-const getColor = (index) => {
-  if (colorList[index]) {
+const getColor = (checked, index) => {
+  if (!checked) {
+    return '#edf2fa';
+  } else if (colorList[index]) {
     return colorList[index];
   } else {
     return '#edf2fa';
@@ -97,6 +100,15 @@ const getOption = (data, key = 'dataType') => {
   return path.toString();
 };
 
+const handleClickLegend = (item) => {
+  item.checked = !item.checked;
+  const newSelected = {};
+  legendData.value.forEach((item) => {
+    newSelected[item.name] = !!item.checked;
+  });
+  chartOption2.legend.selected = newSelected;
+};
+
 watch(
   () => mapStore.pointType,
   () => {
@@ -211,11 +223,21 @@ watch(
         '44': getCountPointInfoTypeErtongfulijigou,
         '45': getCountPointInfoTypeYangLaoJiGou
       };
-      let method = methodList[dataList.value[0].dataType];
+      let dataType = null;
+      for (let i = 0; i < dataList.value.length; i++) {
+        if (dataList.value[i].checked) {
+          dataType = dataList.value[i].dataType;
+          break;
+        }
+      }
+      let method = methodList[dataType];
       if (!method) return;
       method().then((res) => {
         legendData.value = res.rows;
-        chartOption2.legend = { show: false };
+        chartOption2.legend.data = legendData.value;
+        res.rows.forEach((row) => {
+          row.checked = true;
+        });
         chartOption2.series[0].data = res.rows;
       });
     } else {
@@ -318,6 +340,7 @@ const handleClick = (item) => {
         align-items: center;
         margin-bottom: 10px;
         margin-right: 10px;
+        cursor: pointer;
       }
       .dot {
         display: inline-block;

+ 6 - 3
src/views/globalMap/RightMenu/echartOptions.ts

@@ -352,7 +352,7 @@ export const option4 = {
 
 // 类型统计
 export const option5 = {
-  color: ['#00dc98', '#ff3349', '#10b3ff', '#ef9330', '#f6e900'],
+  color: ['#00dc98', '#ff3349', '#10b3ff', '#ef9330', '#f6e900', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
   graphic: {
     elements: [
       {
@@ -382,13 +382,16 @@ export const option5 = {
   tooltip: {
     show: false
   },
-  legend: [],
+  legend: {
+    show: false,
+    selected: {},
+    data: []
+  },
   toolbox: {
     show: false
   },
   series: [
     {
-      name: '',
       type: 'pie',
       clockWise: false,
       center: [120, 110],