Zimo 1 hafta önce
ebeveyn
işleme
6e10c15293

+ 2 - 2
.env.local

@@ -3,8 +3,8 @@ NODE_ENV=development
 
 VITE_DEV=true
 
-# 请求路径  http://192.168.188.79:48080  https://iot.deepoil.cc  http://172.26.0.56:48080
-VITE_BASE_URL='https://iot.deepoil.cc'
+# 请求路径  http://192.168.188.200:48080  https://iot.deepoil.cc  http://172.26.0.56:48080
+VITE_BASE_URL='http://192.168.188.200:48080'
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server

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

@@ -90,6 +90,9 @@ export const IotStatApi = {
   getRhZql: async (params: any) => {
     return await request.get({ url: `/rq/stat/year/total/gas/` + params })
   },
+  getRhZqlTotal: async (params: any) => {
+    return await request.get({ url: `/rq/stat/rh/zql`, params })
+  },
   getRhZqlGases: async (params: any) => {
     return await request.get({ url: `/rq/stat/year/total/gases/` + params })
   },
@@ -147,6 +150,9 @@ export const IotStatApi = {
   getRhRate: async (params: any) => {
     return await request.get({ url: `/rq/stat/rh/device/utilizationRate`, params })
   },
+  getRhTotalUtilizationRate: async (params: any) => {
+    return await request.get({ url: `/rq/stat/rh/device/totalUtilizationRate`, params })
+  },
   getRyRate: async (params: any) => {
     return await request.get({ url: `/rq/stat/ry/device/utilizationRate`, params })
   },

+ 1 - 1
src/config/axios/service.ts

@@ -217,7 +217,7 @@ service.interceptors.response.use(
       ) {
         const localeStore = useLocaleStore()
         const lang = localeStore.getCurrentLocale.lang
-        if (data && data.data) {
+        if (data && data.data !== null && data.data !== undefined) {
           if (data.data.list) {
             if (Array.isArray(data.data.list)) {
               const list = langHelper.transformArray(data.data.list, lang)

+ 121 - 2
src/views/pms/stat/rhkb/rhsummary.vue

@@ -5,6 +5,9 @@ import dayjs from 'dayjs'
 
 type CardKey =
   | 'device'
+  | 'utilizationRate'
+  | 'todayGas'
+  | 'yearGas'
   | 'maintain'
   | 'unfilledCount'
   | 'filledCount'
@@ -23,6 +26,27 @@ const cardConfigs: CardConfig[] = [
     accent: THEME.color.blue.strong,
     glow: THEME.color.blue.glow
   },
+  {
+    key: 'utilizationRate',
+    title: '设备利用率(%)',
+    icon: 'i-solar:chart-2-linear',
+    accent: THEME.color.green.strong,
+    glow: THEME.color.green.glow
+  },
+  {
+    key: 'todayGas',
+    title: '当日注气量(万方)',
+    icon: 'i-solar:gas-station-linear',
+    accent: THEME.color.blue.strong,
+    glow: THEME.color.blue.glow
+  },
+  {
+    key: 'yearGas',
+    title: '累计注气量(万方)',
+    icon: 'i-solar:database-linear',
+    accent: THEME.color.green.strong,
+    glow: THEME.color.green.glow
+  },
   // {
   //   key: 'maintain',
   //   title: '维修工单',
@@ -77,6 +101,9 @@ const cardConfigs: CardConfig[] = [
 function createDefaultCardState(): Record<CardKey, CardStateItem> {
   return {
     device: { value: 0, loading: true },
+    utilizationRate: { value: 0, loading: true },
+    todayGas: { value: 0, loading: true },
+    yearGas: { value: 0, loading: true },
     maintain: { value: 0, loading: true },
     unfilledCount: { value: 0, loading: true },
     filledCount: { value: 0, loading: true },
@@ -93,7 +120,8 @@ const summaryCards = computed(() =>
   cardConfigs.map((card) => ({
     ...card,
     value: cardState[card.key].value,
-    loading: cardState[card.key].loading
+    loading: cardState[card.key].loading,
+    decimals: ['utilizationRate', 'todayGas', 'yearGas'].includes(card.key) ? 2 : 0
   }))
 )
 
@@ -102,7 +130,51 @@ function toNumber(value: unknown) {
   return Number.isFinite(num) ? num : 0
 }
 
+function getCreateTimeRange(start: dayjs.Dayjs, end: dayjs.Dayjs) {
+  return [start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')]
+}
+
+function getFirstNumber(data: unknown): number {
+  if (typeof data === 'number' || typeof data === 'string') return toNumber(data)
+  if (!data || typeof data !== 'object') return 0
+
+  const record = data as Record<string, unknown>
+  const preferredKeys = [
+    'total',
+    'value',
+    'rate',
+    'utilizationRate',
+    'totalUtilizationRate',
+    'gas',
+    'zql',
+    'gasInjection',
+    'totalGasInjection',
+    'totalNaturalGasInjection',
+    'totalN2GasInjection'
+  ]
+
+  for (const key of preferredKeys) {
+    if (record[key] !== undefined) return getFirstNumber(record[key])
+  }
+
+  if (Array.isArray(data)) {
+    return getFirstNumber(data[0])
+  }
+
+  const firstNumber = Object.values(record).find(
+    (value) => Number.isFinite(Number(value)) && value !== ''
+  )
+
+  return toNumber(firstNumber)
+}
+
+function normalizePercent(value: unknown) {
+  const num = getFirstNumber(value)
+  return Math.abs(num) <= 1 ? num * 100 : num
+}
+
 function setCardValue(key: CardKey, value: unknown) {
+  console.log(key, value)
   cardState[key].value = toNumber(value)
 }
 
@@ -127,6 +199,50 @@ async function loadDeviceCard() {
   }
 }
 
+async function loadUtilizationRateCard() {
+  const keys: CardKey[] = ['utilizationRate']
+  setCardLoading(keys, true)
+
+  const params = {
+    createTime: getCreateTimeRange(dayjs().startOf('year'), dayjs().endOf('day'))
+  }
+
+  try {
+    const res = await IotStatApi.getRhTotalUtilizationRate(params)
+    setCardValue('utilizationRate', normalizePercent(res))
+  } catch (error) {
+    console.error('获取设备利用率失败:', error)
+    setCardValue('utilizationRate', 0)
+  } finally {
+    setCardLoading(keys, false)
+  }
+}
+
+async function loadGasCards() {
+  const keys: CardKey[] = ['todayGas', 'yearGas']
+  setCardLoading(keys, true)
+
+  try {
+    const [todayRes, yearRes] = await Promise.all([
+      IotStatApi.getRhZqlTotal({
+        createTime: getCreateTimeRange(dayjs().startOf('day'), dayjs().endOf('day'))
+      }),
+      IotStatApi.getRhZqlTotal({
+        createTime: getCreateTimeRange(dayjs().startOf('year'), dayjs().endOf('day'))
+      })
+    ])
+
+    setCardValue('todayGas', todayRes)
+    setCardValue('yearGas', yearRes)
+  } catch (error) {
+    console.error('获取注气量失败:', error)
+    setCardValue('todayGas', 0)
+    setCardValue('yearGas', 0)
+  } finally {
+    setCardLoading(keys, false)
+  }
+}
+
 async function loadMaintainCard() {
   const keys: CardKey[] = ['maintain']
   setCardLoading(keys, true)
@@ -212,6 +328,8 @@ async function loadInspectCards() {
 
 function loadAllCards() {
   loadDeviceCard()
+  loadUtilizationRateCard()
+  loadGasCards()
   loadMaintainCard()
   loadFillCards()
   loadMaintainStatusCards()
@@ -233,7 +351,7 @@ onMounted(() => {
       工单情况
     </div>
 
-    <div class="summary-panel__grid grid grid-cols-8 flex-1">
+    <div class="summary-panel__grid grid grid-cols-7 flex-1">
       <article
         v-for="card in summaryCards"
         :key="card.key"
@@ -256,6 +374,7 @@ onMounted(() => {
               style="color: #1f5bb8"
               :start-val="0"
               :end-val="card.value"
+              :decimals="card.decimals"
               :duration="1200" />
             <span v-else class="summary-card__placeholder">--</span>
           </div>