Răsfoiți Sursa

feat(online): support separate statistics of box and power

Casper Dai 2 ani în urmă
părinte
comite
844ba07ed2

+ 116 - 61
src/views/device/detail/components/DeviceRuntime/OnlineDuration.vue

@@ -2,50 +2,83 @@
   <div class="l-flex--col c-device-grid-item has-border radius">
     <div class="l-flex__none l-flex--row c-sibling-item--v">
       <i class="l-flex__none c-sibling-item o-icon" />
-      <span class="l-flex__fill c-sibling-item near u-color--info u-ellipsis">在线总时长</span>
-      <template v-if="timestamp">
-        <div class="c-sibling-item nearest u-color--info u-font-size--xs">{{ timestamp }}</div>
+      <span class="l-flex__fill c-sibling-item near u-color--info u-ellipsis">时长统计</span>
+      <template v-if="amounts && amounts.length">
         <i
-          class="c-sibling-item nearer el-icon-date has-active"
+          class="c-sibling-item el-icon-date has-active"
           @click="showReport"
         />
       </template>
-      <c-dialog
-        ref="dialog"
-        title="历史在线时长"
-        size="lg fixed"
-      >
-        <div class="l-flex__none l-flex c-sibling-item--v">
-          <div class="l-flex__fill" />
-          <el-date-picker
-            v-model="date"
-            type="daterange"
-            format="yyyy-MM-dd"
-            value-format="yyyy-MM-dd"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            @change="getOnlineDurationReport"
-          />
-        </div>
-        <div
-          ref="chart"
-          class="l-flex__fill c-sibling-item--v"
-        />
-      </c-dialog>
     </div>
-    <div class="l-flex__fill l-flex--row center u-color--black u-text--center">
-      <div
-        v-if="duration"
-        class="u-font-size--lg"
-      >
-        {{ duration }}
-      </div>
+    <div
+      class="l-flex__fill l-flex--col jcenter u-color--black"
+      :class="{ 'c-sibling-item--v far': hasMore }"
+    >
+      <template v-if="amounts">
+        <div
+          v-if="amounts.length === 0"
+          class="u-font-size--lg u-text--center"
+        >
+          暂无统计数据
+        </div>
+        <template v-else>
+          <div
+            v-for="amount in amounts"
+            :key="amount.key"
+            class="c-sibling-item--v far"
+          >
+            <div class="l-flex--row c-sibling-item--v u-font-size--xs">
+              <span class="l-flex__fill">{{ amount.label }}</span>
+              <span class="l-flex__none u-color--info dark">{{ amount.timestamp }}</span>
+            </div>
+            <div class="c-sibling-item--v u-color--blue u-font-size--md u-bold u-text--center">{{ amount.value }}</div>
+          </div>
+        </template>
+      </template>
       <i
         v-else
-        class="el-icon-loading"
+        class="l-flex__none el-icon-loading u-align-self--center"
       />
     </div>
+    <c-dialog
+      ref="dialog"
+      title="历史在线时长(小时)"
+      size="lg fixed"
+    >
+      <div class="l-flex__none l-flex c-sibling-item--v">
+        <div class="l-flex__fill" />
+        <el-select
+          v-if="hasPowerData"
+          v-model="type"
+          class="c-sibling-item u-width--sm"
+        >
+          <el-option
+            value="online"
+            label="播控器在线时长"
+          />
+          <el-option
+            value="power"
+            label="电源开启时长"
+          />
+        </el-select>
+        <el-date-picker
+          v-model="date"
+          class="c-sibling-item near"
+          type="daterange"
+          format="yyyy-MM-dd"
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions"
+          @change="getOnlineDurationReport"
+        />
+      </div>
+      <div
+        ref="chart"
+        class="l-flex__fill c-sibling-item--v"
+      />
+    </c-dialog>
   </div>
 </template>
 
@@ -67,17 +100,31 @@ export default {
   },
   data () {
     const startDate = new Date()
+    startDate.setDate(startDate.getDate() - 1)
     startDate.setMonth(startDate.getMonth() - 1)
     const endDate = new Date()
+    endDate.setDate(endDate.getDate() - 1)
 
     return {
-      duration: '',
-      timestamp: '',
+      type: 'online',
+      amounts: null,
       date: [parseTime(startDate, '{y}-{m}-{d}'), parseTime(endDate, '{y}-{m}-{d}')],
       reportData: []
     }
   },
   computed: {
+    hasPowerData () {
+      return this.amounts?.some(({ key }) => key === 'power')
+    },
+    hasMore () {
+      return this.amounts?.length > 1
+    },
+    pickerOptions () {
+      return { disabledDate: this.disabledDate }
+    },
+    valueKey () {
+      return this.type === 'online' ? 'seconds' : 'powerSeconds'
+    },
     xData () {
       let startDate = new Date(this.date[0])
       const endDate = new Date(this.date[1])
@@ -89,13 +136,19 @@ export default {
       }
       return arr
     },
-    yData () {
+    valueData () {
       const map = {}
       for (let i = 0; i < this.reportData.length; i++) {
-        const { sumDate, seconds } = this.reportData[i]
-        map[sumDate] = (seconds / 3600).toFixed(1)
+        const data = this.reportData[i]
+        const seconds = data[this.valueKey]
+        map[data.sumDate] = seconds ? (seconds / 3600).toFixed(1) : '0'
       }
-      return this.xData.map(date => map[date] || 0)
+      return this.xData.map(date => map[date] || '0')
+    }
+  },
+  watch: {
+    type () {
+      this.initChart()
     }
   },
   created () {
@@ -108,25 +161,35 @@ export default {
     clearTimeout(this.$timer)
   },
   methods: {
+    disabledDate (date) {
+      return date >= this.$minDate
+    },
     startRun () {
       if (!this.$running) {
         return
       }
       getOnlineDurationByDevice(this.device.id).then(({ data }) => {
         if (data) {
-          if (!data.powerSeconds || data.powerSeconds === '0') {
-            this.duration = this.transformDuration(data.onlineSeconds)
-            this.timestamp = data.onlineSecondsUpdateTime
-          } else {
-            this.duration = this.transformDuration(data.powerSeconds)
-            this.timestamp = data.powerSecondsUpdateTime
+          const amounts = []
+          if (data.onlineSeconds) {
+            amounts.push({
+              key: 'online',
+              label: '播控器在线时长',
+              value: this.transformDuration(data.onlineSeconds),
+              timestamp: data.onlineSecondsUpdateTime
+            })
           }
-          if (!this.duration) {
-            this.duration = '暂无统计数据'
+          if (data.powerSeconds && data.powerSeconds !== '0') {
+            amounts.push({
+              key: 'power',
+              label: '电源开启时长',
+              value: this.transformDuration(data.powerSeconds),
+              timestamp: data.powerSecondsUpdateTime
+            })
           }
+          this.amounts = amounts
         } else {
-          this.duration = '暂无统计数据'
-          this.timestamp = ''
+          this.amounts = []
         }
       }).finally(() => {
         if (this.$running) {
@@ -143,16 +206,8 @@ export default {
         { value: duration % 60, unit: '秒' }
       ].reduce((curr, { value, unit }) => value ? `${curr}${value}${unit}` : curr, '')
     },
-    getMonth () {
-      const startDate = new Date()
-      startDate.setMonth(startDate.getMonth() - 1)
-      const endDate = new Date()
-      return {
-        startDate: parseTime(startDate, '{y}-{m}-{d}'),
-        endDate: parseTime(endDate, '{y}-{m}-{d}')
-      }
-    },
     showReport () {
+      this.$minDate = new Date(parseTime(Date.now(), '{y}-{m}-{d} 00:00:00'))
       this.getOnlineDurationReport()
       this.$refs.dialog.show()
     },
@@ -192,7 +247,7 @@ export default {
         series: [
           {
             type: 'line',
-            data: this.yData
+            data: this.valueData
           }
         ]
       })

+ 1 - 1
src/views/device/index.vue

@@ -46,7 +46,7 @@ export default {
             : { type: 'warning', label: '未激活' }, 'width': 120 },
           { label: '运行时间', render: ({ openTime, closeTime }) => openTime && closeTime
             ? `${openTime} - ${closeTime}`
-            : '-', width: 140 },
+            : '-', width: 148 },
           { prop: 'address', label: '地址', 'min-width': 160 },
           { type: 'invoke', render: [
             { label: '详情', on: this.onViewDevice }