learshaw 5 月之前
父节点
当前提交
630401fe1c

+ 10 - 1
ems-ui-cloud/src/api/screen/index.js

@@ -34,14 +34,23 @@ export function pgSupplyMonthTotalPg(query) {
   });
 }
 
+// 1. 修改现有的 pgSupplyHourTotalPv 函数,指向新的 summary 接口
 export function pgSupplyHourTotalPv(query) {
   return request({
-    url: '/ems/pg/supply/hour/hour/pv',
+    url: '/ems/prod/pv/hour/summary',  // 新接口地址
     method: 'get',
     params: query,
   });
 }
 
+// 2. 新增一个函数用于获取小时和日列表数据
+export function pgSupplyHourList(query) {
+  return request({
+    url: '/ems/prod/pv/hour/list',
+    method: 'get',
+    params: query,
+  });
+}
 
 export function ecoDateRange(query) {
   return request({

文件差异内容过多而无法显示
+ 427 - 232
ems-ui-cloud/src/views/adapter/dljk/index.vue


+ 20 - 6
ems-ui-cloud/src/views/adapter/zm/index.vue

@@ -210,8 +210,8 @@
                               {{ getConcentratorAttr(props.row.deviceCode, 'deviceModelId', 'Base') || '-' }}
                             </el-descriptions-item>
                             <el-descriptions-item label="设备状态">
-                              <el-tag size="small" :type="getConcentratorAttr(props.row.deviceCode, 'deviceStatus', 'Base') === '0' ? 'success' : 'danger'">
-                                {{ getConcentratorAttr(props.row.deviceCode, 'deviceStatus', 'Base') === '0' ? '正常' : '异常' }}
+                              <el-tag size="small" :type="getConcentratorAttr(props.row.deviceCode, 'deviceStatus', 'Base') === '1' ? 'success' : 'danger'">
+                                {{ getConcentratorAttr(props.row.deviceCode, 'deviceStatus', 'Base') === '1' ? '正常' : '异常' }}
                               </el-tag>
                             </el-descriptions-item>
                             <el-descriptions-item label="信号强度">
@@ -727,8 +727,8 @@
                       </el-table-column>
                       <el-table-column label="设备状态" width="100" align="center">
                         <template slot-scope="scope">
-                          <el-tag size="small" :type="getLampGroupAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? 'success' : 'danger'">
-                            {{ getLampGroupAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? '正常' : '异常' }}
+                          <el-tag size="small" :type="getLampGroupAttrValue(scope.row.deviceCode, 'deviceStatus') === '1' ? 'success' : 'danger'">
+                            {{ getLampGroupAttrValue(scope.row.deviceCode, 'deviceStatus') === '1' ? '正常' : '异常' }}
                           </el-tag>
                         </template>
                       </el-table-column>
@@ -791,6 +791,11 @@
                   <el-tag type="success" size="small">{{ getOnlineLampGroupCount(scope.row.deviceCode) }}</el-tag>
                 </template>
               </el-table-column>
+              <el-table-column label="开启灯组" width="90" align="center">
+                <template slot-scope="scope">
+                  <el-tag type="success" size="small">{{ getOnSwitchLampGroupCount(scope.row.deviceCode) }}</el-tag>
+                </template>
+              </el-table-column>
               <el-table-column label="设备状态" width="90" align="center">
                 <template slot-scope="scope">
                   <el-tag :type="scope.row.deviceStatus === 1 ? 'success' : 'info'" size="small">
@@ -2078,7 +2083,16 @@ export default {
       const lampGroups = this.getLampGroupList(poleCode)
       return lampGroups.filter(lamp => {
         const deviceStatus = this.getLampGroupAttrValue(lamp.deviceCode, 'deviceStatus')
-        return deviceStatus === '0'
+        return deviceStatus === '1'
+      }).length
+    },
+
+    // 获取灯杆下的在线灯组数量
+    getOnSwitchLampGroupCount(poleCode) {
+      const lampGroups = this.getLampGroupList(poleCode)
+      return lampGroups.filter(lamp => {
+        const deviceStatus = this.getLampGroupAttrValue(lamp.deviceCode, 'Switch')
+        return deviceStatus === '1'
       }).length
     },
 
@@ -2087,7 +2101,7 @@ export default {
       this.totalLampCount = this.lampGroupList.length
       this.onlineLampCount = this.lampGroupList.filter(lamp => {
         const deviceStatus = this.getLampGroupAttrValue(lamp.deviceCode, 'deviceStatus')
-        return deviceStatus === '0'
+        return deviceStatus === '1'
       }).length
 
       // 统计开启的灯组和总功率

+ 144 - 26
ems-ui-cloud/src/views/basecfg/device/index.vue

@@ -695,25 +695,27 @@
 
                   <el-table-column prop="deviceCode" label="设备代码" min-width="180"></el-table-column>
 
+                  <!-- 优化后的设备状态列 -->
                   <el-table-column label="设备状态" width="100" align="center">
                     <template slot-scope="scope">
-                      <el-tag size="small"
-                              :type="getSubDeviceAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? 'success' : 'danger'"
+                      <el-tag
+                        size="small"
+                        :type="getEnumTagType(scope.row.deviceCode, 'deviceStatus', 'success', 'danger')"
                       >
-                        {{ getSubDeviceAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? '正常' : '异常' }}
+                        {{ getSubDeviceAttrEnumDisplay(scope.row.deviceCode, 'deviceStatus') }}
                       </el-tag>
                     </template>
                   </el-table-column>
 
+                  <!-- 优化后的开关状态列 -->
                   <el-table-column label="开关状态" width="100" align="center">
                     <template slot-scope="scope">
-                      <el-tag size="small"
-                              :type="getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? 'success' : 'info'"
+                      <el-tag
+                        size="small"
+                        :type="getEnumTagType(scope.row.deviceCode, 'Switch', 'success', 'info')"
                       >
-                        <i
-                          :class="getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? 'el-icon-sunny' : 'el-icon-moon'"
-                        ></i>
-                        {{ getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? '开启' : '关闭' }}
+                        <i :class="getEnumIcon(scope.row.deviceCode, 'Switch', 'el-icon-sunny', 'el-icon-moon')"></i>
+                        {{ getSubDeviceAttrEnumDisplay(scope.row.deviceCode, 'Switch') }}
                       </el-tag>
                     </template>
                   </el-table-column>
@@ -983,7 +985,7 @@ import { areaTreeSelect } from '@/api/basecfg/area'
 import { getFacsCategorygetByCode, listAllFacs } from '@/api/basecfg/emsfacs'
 import { listSubsystemAll } from '@/api/adapter/subsystem'
 import { getModelByCode, listAllModel } from '@/api/basecfg/objModel'
-import { getObjAttr } from '@/api/basecfg/objAttribute'
+import { getObjAttr, getObjAttrBatch } from '@/api/basecfg/objAttribute'
 import { addAttrValueBatch } from '@/api/basecfg/objAttributeValue'
 import { getDevProcess } from '@/api/commonApi'
 import { addComponent, delComponent, getComponent, listByDevice, updateComponent } from '@/api/basecfg/component'
@@ -1280,39 +1282,40 @@ export default {
      */
     async loadSubDevices(subDevValue) {
       this.loadingSubDevices = true
-
       try {
-        // 解析子设备列表
         const subDevList = JSON.parse(subDevValue)
-
         if (!Array.isArray(subDevList) || subDevList.length === 0) {
           this.hasSubDevices = false
           return
         }
 
-        // 初始化子设备列表(添加展开状态控制)
         this.subDeviceList = subDevList.map(item => ({
           deviceCode: item.deviceCode,
           modelCode: item.modelCode,
           detailTab: 'attrs'
         }))
 
-        // 批量加载所有子设备的物模型(去重)
+        // 1. 加载所有唯一的模型定义
         const uniqueModelCodes = [...new Set(subDevList.map(item => item.modelCode))]
-        await Promise.all(
-          uniqueModelCodes.map(modelCode => this.loadSubDeviceModel(modelCode))
-        )
+        await Promise.all(uniqueModelCodes.map(modelCode => this.loadSubDeviceModel(modelCode)))
+
+        // 2. 按模型分组子设备
+        const devicesByModel = {}
+        subDevList.forEach(item => {
+          if (!devicesByModel[item.modelCode]) {
+            devicesByModel[item.modelCode] = []
+          }
+          devicesByModel[item.modelCode].push(item.deviceCode)
+        })
 
-        // 批量加载所有子设备的属性值
+        // 3. 批量加载每个模型的所有设备属性
         await Promise.all(
-          subDevList.map(item => this.loadSubDeviceAttr(item.deviceCode, item.modelCode))
+          Object.entries(devicesByModel).map(([modelCode, deviceCodes]) =>
+            this.loadSubDeviceAttrBatch(modelCode, deviceCodes)
+          )
         )
 
-        console.log('子设备加载完成:', {
-          count: this.subDeviceList.length,
-          models: Object.keys(this.subDeviceModels),
-          devices: Object.keys(this.subDeviceAttrs)
-        })
+        console.log('子设备属性批量加载完成', this.subDeviceAttrs)
       } catch (error) {
         console.error('加载子设备失败:', error)
         this.$message.error('加载子设备失败:' + error.message)
@@ -1323,6 +1326,49 @@ export default {
     },
 
     /**
+     * 批量加载子设备属性(新方法)
+     * @param {String} modelCode - 模型代码
+     * @param {Array} deviceCodes - 设备代码数组
+     */
+    async loadSubDeviceAttrBatch(modelCode, deviceCodes) {
+      try {
+        const res = await getObjAttrBatch(2, modelCode)
+
+        if (res.data) {
+          // 将批量返回的数据按设备代码分配到 subDeviceAttrs
+          deviceCodes.forEach(deviceCode => {
+            if (res.data[deviceCode]) {
+              this.$set(this.subDeviceAttrs, deviceCode, res.data[deviceCode])
+            } else {
+              console.warn(`设备 ${deviceCode} 未返回属性数据`)
+              // 初始化空数据结构
+              this.$set(this.subDeviceAttrs, deviceCode, {
+                Base: [],
+                State: [],
+                Measure: [],
+                Protocol: []
+              })
+            }
+          })
+        }
+
+        return res.data
+      } catch (error) {
+        console.error(`批量加载子设备属性失败(${modelCode}):`, error)
+        // 失败时初始化空数据
+        deviceCodes.forEach(deviceCode => {
+          this.$set(this.subDeviceAttrs, deviceCode, {
+            Base: [],
+            State: [],
+            Measure: [],
+            Protocol: []
+          })
+        })
+        throw error
+      }
+    },
+
+    /**
      * 加载子设备物模型定义
      */
     async loadSubDeviceModel(modelCode) {
@@ -1386,6 +1432,78 @@ export default {
     },
 
     /**
+     * 获取枚举值的显示名称
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @returns {String} 枚举显示名称
+     */
+    getSubDeviceAttrEnumDisplay(deviceCode, attrKey) {
+      const device = this.subDeviceList.find(d => d.deviceCode === deviceCode)
+      if (!device) return '-'
+
+      const model = this.subDeviceModels[device.modelCode]
+      if (!model || !model.attrList) return '-'
+
+      // 查找属性定义
+      const attrDef = model.attrList.find(attr => attr.attrKey === attrKey)
+      if (!attrDef || attrDef.attrValueType !== 'Enum') {
+        return this.getSubDeviceAttrValue(deviceCode, attrKey) || '-'
+      }
+
+      // 获取当前值
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return '-'
+
+      // 从枚举定义中查找对应的显示名称
+      if (attrDef.valueEnums && Array.isArray(attrDef.valueEnums)) {
+        const enumItem = attrDef.valueEnums.find(e => {
+          // 处理数值比较(去除可能的小数点后的0)
+          const enumValue = String(e.attrValue).replace(/\.0+$/, '')
+          const currentVal = String(currentValue).replace(/\.0+$/, '')
+          return enumValue === currentVal
+        })
+        if (enumItem) {
+          return enumItem.attrValueName || currentValue
+        }
+      }
+
+      return currentValue
+    },
+
+    /**
+     * 根据枚举值获取Tag类型(用于el-tag的type属性)
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @param {String} positiveType - 正向值的类型(如'success')
+     * @param {String} negativeType - 负向值的类型(如'danger')
+     * @returns {String} Tag类型
+     */
+    getEnumTagType(deviceCode, attrKey, positiveType = 'success', negativeType = 'info') {
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return negativeType
+
+      // 去除小数点后的0进行比较
+      const normalizedValue = String(currentValue).replace(/\.0+$/, '')
+      return normalizedValue === '1' ? positiveType : negativeType
+    },
+
+    /**
+     * 根据枚举值获取图标类名
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @param {String} positiveIcon - 正向值的图标
+     * @param {String} negativeIcon - 负向值的图标
+     * @returns {String} 图标类名
+     */
+    getEnumIcon(deviceCode, attrKey, positiveIcon, negativeIcon) {
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return negativeIcon
+
+      const normalizedValue = String(currentValue).replace(/\.0+$/, '')
+      return normalizedValue === '1' ? positiveIcon : negativeIcon
+    },
+
+    /**
      * 获取子设备枚举属性的显示名称
      */
     getSubDeviceAttrEnumName(deviceCode, attrKey, valueEnums) {
@@ -1417,7 +1535,7 @@ export default {
     getOnlineSubDeviceCount() {
       return this.subDeviceList.filter(device => {
         const deviceStatus = this.getSubDeviceAttrValue(device.deviceCode, 'deviceStatus')
-        return deviceStatus === '0'
+        return deviceStatus === '1'
       }).length
     },
 

+ 169 - 15
ems-ui-cloud/src/views/devmgr/device/index.vue

@@ -438,17 +438,24 @@
 
                   <el-table-column label="设备状态" width="100" align="center">
                     <template slot-scope="scope">
-                      <el-tag size="small" :type="getSubDeviceAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? 'success' : 'danger'">
-                        {{ getSubDeviceAttrValue(scope.row.deviceCode, 'deviceStatus') === '0' ? '正常' : '异常' }}
+                      <el-tag
+                        size="small"
+                        :type="getEnumTagType(scope.row.deviceCode, 'deviceStatus', 'success', 'danger')"
+                      >
+                        {{ getSubDeviceAttrEnumDisplay(scope.row.deviceCode, 'deviceStatus') }}
                       </el-tag>
                     </template>
                   </el-table-column>
 
+                  <!-- 优化后的开关状态列 -->
                   <el-table-column label="开关状态" width="100" align="center">
                     <template slot-scope="scope">
-                      <el-tag size="small" :type="getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? 'success' : 'info'">
-                        <i :class="getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? 'el-icon-sunny' : 'el-icon-moon'"></i>
-                        {{ getSubDeviceAttrValue(scope.row.deviceCode, 'Switch') === '1' ? '开启' : '关闭' }}
+                      <el-tag
+                        size="small"
+                        :type="getEnumTagType(scope.row.deviceCode, 'Switch', 'success', 'info')"
+                      >
+                        <i :class="getEnumIcon(scope.row.deviceCode, 'Switch', 'el-icon-sunny', 'el-icon-moon')"></i>
+                        {{ getSubDeviceAttrEnumDisplay(scope.row.deviceCode, 'Switch') }}
                       </el-tag>
                     </template>
                   </el-table-column>
@@ -726,7 +733,7 @@ import { areaTreeSelect } from '@/api/basecfg/area'
 import { getFacsCategorygetByCode, listAllFacs } from '@/api/basecfg/emsfacs'
 import { listSubsystemAll } from '@/api/adapter/subsystem'
 import { getModelByCode } from '@/api/basecfg/objModel'
-import { getObjAttr } from '@/api/basecfg/objAttribute'
+import { getObjAttr, getObjAttrBatch } from '@/api/basecfg/objAttribute'
 import Treeselect from '@riophae/vue-treeselect'
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import { callAbility } from '@/api/basecfg/objAbility'
@@ -933,9 +940,27 @@ export default {
           detailTab: 'attrs'
         }))
 
+        // 1. 加载所有唯一的模型定义
         const uniqueModelCodes = [...new Set(subDevList.map(item => item.modelCode))]
         await Promise.all(uniqueModelCodes.map(modelCode => this.loadSubDeviceModel(modelCode)))
-        await Promise.all(subDevList.map(item => this.loadSubDeviceAttr(item.deviceCode, item.modelCode)))
+
+        // 2. 按模型分组子设备
+        const devicesByModel = {}
+        subDevList.forEach(item => {
+          if (!devicesByModel[item.modelCode]) {
+            devicesByModel[item.modelCode] = []
+          }
+          devicesByModel[item.modelCode].push(item.deviceCode)
+        })
+
+        // 3. 批量加载每个模型的所有设备属性
+        await Promise.all(
+          Object.entries(devicesByModel).map(([modelCode, deviceCodes]) =>
+            this.loadSubDeviceAttrBatch(modelCode, deviceCodes)
+          )
+        )
+
+        console.log('子设备属性批量加载完成', this.subDeviceAttrs)
       } catch (error) {
         console.error('加载子设备失败:', error)
         this.$message.error('加载子设备失败:' + error.message)
@@ -945,6 +970,49 @@ export default {
       }
     },
 
+    /**
+     * 批量加载子设备属性(新方法)
+     * @param {String} modelCode - 模型代码
+     * @param {Array} deviceCodes - 设备代码数组
+     */
+    async loadSubDeviceAttrBatch(modelCode, deviceCodes) {
+      try {
+        const res = await getObjAttrBatch(2, modelCode)
+
+        if (res.data) {
+          // 将批量返回的数据按设备代码分配到 subDeviceAttrs
+          deviceCodes.forEach(deviceCode => {
+            if (res.data[deviceCode]) {
+              this.$set(this.subDeviceAttrs, deviceCode, res.data[deviceCode])
+            } else {
+              console.warn(`设备 ${deviceCode} 未返回属性数据`)
+              // 初始化空数据结构
+              this.$set(this.subDeviceAttrs, deviceCode, {
+                Base: [],
+                State: [],
+                Measure: [],
+                Protocol: []
+              })
+            }
+          })
+        }
+
+        return res.data
+      } catch (error) {
+        console.error(`批量加载子设备属性失败(${modelCode}):`, error)
+        // 失败时初始化空数据
+        deviceCodes.forEach(deviceCode => {
+          this.$set(this.subDeviceAttrs, deviceCode, {
+            Base: [],
+            State: [],
+            Measure: [],
+            Protocol: []
+          })
+        })
+        throw error
+      }
+    },
+
     async loadSubDeviceModel(modelCode) {
       if (this.subDeviceModels[modelCode]) {
         return this.subDeviceModels[modelCode]
@@ -978,6 +1046,99 @@ export default {
       return model.attrList.filter(attr => attr.attrGroup === attrGroup)
     },
 
+    /**
+     * 获取枚举值的显示名称
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @returns {String} 枚举显示名称
+     */
+    getSubDeviceAttrEnumDisplay(deviceCode, attrKey) {
+      const device = this.subDeviceList.find(d => d.deviceCode === deviceCode)
+      if (!device) return '-'
+
+      const model = this.subDeviceModels[device.modelCode]
+      if (!model || !model.attrList) return '-'
+
+      // 查找属性定义
+      const attrDef = model.attrList.find(attr => attr.attrKey === attrKey)
+      if (!attrDef || attrDef.attrValueType !== 'Enum') {
+        return this.getSubDeviceAttrValue(deviceCode, attrKey) || '-'
+      }
+
+      // 获取当前值
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return '-'
+
+      // 从枚举定义中查找对应的显示名称
+      if (attrDef.valueEnums && Array.isArray(attrDef.valueEnums)) {
+        const enumItem = attrDef.valueEnums.find(e => {
+          // 处理数值比较(去除可能的小数点后的0)
+          const enumValue = String(e.attrValue)
+          const currentVal = String(currentValue)
+          return enumValue === currentVal
+        })
+        if (enumItem) {
+          return enumItem.attrValueName || currentValue
+        }
+      }
+
+      return currentValue
+    },
+
+    /**
+     * 根据枚举值获取Tag类型(用于el-tag的type属性)
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @param {String} positiveType - 正向值的类型(如'success')
+     * @param {String} negativeType - 负向值的类型(如'danger')
+     * @returns {String} Tag类型
+     */
+    getEnumTagType(deviceCode, attrKey, positiveType = 'success', negativeType = 'info') {
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return negativeType
+
+      // 去除小数点后的0进行比较
+      const normalizedValue = String(currentValue).replace(/\.0+$/, '')
+      return normalizedValue === '1' ? positiveType : negativeType
+    },
+
+    /**
+     * 根据枚举值获取图标类名
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @param {String} positiveIcon - 正向值的图标
+     * @param {String} negativeIcon - 负向值的图标
+     * @returns {String} 图标类名
+     */
+    getEnumIcon(deviceCode, attrKey, positiveIcon, negativeIcon) {
+      const currentValue = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!currentValue) return negativeIcon
+
+      const normalizedValue = String(currentValue).replace(/\.0+$/, '')
+      return normalizedValue === '1' ? positiveIcon : negativeIcon
+    },
+
+    /**
+     * 通用枚举值名称获取方法(兼容旧方法)
+     * @param {String} deviceCode - 设备代码
+     * @param {String} attrKey - 属性键
+     * @param {Array} valueEnums - 枚举定义数组
+     * @returns {String} 枚举显示名称
+     */
+    getSubDeviceAttrEnumName(deviceCode, attrKey, valueEnums) {
+      const value = this.getSubDeviceAttrValue(deviceCode, attrKey)
+      if (!value) return '-'
+      if (!valueEnums || !Array.isArray(valueEnums)) return value
+
+      const normalizedValue = String(value).replace(/\.0+$/, '')
+      const enumItem = valueEnums.find(e => {
+        const enumValue = String(e.attrValue).replace(/\.0+$/, '')
+        return enumValue === normalizedValue
+      })
+
+      return enumItem ? enumItem.attrValueName : value
+    },
+
     getSubDeviceAttrValue(deviceCode, attrKey) {
       const attrs = this.subDeviceAttrs[deviceCode]
       if (!attrs) return null
@@ -990,13 +1151,6 @@ export default {
       return null
     },
 
-    getSubDeviceAttrEnumName(deviceCode, attrKey, valueEnums) {
-      const value = this.getSubDeviceAttrValue(deviceCode, attrKey)
-      if (!value || !valueEnums) return value || '-'
-      const enumItem = valueEnums.find(e => e.attrValue === value)
-      return enumItem ? enumItem.attrValueName : value
-    },
-
     getSubDeviceUpdateTime(deviceCode) {
       const attrs = this.subDeviceAttrs[deviceCode]
       if (!attrs) return null
@@ -1010,7 +1164,7 @@ export default {
     getOnlineSubDeviceCount() {
       return this.subDeviceList.filter(device => {
         const deviceStatus = this.getSubDeviceAttrValue(device.deviceCode, 'deviceStatus')
-        return deviceStatus === '0'
+        return deviceStatus === '1'
       }).length
     },
 

+ 172 - 146
ems-ui-cloud/src/views/largeScreen/source/left.vue

@@ -26,13 +26,14 @@
     </CusModule>
   </div>
 </template>
+
 <script>
 import CusModule from '../components/CusModule.vue';
 import BaseChart from '@/components/BaseChart/index.vue'
 import {copyObj, numToStr} from '@/utils';
 import {mapState} from 'vuex';
 import * as echarts from 'echarts'
-import {pgSupplyDayTotalPv, pgSupplyHourTotalPv, pgSupplyTotalPv} from "@/api/screen";
+import {pgSupplyHourList, pgSupplyHourTotalPv} from "@/api/screen";
 import {DateTool} from "@/utils/DateTool";
 
 const option = {
@@ -64,11 +65,12 @@ const option = {
     }
   },
 }
+
 export default {
   name: 'SourceLeft',
   data() {
     return {
-      todayEnergy: '321',
+      todayEnergy: '0',
       elecList: [
         {
           name: "本月发电量",
@@ -89,28 +91,6 @@ export default {
           image: require("@/assets/images/source/l1-item3.png"),
         },
       ],
-      elecIndexList: [
-        {
-          name: "逆变器输入电量",
-          value: 120,
-          unit: "kW",
-        },
-        {
-          name: "逆变器转换效率",
-          value: 86.3,
-          unit: "%",
-        },
-        {
-          name: "光电转换效率",
-          value: 82.1,
-          unit: "%",
-        },
-        {
-          name: "电站性能比",
-          value: 78.09,
-          unit: "",
-        },
-      ],
       lineData: [],
       realtimeLineData: []
     };
@@ -142,7 +122,7 @@ export default {
             smooth: true,
             lineStyle: {
               normal: {
-                color: "#80DBE1", // 线条颜色
+                color: "#80DBE1",
               },
             },
             itemStyle: {
@@ -150,9 +130,8 @@ export default {
               borderColor: "#fff",
               borderWidth: 3
             },
-            areaStyle: { //区域填充样式
+            areaStyle: {
               normal: {
-                //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
                 color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                   offset: 0,
                   color: "rgba(81, 139, 152,0.8)"
@@ -162,8 +141,8 @@ export default {
                     color: "rgba(81, 139, 152, 0)"
                   }
                 ], false),
-                shadowColor: 'rgba(81, 139, 152, 0.5)', //阴影颜色
-                shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
+                shadowColor: 'rgba(81, 139, 152, 0.5)',
+                shadowBlur: 20
               }
             },
             data: this.lineData.map(item => item.yData),
@@ -192,7 +171,7 @@ export default {
             smooth: true,
             lineStyle: {
               normal: {
-                color: "#80DBE1", // 线条颜色
+                color: "#80DBE1",
               },
             },
             itemStyle: {
@@ -200,9 +179,8 @@ export default {
               borderColor: "#fff",
               borderWidth: 3
             },
-            areaStyle: { //区域填充样式
+            areaStyle: {
               normal: {
-                //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
                 color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                   offset: 0,
                   color: "rgba(81, 139, 152,0.8)"
@@ -212,8 +190,8 @@ export default {
                     color: "rgba(81, 139, 152, 0)"
                   }
                 ], false),
-                shadowColor: 'rgba(81, 139, 152, 0.5)', //阴影颜色
-                shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
+                shadowColor: 'rgba(81, 139, 152, 0.5)',
+                shadowBlur: 20
               }
             },
             data: this.realtimeLineData.map(item => item.yData),
@@ -243,89 +221,182 @@ export default {
       this.getPgPvRealTimeSupply()
       this.getHisPgPvSupply()
     },
+
+    /**
+     * 获取光伏汇总数据(今日、本月、今年、累计)
+     */
     async getPgSupply() {
-      const {data: pgPvSupplyTotalPv} = await pgSupplyTotalPv({
-        areaCode: this.areaType
-      })
-      if (!pgPvSupplyTotalPv) {
-        return
+      try {
+        const todayStr = DateTool.now(DateTool.DateFormat.YYYY_MM_DD)
+        const monthStart = DateTool.now(DateTool.DateFormat.YYYY_MM) + '-01'
+        const yearStart = DateTool.now(DateTool.DateFormat.YYYY) + '-01-01'
+
+        // 并发请求所有汇总数据
+        const [todayRes, monthRes, yearRes, totalRes] = await Promise.all([
+          // 今日发电量
+          pgSupplyHourTotalPv({
+            areaCode: this.areaType,
+            date: todayStr
+          }),
+          // 本月发电量
+          pgSupplyHourTotalPv({
+            areaCode: this.areaType,
+            startRecTime: monthStart,
+            endRecTime: todayStr
+          }),
+          // 今年发电量
+          pgSupplyHourTotalPv({
+            areaCode: this.areaType,
+            startRecTime: yearStart,
+            endRecTime: todayStr
+          }),
+          // 累计发电量
+          pgSupplyHourTotalPv({
+            areaCode: this.areaType
+          })
+        ])
+
+        // 更新今日发电量
+        if (todayRes?.data) {
+          this.todayEnergy = numToStr(todayRes.data.genElecQuantity || 0)
+        }
+
+        // 更新统计卡片
+        const [monthPv, yearPv, totalPv] = this.elecList
+        monthPv.value = numToStr(monthRes?.data?.genElecQuantity || 0)
+        yearPv.value = numToStr(yearRes?.data?.genElecQuantity || 0)
+        totalPv.value = numToStr(totalRes?.data?.genElecQuantity || 0)
+
+      } catch (error) {
+        console.error('获取光伏汇总数据失败:', error)
       }
-      const {
-        thisDay,
-        thisMonth,
-        thisYear,
-        total
-      } = pgPvSupplyTotalPv
-      const [monthPv, yearPv, totalPv] = this.elecList
-      this.todayEnergy = numToStr(thisDay.genElecQuantity)
-      monthPv.value = numToStr(thisMonth.genElecQuantity)
-      yearPv.value = numToStr(thisYear.genElecQuantity)
-      totalPv.value = numToStr(total.genElecQuantity)
     },
+
+    /**
+     * 获取今日实时小时数据
+     */
     async getPgPvRealTimeSupply() {
-      const {data: pgPvRealtimeSupply} = await pgSupplyHourTotalPv({
-        areaCode: this.areaType,
-        date: DateTool.now(DateTool.DateFormat.YYYY_MM_DD)
-      })
-      if (!pgPvRealtimeSupply) {
-        return
-      }
-      const timeIndex = DateTool.getTime(60);
-      const timeIndexMap = {}
-      pgPvRealtimeSupply.forEach(item => {
-        timeIndexMap[item.timeIndex] = item
-      })
-      const lineData = []
-      timeIndex.forEach((item, index) => {
-        if (timeIndexMap[index + 1]) {
-          lineData.push({
-            xData: item,
-            yData: timeIndexMap[index + 1].genElecQuantity
-          })
-        } else {
+      try {
+        const {data, rows} = await pgSupplyHourList({
+          areaCode: this.areaType,
+          date: DateTool.now(DateTool.DateFormat.YYYY_MM_DD),
+          timeDimension: 'hour',  // 关键参数:按小时维度查询
+          pageNum: 1,
+          pageSize: 24,  // 一天24小时
+          orderFlag: 'asc'  // 升序排列
+        })
+
+        // 兼容两种返回格式
+        const hourlyData = rows || data || []
+
+        if (!Array.isArray(hourlyData) || hourlyData.length === 0) {
+          console.warn('实时小时数据为空')
+          this.realtimeLineData = this.getEmptyHourData()
+          return
+        }
+
+        // 构建小时索引映射
+        const timeIndexMap = {}
+        hourlyData.forEach(item => {
+          if (item.timeIndex) {
+            timeIndexMap[item.timeIndex] = item
+          }
+        })
+
+        // 生成24小时完整数据
+        const timeLabels = DateTool.getTime(60) // 获取24小时的时间标签
+        const lineData = []
+
+        timeLabels.forEach((timeLabel, index) => {
+          const hourIndex = index + 1  // timeIndex 从1开始
+          const hourData = timeIndexMap[hourIndex]
+
           lineData.push({
-            xData: item,
-            yData: 0
+            xData: timeLabel,
+            yData: hourData ? (hourData.genElecQuantity || 0) : 0
           })
-        }
-      })
-      this.realtimeLineData = lineData
+        })
+
+        this.realtimeLineData = lineData
+
+      } catch (error) {
+        console.error('获取实时发电数据失败:', error)
+        this.realtimeLineData = this.getEmptyHourData()
+      }
     },
+
+    /**
+     * 获取历史发电量(最近30天)
+     */
     async getHisPgPvSupply() {
-      const {data: pgPvHisSupply} = await pgSupplyDayTotalPv({
-        areaCode: this.areaType,
-        startRecTime: DateTool.lastXDay(30),
-        endRecTime: DateTool.now(),
-      })
-      if (!pgPvHisSupply) {
-        return
-      }
+      try {
+        const startDate = DateTool.lastXDay(30)
+        const endDate = DateTool.now()
 
-      const dateTips = DateTool.getDayOfRange(DateTool.lastXDay(30), DateTool.now());
-      const dateIndexMap = {}
-      pgPvHisSupply.forEach(item => {
-        dateIndexMap[item.date] = item
-      })
-      const lineData = []
-      dateTips.forEach((item, index) => {
-        if (dateIndexMap[item]) {
-          lineData.push({
-            xData: item,
-            yData: dateIndexMap[item].genElecQuantity
-          })
-        } else {
+        const {data, rows} = await pgSupplyHourList({
+          areaCode: this.areaType,
+          startRecTime: startDate,
+          endRecTime: endDate,
+          timeDimension: 'day',  // 按日维度查询
+          pageNum: 1,
+          pageSize: 31,  // 最多31天
+          orderFlag: 'asc'
+        })
+
+        // 兼容两种返回格式
+        const dailyData = rows || data || []
+
+        if (!Array.isArray(dailyData)) {
+          console.warn('历史发电数据格式错误')
+          this.lineData = []
+          return
+        }
+
+        // 生成日期范围
+        const dateTips = DateTool.getDayOfRange(startDate, endDate)
+
+        // 构建日期索引映射
+        const dateIndexMap = {}
+        dailyData.forEach(item => {
+          if (item.statisticDate) {
+            // 格式化日期为 YYYY-MM-DD
+            const dateStr = item.statisticDate.split(' ')[0]
+            dateIndexMap[dateStr] = item
+          }
+        })
+
+        // 生成完整的30天数据
+        const lineData = []
+        dateTips.forEach(date => {
+          const dayData = dateIndexMap[date]
           lineData.push({
-            xData: item,
-            yData: 0
+            xData: date,
+            yData: dayData ? (dayData.genElecQuantity || 0) : 0
           })
-        }
-      })
-      this.lineData = lineData
+        })
+
+        this.lineData = lineData
+
+      } catch (error) {
+        console.error('获取历史发电数据失败:', error)
+        this.lineData = []
+      }
     },
 
+    /**
+     * 获取空的24小时数据(用于异常情况)
+     */
+    getEmptyHourData() {
+      const timeLabels = DateTool.getTime(60)
+      return timeLabels.map(timeLabel => ({
+        xData: timeLabel,
+        yData: 0
+      }))
+    }
   }
 }
 </script>
+
 <style lang='scss' scoped>
 @import url("../index.scss");
 
@@ -349,7 +420,6 @@ export default {
       font-weight: bold;
       color: #06E3F9;
     }
-
   }
 }
 
@@ -385,48 +455,4 @@ export default {
     }
   }
 }
-
-.elec-index {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: space-between;
-  padding: 10px 0 0;
-
-  .panel-content {
-    margin-top: 12px;
-    flex-basis: 48%;
-    height: 75px;
-    color: #B3E3E8;
-    background: url('~@/assets/images/home/l2_item_bg.png') no-repeat;
-    background-size: 100% 100%;
-    display: flex;
-
-    .whitespace-pre {
-      margin-top: 15px;
-      margin-left: 10px;
-
-      span.value {
-        font-size: 18px;
-        font-weight: bold;
-      }
-    }
-
-    .label {
-      margin-top: 5px;
-      font-size: 14px;
-    }
-
-    .image-container {
-      width: 60px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-
-      img {
-        height: 24px;
-        margin-bottom: 5px;
-      }
-    }
-  }
-}
 </style>

部分文件因为文件数量过多而无法显示