Przeglądaj źródła

应检设备添加检测类型

yanghao 4 dni temu
rodzic
commit
d681d51946

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

@@ -260,6 +260,9 @@ export const IotStatApi = {
   getRdRecentWbcs: async () => {
     return await request.get({ url: `/rq/stat/recent/wbcs/rd` })
   },
+  getRdNewClassify: async () => {
+    return await request.get({ url: `/rq/stat/new/classify` })
+  },
 
   // 瑞都看板(新)
   // 获取ssoToken

+ 81 - 25
src/views/pms/stat/rdkb/rd-device-category.vue

@@ -1,27 +1,45 @@
 <script lang="ts" setup>
 import * as echarts from 'echarts'
+import { IotStatApi } from '@/api/pms/stat'
 import { ANIMATION, CHART_RENDERER, createTooltip, FONT_FAMILY, THEME } from '@/utils/kb'
 
 interface DeviceCategoryItem {
   name: string
   count: number
+  type: string
+}
+
+interface DeviceCategoryResponseItem {
+  className?: string
+  count?: number | string
+  type?: string
 }
 
 const chartRef = ref<HTMLDivElement>()
+const loading = ref(false)
+const categoryData = ref<DeviceCategoryItem[]>([])
 let chart: echarts.ECharts | null = null
 
-const categoryData: DeviceCategoryItem[] = [
-  { name: '压裂泵车', count: 75 },
-  { name: '连油主车', count: 36 },
-  { name: '其他', count: 35 },
-  { name: '小车', count: 32 },
-  { name: '井控装备', count: 22 },
-  { name: '连油辅助设备', count: 19 },
-  { name: '货车', count: 17 },
-  { name: '四川瑞都设备', count: 16 },
-  { name: '卡车', count: 16 },
-  { name: '供液橇', count: 12 }
-]
+const TOP_BAR_COLOR = new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+  { offset: 0, color: '#ffd166' },
+  { offset: 0.58, color: '#ff9f43' },
+  { offset: 1, color: '#f76707' }
+])
+const DEFAULT_BAR_COLOR = new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+  { offset: 0, color: THEME.color.blue.light },
+  { offset: 0.58, color: THEME.color.blue.mid },
+  { offset: 1, color: THEME.color.blue.line }
+])
+
+function sortCategoryData(data: DeviceCategoryItem[]) {
+  const typeOrder = (type: string) => {
+    if (type === 'top') return 0
+    if (type === '') return 1
+    return 2
+  }
+
+  return data.sort((a, b) => typeOrder(a.type) - typeOrder(b.type))
+}
 
 function getChartLayout() {
   const { clientWidth = 0, clientHeight = 0 } = chartRef.value ?? {}
@@ -44,7 +62,7 @@ function formatValue(value: number) {
 
 function getChartOption(): echarts.EChartsOption {
   const layout = getChartLayout()
-  const values = categoryData.map((item) => item.count)
+  const values = categoryData.value.map((item) => item.count)
   const maxValue = Math.max(...values, 1)
   const xAxisMax = Math.ceil((maxValue * 1.12) / 10) * 10
 
@@ -67,7 +85,7 @@ function getChartOption(): echarts.EChartsOption {
       },
       formatter(params: any[]) {
         const first = params[0]
-        const row = categoryData[first?.dataIndex ?? 0]
+        const row = categoryData.value[first?.dataIndex ?? 0]
         if (!row) return ''
 
         return [
@@ -109,7 +127,7 @@ function getChartOption(): echarts.EChartsOption {
     },
     yAxis: {
       type: 'category',
-      data: categoryData.map((item) => item.name),
+      data: categoryData.value.map((item) => item.name),
       inverse: true,
       axisLine: {
         show: false
@@ -130,7 +148,12 @@ function getChartOption(): echarts.EChartsOption {
       {
         name: '设备数量',
         type: 'bar',
-        data: values,
+        data: categoryData.value.map((item) => ({
+          value: item.count,
+          itemStyle: {
+            color: item.type === 'top' ? TOP_BAR_COLOR : DEFAULT_BAR_COLOR
+          }
+        })),
         barWidth: layout.barWidth,
         showBackground: true,
         backgroundStyle: {
@@ -138,12 +161,7 @@ function getChartOption(): echarts.EChartsOption {
           borderRadius: 999
         },
         itemStyle: {
-          borderRadius: 999,
-          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
-            { offset: 0, color: THEME.color.blue.light },
-            { offset: 0.58, color: THEME.color.blue.mid },
-            { offset: 1, color: THEME.color.blue.line }
-          ])
+          borderRadius: 999
         },
         label: {
           show: true,
@@ -159,8 +177,8 @@ function getChartOption(): echarts.EChartsOption {
         },
         emphasis: {
           itemStyle: {
-            shadowBlur: 16,
-            shadowColor: THEME.color.blue.shadow
+            shadowBlur: 2
+            // shadowColor: THEME.color.blue.shadow
           }
         }
       }
@@ -192,8 +210,33 @@ function destroyChart() {
   chart = null
 }
 
+async function getDeviceCategory() {
+  loading.value = true
+
+  try {
+    const res = await IotStatApi.getRdNewClassify()
+    categoryData.value = Array.isArray(res)
+      ? sortCategoryData(
+          res.map((item: DeviceCategoryResponseItem) => ({
+            name: item.className || '未知',
+            count: Number(item.count ?? 0),
+            type: item.type || ''
+          }))
+        ).slice(0, 10)
+      : []
+    renderChart()
+  } catch (error) {
+    console.error('获取瑞都设备分类失败:', error)
+    categoryData.value = []
+    renderChart()
+  } finally {
+    loading.value = false
+  }
+}
+
 onMounted(() => {
   initChart()
+  getDeviceCategory()
   window.addEventListener('resize', resizeChart)
   window.addEventListener('rdkb:resize', resizeChart)
 })
@@ -214,13 +257,26 @@ onUnmounted(() => {
       </div>
       设备分类
     </div>
-    <div ref="chartRef" class="device-category-chart"></div>
+    <div
+      v-loading="loading"
+      element-loading-text="加载中..."
+      element-loading-background="rgb(222 236 252 / 72%)"
+      class="device-category-body">
+      <div ref="chartRef" class="device-category-chart"></div>
+    </div>
   </div>
 </template>
 
 <style lang="scss" scoped>
 @import url('@/styles/kb.scss');
 
+.device-category-body {
+  display: flex;
+  width: 100%;
+  min-height: 0;
+  flex: 1;
+}
+
 .device-category-chart {
   width: 100%;
   min-height: 0;

+ 37 - 18
src/views/pms/stat/rdkb/rd-use-status.vue

@@ -1,33 +1,26 @@
 <script lang="ts" setup>
 import * as echarts from 'echarts'
 import { ANIMATION, CHART_RENDERER, createTooltip, FONT_FAMILY, THEME } from '@/utils/kb'
+import { IotDeviceApi } from '@/api/pms/device'
 
 interface UseStatusItem {
   name: string
   value: number
 }
 
-const statusData: UseStatusItem[] = [
-  { name: '动迁', value: 0 },
-  { name: '施工', value: 162 },
-  { name: '维修中', value: 4 },
-  { name: '完工', value: 4 },
-  { name: '待维修', value: 2 },
-  { name: '封存', value: 61 },
-  { name: '驻地待命', value: 6 },
-  { name: '待命', value: 16 },
-  { name: '准备', value: 0 },
-  { name: '现场待命', value: 1 },
-  { name: '待保养', value: 0 },
-  { name: '闲置', value: 19 },
-  { name: '观察使用', value: 1 },
-  { name: '报废', value: 0 }
-]
+interface DeviceStatusResponseItem {
+  name?: string
+  category?: string
+  value?: number | string
+}
 
+const RD_DEPT_ID = 163
 const chartRef = ref<HTMLDivElement>()
+const loading = ref(false)
+const statusData = ref<UseStatusItem[]>([])
 let chart: echarts.ECharts | null = null
 
-const chartData = computed(() => statusData.filter((item) => item.value > 0))
+const chartData = computed(() => statusData.value.filter((item) => item.value > 0))
 
 function getChartLayout() {
   const { clientWidth = 0, clientHeight = 0 } = chartRef.value ?? {}
@@ -126,8 +119,30 @@ function destroyChart() {
   chart = null
 }
 
+async function getDeviceStatus() {
+  loading.value = true
+
+  try {
+    const res = await IotDeviceApi.getIotDeviceStatus({ deptId: RD_DEPT_ID })
+    statusData.value = Array.isArray(res)
+      ? res.map((item: DeviceStatusResponseItem) => ({
+          name: item.name || item.category || '未知',
+          value: Number(item.value ?? 0)
+        }))
+      : []
+    renderChart()
+  } catch (error) {
+    console.error('获取瑞都设备使用状态失败:', error)
+    statusData.value = []
+    renderChart()
+  } finally {
+    loading.value = false
+  }
+}
+
 onMounted(() => {
   initChart()
+  getDeviceStatus()
   window.addEventListener('resize', resizeChart)
   window.addEventListener('rdkb:resize', resizeChart)
 })
@@ -148,7 +163,11 @@ onUnmounted(() => {
       </div>
       设备使用状态
     </div>
-    <div class="use-status-body">
+    <div
+      v-loading="loading"
+      element-loading-text="加载中..."
+      element-loading-background="rgb(222 236 252 / 72%)"
+      class="use-status-body">
       <div ref="chartRef" class="use-status-chart"></div>
     </div>
   </div>