Kaynağa Gözat

qhse资料库左侧菜单

yanghao 6 gün önce
ebeveyn
işleme
1cf207528f

+ 3 - 0
src/api/pms/stat/index.ts

@@ -171,6 +171,9 @@ export const IotStatApi = {
   getRhSevenDayUtilization: async () => {
     return await request.get({ url: `/rq/stat/rh/device/sevenDayUtilization` })
   },
+  getRhSixMonthUtilization: async () => {
+    return await request.get({ url: `/rq/stat/rh/device/sixMonthUtilization` })
+  },
   getRdSevenDayUtilization: async () => {
     return await request.get({ url: `/rq/stat/rd/device/sevenDayUtilization` })
   },

+ 13 - 1
src/views/pms/stat/rdkb/rd-rate.vue

@@ -22,6 +22,7 @@ const chartData = ref<ChartData>({
 
 const chartRef = ref<HTMLDivElement>()
 const activeRange = ref<RateRange>('week')
+const loading = ref(false)
 const rangeOptions: Array<{ label: string; value: RateRange }> = [
   { label: '近一周', value: 'week' },
   { label: '近六个月', value: 'sixMonth' }
@@ -203,6 +204,7 @@ function destroyChart() {
 
 async function loadChart(range: RateRange = activeRange.value) {
   const requestId = ++loadRequestId
+  loading.value = true
   try {
     const res =
       range === 'sixMonth'
@@ -226,6 +228,10 @@ async function loadChart(range: RateRange = activeRange.value) {
       series: []
     }
     renderChart()
+  } finally {
+    if (requestId === loadRequestId) {
+      loading.value = false
+    }
   }
 }
 
@@ -263,7 +269,7 @@ onUnmounted(() => {
         size="small"
         class="rate-range-switch" />
     </div>
-    <div ref="chartRef" class="flex-1 min-h-0"></div>
+    <div ref="chartRef" v-loading="loading" class="rate-chart flex-1 min-h-0"></div>
   </div>
 </template>
 
@@ -289,4 +295,10 @@ onUnmounted(() => {
     color: #29527f;
   }
 }
+
+.rate-chart {
+  :deep(.el-loading-mask) {
+    background-color: rgb(221 233 251 / 42%);
+  }
+}
 </style>

+ 71 - 11
src/views/pms/stat/rhkb/equipment-rate.vue

@@ -8,19 +8,29 @@ import {
   createTooltip,
   FONT_FAMILY,
   formatDateLabel,
+  formatMonthLabel,
   THEME
 } from '@/utils/kb'
 import { IotStatApi } from '@/api/pms/stat'
 
+type RateRange = 'week' | 'sixMonth'
+
 const chartData = ref<ChartData>({
   xAxis: [],
   series: []
 })
 
 const chartRef = ref<HTMLDivElement>()
+const activeRange = ref<RateRange>('week')
+const loading = ref(false)
+const rangeOptions: Array<{ label: string; value: RateRange }> = [
+  { label: '近一周', value: 'week' },
+  { label: '近六个月', value: 'sixMonth' }
+]
 let chart: echarts.ECharts | null = null
 const router = useRouter()
 let chartClickBound = false
+let loadRequestId = 0
 
 function formatRate(value: number) {
   return `${Number(value || 0).toFixed(2)}%`
@@ -57,7 +67,7 @@ function getChartOption(data: ChartData): echarts.EChartsOption {
         fontWeight: 500,
         fontFamily: FONT_FAMILY,
         formatter(value: string) {
-          return formatDateLabel(value)
+          return activeRange.value === 'sixMonth' ? formatMonthLabel(value) : formatDateLabel(value)
         }
       }
     },
@@ -152,9 +162,10 @@ function getChartDayRange() {
   const endDate = dayjs(xAxis[xAxis.length - 1])
   if (!startDate.isValid() || !endDate.isValid()) return null
 
+  const rangeUnit = activeRange.value === 'sixMonth' ? 'month' : 'day'
   return [
-    startDate.startOf('day').format('YYYY-MM-DD HH:mm:ss'),
-    endDate.endOf('day').format('YYYY-MM-DD HH:mm:ss')
+    startDate.startOf(rangeUnit).format('YYYY-MM-DD HH:mm:ss'),
+    endDate.endOf(rangeUnit).format('YYYY-MM-DD HH:mm:ss')
   ]
 }
 
@@ -191,9 +202,16 @@ function destroyChart() {
   }
 }
 
-async function loadChart() {
+async function loadChart(range: RateRange = activeRange.value) {
+  const requestId = ++loadRequestId
+  loading.value = true
   try {
-    const res = await IotStatApi.getRhSevenDayUtilization()
+    const res =
+      range === 'sixMonth'
+        ? await IotStatApi.getRhSixMonthUtilization()
+        : await IotStatApi.getRhSevenDayUtilization()
+    if (requestId !== loadRequestId) return
+
     chartData.value = {
       xAxis: res.xAxis || [],
       series: (res.series || []).map((item) => ({
@@ -203,15 +221,24 @@ async function loadChart() {
     }
     renderChart()
   } catch (error) {
+    if (requestId !== loadRequestId) return
     console.error('获取设备利用率失败:', error)
     chartData.value = {
       xAxis: [],
       series: []
     }
     renderChart()
+  } finally {
+    if (requestId === loadRequestId) {
+      loading.value = false
+    }
   }
 }
 
+watch(activeRange, (range) => {
+  loadChart(range)
+})
+
 onMounted(() => {
   initChart()
   loadChart()
@@ -228,17 +255,50 @@ onUnmounted(() => {
 
 <template>
   <div class="panel flex flex-col">
-    <div class="panel-title">
-      <div class="icon-decorator">
-        <span></span>
-        <span></span>
+    <div class="panel-title flex items-center justify-between">
+      <div class="kb-panel-title-text flex items-center">
+        <div class="icon-decorator">
+          <span></span>
+          <span></span>
+        </div>
+        设备利用率
       </div>
-      设备利用率
+      <el-segmented
+        v-model="activeRange"
+        :options="rangeOptions"
+        size="small"
+        class="rate-range-switch" />
     </div>
-    <div ref="chartRef" class="flex-1 min-h-0"></div>
+    <div ref="chartRef" v-loading="loading" class="rate-chart flex-1 min-h-0"></div>
   </div>
 </template>
 
 <style lang="scss" scoped>
 @import url('@/styles/kb.scss');
+
+.rate-range-switch {
+  --el-segmented-item-selected-color: #03409b;
+  --el-segmented-item-selected-bg-color: rgb(255 255 255 / 86%);
+  --el-segmented-bg-color: rgb(31 91 184 / 10%);
+  --el-segmented-item-hover-bg-color: rgb(255 255 255 / 56%);
+
+  min-height: calc(26px * var(--kb-scale, 1));
+  padding: calc(2px * var(--kb-scale, 1));
+  border: 1px solid rgb(31 91 184 / 12%);
+  transform: translateY(calc(-2px * var(--kb-scale, 1)));
+
+  :deep(.el-segmented__item) {
+    min-height: calc(22px * var(--kb-scale, 1));
+    padding: 0 calc(7px * var(--kb-scale, 1));
+    font-size: calc(13px * var(--kb-scale, 1));
+    font-weight: 600;
+    color: #29527f;
+  }
+}
+
+.rate-chart {
+  :deep(.el-loading-mask) {
+    background-color: rgb(221 233 251 / 42%);
+  }
+}
 </style>