Переглянути джерело

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

Hwf 3 місяців тому
батько
коміт
95931315e5

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

@@ -46,7 +46,6 @@ watch(
 
 // 加载事件
 const load = () => {
-  const that = this;
   if (!myChart.value || Object.keys(myChart.value).length === 0) {
     myChart.value = echarts.init(canvas.value);
   }
@@ -85,6 +84,10 @@ const handleClick = (params: any) => {
   props.chartClick(params);
 };
 
+const getMyChart = () => {
+  return myChart.value;
+};
+
 onMounted(() => {
   if (!(JSON.stringify(props.option) === '{}')) {
     load();
@@ -94,6 +97,7 @@ onMounted(() => {
 onUnmounted(() => {
   myChart.value = null;
 });
+defineExpose({ getMyChart });
 </script>
 
 <style lang="scss" scoped>

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

@@ -27,14 +27,14 @@
       </div>
     </div>
   </div>
-  <Dialog :hide-title="false" v-model="showQrCode" title="签到码" type="sm" hide-footer>
+  <Dialog v-model="showQrCode" title="签到码" type="sm" hide-footer>
     <div style="display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100%">
       <div id="qrCodeBox" style="display: flex; flex-direction: column; justify-content: center; align-items: center">
         <div class="print-title" style="margin: 30px 0; color: #ffffff">请联合值守人员通过粤政易/微信扫描二维码进行签到、签退</div>
         <img class="img" :src="qrCodeUrl" alt="" />
       </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('');
@@ -69,17 +55,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();
@@ -103,64 +78,33 @@ 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;
-  });
+  isMounted.value = true;
+  nextFetchData();
   qrCodeUrl.value = import.meta.env.VITE_APP_BASE_API2 + 'api/qrcode/event/checkin?event_id=' + eventId.value;
+});
 
-  nextFetchData();
+onUnmounted(() => {
+  isMounted.value = false;
+  if (!!timer) {
+    clearTimeout(timer);
+    timer = null;
+  }
 });
 </script>
 

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

@@ -78,18 +78,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) => {
@@ -100,7 +104,7 @@ const openUpdateDialog = (task) => {
 
 const handleUpdateSuccess = (updatedData) => {
   console.log('任务进度更新成功:', updatedData);
-  fetchData(); // 重新加载任务列表
+  fetchData(true); // 重新加载任务列表
 };
 const handleLeaderInstruction = (item) => {
   // 处理领导批示逻辑
@@ -113,47 +117,30 @@ const toggleExpand = (item) => {
 
 // 设置定时器
 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>
 

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

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

+ 1 - 1
src/views/emergencyCommandMap/RightSection/ShiJianJieBaoInfo.vue

@@ -32,7 +32,7 @@
 
 <script lang="ts" setup>
 import { ref, reactive } from 'vue';
-import { getEventBriefingList, selectTask } from '@/api/emergencyCommandMap/JointDuty';
+import { getEventBriefingList } from '@/api/emergencyCommandMap/JointDuty';
 
 const taskList = ref([]);
 const total = ref(0);

+ 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: 500px; height: 100%" />
+          <Chart ref="chartRef" :option="chartOption2" style="width: 500px; 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 {
@@ -322,6 +344,7 @@ const handleClick = (item) => {
         align-items: center;
         margin-bottom: 20px;
         margin-right: 20px;
+        cursor: pointer;
       }
       .dot {
         display: inline-block;

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

@@ -348,7 +348,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: [
       {
@@ -378,13 +378,16 @@ export const option5 = {
   tooltip: {
     show: false
   },
-  legend: [],
+  legend: {
+    show: false,
+    selected: {},
+    data: []
+  },
   toolbox: {
     show: false
   },
   series: [
     {
-      name: '',
       type: 'pie',
       clockWise: false,
       center: [254, 158],