gongchunyi
6 天以前 f0c8e8aaf9f41a7ab0f02a23cd7c5de1bffb9e71
feat: 决策分析数据获取新增轮询
已添加1个文件
已修改11个文件
206 ■■■■ 文件已修改
src/hooks/usePolling.js 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/financialAnalysis/components/center-bottom.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/financialAnalysis/components/center-center.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/financialAnalysis/components/center-top.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/financialAnalysis/components/left-bottom.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/financialAnalysis/components/left-top.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/center-center.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/center-top.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/left-top.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/qualityAnalysis/components/right-top.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/usePolling.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,121 @@
import { onMounted, onBeforeUnmount } from 'vue'
/**
 * æ•°æ®è½®è¯¢ composable
 * @param {Function} fetchFn - æ•°æ®èŽ·å–å‡½æ•°
 * @param {Object} options - é…ç½®é€‰é¡¹
 * @param {number} options.interval - è½®è¯¢é—´éš”(毫秒),默认 60000(60秒)
 * @param {boolean} options.immediate - æ˜¯å¦ç«‹å³æ‰§è¡Œä¸€æ¬¡ï¼Œé»˜è®¤ true
 * @returns {Object} { start, stop, isPolling }
 */
export function usePolling(fetchFn, options = {}) {
  const {
    interval = 60000,
    immediate = true
  } = options
  let pollingTimer = null
  const isPolling = { value: false }
  const start = () => {
    if (pollingTimer) return
    if (immediate) {
      fetchFn()
    }
    pollingTimer = setInterval(() => {
      fetchFn()
    }, interval)
    isPolling.value = true
  }
  const stop = () => {
    if (pollingTimer) {
      clearInterval(pollingTimer)
      pollingTimer = null
    }
    isPolling.value = false
  }
  // ç»„件挂载时自动启动
  onMounted(() => {
    start()
  })
  // ç»„件卸载时自动停止
  onBeforeUnmount(() => {
    stop()
  })
  return {
    start,
    stop,
    isPolling
  }
}
/**
 * å¤šå‡½æ•°è½®è¯¢ composable
 * @param {Function[]} fetchFns - æ•°æ®èŽ·å–å‡½æ•°æ•°ç»„
 * @param {Object} options - é…ç½®é€‰é¡¹
 * @param {number} options.interval - è½®è¯¢é—´éš”(毫秒),默认 60000(60秒)
 * @param {boolean} options.immediate - æ˜¯å¦ç«‹å³æ‰§è¡Œä¸€æ¬¡ï¼Œé»˜è®¤ true
 * @returns {Object} { start, stop, isPolling }
 */
export function usePollingMultiple(fetchFns, options = {}) {
  const {
    interval = 60000,
    immediate = true
  } = options
  let pollingTimer = null
  const isPolling = { value: false }
  const fetchAll = () => {
    fetchFns.forEach(fn => {
      if (typeof fn === 'function') {
        fn()
      }
    })
  }
  const start = () => {
    if (pollingTimer) return
    if (immediate) {
      fetchAll()
    }
    pollingTimer = setInterval(() => {
      fetchAll()
    }, interval)
    isPolling.value = true
  }
  const stop = () => {
    if (pollingTimer) {
      clearInterval(pollingTimer)
      pollingTimer = null
    }
    isPolling.value = false
  }
  // ç»„件挂载时自动启动
  onMounted(() => {
    start()
  })
  // ç»„件卸载时自动停止
  onBeforeUnmount(() => {
    stop()
  })
  return {
    start,
    stop,
    isPolling
  }
}
src/views/reportAnalysis/financialAnalysis/components/center-bottom.vue
@@ -19,10 +19,11 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import PanelHeader from './PanelHeader.vue'
import { profitTrendAnalysis } from '@/api/viewIndex.js'
import { usePolling } from '@/hooks/usePolling.js'
const chartStyle = { width: '100%', height: '150%' }
const grid = { left: '3%', right: '4%', bottom: '3%', top: '4%', containLabel: true }
@@ -85,9 +86,8 @@
    })
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/financialAnalysis/components/center-center.vue
@@ -27,10 +27,11 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import * as echarts from 'echarts'
import Echarts from '@/components/Echarts/echarts.vue'
import { incomeExpenseAnalysis } from '@/api/viewIndex.js'
import { usePolling } from '@/hooks/usePolling.js'
const chartStyle = { width: '100%', height: '100%' }
const grid = {
@@ -144,9 +145,8 @@
    })
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/financialAnalysis/components/center-top.vue
@@ -96,8 +96,9 @@
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { ref } from 'vue'
import { getMonthlyIncome, getMonthlyExpenditure } from '@/api/viewIndex'
import { usePollingMultiple } from '@/hooks/usePolling.js'
const income = ref({
  amount: 0,
@@ -179,10 +180,8 @@
  return Number(metric.trend) >= 0 ? '↑' : '↓'
}
onMounted(() => {
  fetchMonthlyIncome()
  fetchMonthlyExpenditure()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePollingMultiple([fetchMonthlyIncome, fetchMonthlyExpenditure])
</script>
<style scoped>
src/views/reportAnalysis/financialAnalysis/components/left-bottom.vue
@@ -29,12 +29,13 @@
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { ref, onBeforeUnmount, computed } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import PanelHeader from './PanelHeader.vue'
import ProductTypeSwitch from './ProductTypeSwitch.vue'
import { expenseCompositionAnalysis } from '@/api/viewIndex.js'
import { useChartBackground } from '@/hooks/useChartBackground.js'
import { usePolling } from '@/hooks/usePolling.js'
const pieWrapperRef = ref(null)
const pieBackgroundRef = ref(null)
@@ -231,13 +232,15 @@
}
onMounted(() => {
  fetchData()
  initBackground()
})
onBeforeUnmount(() => {
  cleanupBackground()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/financialAnalysis/components/left-top.vue
@@ -19,10 +19,11 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { getAmountHalfYear } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
import Echarts from '@/components/Echarts/echarts.vue'
import { usePolling } from '@/hooks/usePolling.js'
const chartStyle = {
  width: '100%',
@@ -113,9 +114,8 @@
    })
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue
@@ -24,10 +24,11 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { completedInspectionCount } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
import Echarts from '@/components/Echarts/echarts.vue'
import { usePolling } from '@/hooks/usePolling.js'
const chartStyle = {
  width: '100%',
@@ -154,9 +155,8 @@
  fetchData()
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
@@ -25,9 +25,10 @@
</template>
<script setup>
import { computed, getCurrentInstance, ref, onMounted } from 'vue'
import { computed, getCurrentInstance, ref } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import { nonComplianceWarning } from '@/api/viewIndex.js'
import { usePolling } from '@/hooks/usePolling.js'
const { proxy } = getCurrentInstance() || {}
@@ -161,9 +162,8 @@
  // å…ˆæŒ‰æˆªå›¾åšé™æ€â€œè¿‘7天”,后续有真实筛选需求再接入
}
onMounted(() => {
  fetchWarnings()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchWarnings)
</script>
<style scoped>
src/views/reportAnalysis/qualityAnalysis/components/center-top.vue
@@ -20,8 +20,9 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { qualityInspectionCount } from '@/api/viewIndex.js'
import { usePolling } from '@/hooks/usePolling.js'
const statItems = ref([])
@@ -62,9 +63,8 @@
    })
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>
src/views/reportAnalysis/qualityAnalysis/components/left-top.vue
@@ -51,6 +51,7 @@
import PanelHeader from './PanelHeader.vue'
import DateTypeSwitch from './DateTypeSwitch.vue'
import { rawMaterialDetection, processDetection, factoryDetection } from '@/api/viewIndex.js'
import { usePolling } from '@/hooks/usePolling.js'
const QUALIFIED_COLOR = '#4EE4FF'
const UNQUALIFIED_COLOR = '#3378FF'
@@ -218,6 +219,13 @@
    fetchSectionData(section)
  })
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(() => {
  sections.forEach((section) => {
    fetchSectionData(section)
  })
})
</script>
<style scoped lang="scss">
src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
@@ -17,6 +17,7 @@
import PanelHeader from './PanelHeader.vue'
import { unqualifiedProductProcessingAnalysis } from '@/api/viewIndex.js'
import { useChartBackground } from '@/hooks/useChartBackground.js'
import { usePolling } from '@/hooks/usePolling.js'
const pieWrapperRef = ref(null)
const pieBackgroundRef = ref(null)
@@ -149,13 +150,15 @@
}
onMounted(() => {
  loadData()
  initBackground()
})
onBeforeUnmount(() => {
  cleanupBackground()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(loadData)
</script>
<style scoped>
src/views/reportAnalysis/qualityAnalysis/components/right-top.vue
@@ -24,9 +24,10 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { unqualifiedProductRanking } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
import { usePolling } from '@/hooks/usePolling.js'
const panelList = ref([])
@@ -60,9 +61,8 @@
    })
}
onMounted(() => {
  fetchData()
})
// å¯åŠ¨è½®è¯¢ï¼Œæ¯åˆ†é’Ÿåˆ·æ–°ä¸€æ¬¡æ•°æ®
usePolling(fetchData)
</script>
<style scoped>