| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- <template>
- <box
- :title="title"
- :fullscreen.sync="fullscreen"
- :empty="empty"
- >
- <div
- class="l-flex__fill l-flex--col jcenter c-device-dashboard-sensor"
- :class="{ fullscreen }"
- >
- <div
- class="l-flex__none c-device-dashboard-sensor__tip u-bold u-text--center"
- :style="{ color }"
- >
- {{ tip }}
- </div>
- <div class="l-flex__none c-device-dashboard-sensor__current u-text--center">
- <template v-if="fullscreen">
- {{ sensorTime }} {{ sensorName }}
- </template>
- <template v-else>
- <div>{{ sensorTime }}</div>
- <div>{{ sensorName }}</div>
- </template>
- </div>
- <div
- v-if="fullscreen && sorted.length > 1"
- class="l-flex__fill u-relative"
- >
- <div class="l-flex__fill c-device-dashboard-sensor__list">
- <vue-seamless-scroll
- :data="sorted"
- :class-option="classOption"
- >
- <div
- v-for="(item,index) in sorted"
- :key="index"
- class="l-flex--row c-device-dashboard-sensor__item"
- >
- <div class="l-flex__fill u-text--center u-ellipsis">{{ item.time }}</div>
- <div class="l-flex__fill u-text--center u-ellipsis">传感器{{ item.port }}</div>
- <div
- :style="{ color }"
- class="l-flex__fill u-text--center"
- >
- {{ item.value }}
- </div>
- </div>
- </vue-seamless-scroll>
- </div>
- </div>
- </div>
- </box>
- </template>
- <script>
- import { ThirdPartyDevice } from '@/constant'
- import { parseTime } from '@/utils'
- import { getSensorRecords } from '@/api/external'
- import VueSeamlessScroll from 'vue-seamless-scroll'
- import Box from './Box'
- export default {
- components: {
- VueSeamlessScroll,
- Box
- },
- props: {
- type: {
- type: Number,
- required: true
- },
- title: {
- type: String,
- default: ''
- },
- color: {
- type: String,
- default: ''
- },
- deviceId: {
- type: String,
- required: true
- }
- },
- data () {
- return {
- fullscreen: false,
- list: [],
- classOption: {
- step: 0.3,
- hoverStop: false
- }
- }
- },
- computed: {
- sorted () {
- return this.list.slice().sort((a, b) => Number(a.value) < Number(b.value) ? 1 : -1)
- },
- tip () {
- return this.sorted.length ? this.sorted[0].info : '未知'
- },
- sensorTime () {
- return this.sorted.length
- ? this.sorted[0].time
- : null
- },
- sensorName () {
- return this.sorted.length
- ? `传感器${this.sorted[0].port}`
- : null
- },
- empty () {
- return this.list.length === 0
- }
- },
- created () {
- this.$running = true
- this.$timer = -1
- this.startRun()
- },
- beforeDestroy () {
- this.$running = false
- clearTimeout(this.$timer)
- },
- methods: {
- startRun () {
- if (!this.$running) {
- return
- }
- const now = Date.now()
- this.loading = true
- getSensorRecords({
- deviceId: this.deviceId,
- sensorType: this.type,
- startTime: parseTime(now - 30000, '{y}-{m}-{d} {h}:{i}:{s}'),
- endTime: parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}')
- }, { custom: true }).then(({ data }) => {
- this.list = this.transfromData(data)
- this.$refs.tableDialog?.getTable()?.pageTo()
- }).finally(() => {
- this.loading = false
- if (this.$running) {
- this.$timer = setTimeout(this.startRun, 10000)
- }
- })
- },
- transfromData (data) {
- const map = {}
- const arr = []
- data.forEach(sensor => {
- if (!map[sensor.port]) {
- map[sensor.port] = 1
- arr.push(this.transformSensorData(sensor))
- }
- })
- return arr
- },
- transformSensorData (data) {
- const { port, type, value, time } = data
- return {
- port,
- value,
- time,
- info: this.transformValue(type, value)
- }
- },
- transformValue (type, value) {
- switch (type) {
- case ThirdPartyDevice.SMOKE_SENSOR:
- return `${value}ppm`
- case ThirdPartyDevice.TEMPERATURE_SENSOR:
- return `${value}℃`
- case ThirdPartyDevice.LIGHT_SENSOR:
- return `${value}Lux`
- case ThirdPartyDevice.FLOODING_SENSOR:
- return value ? '是' : '否'
- default:
- return value
- }
- },
- getSensors () {
- return Promise.resolve({ data: this.list })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .c-device-dashboard-sensor {
- color: #ffffff;
- &__tip {
- font-size: 24px;
- line-height: 36px;
- }
- &__current {
- margin-bottom: 10px;
- color: #9ea9cd;
- font-size: 12px;
- }
- &__list {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
- }
- &__item {
- font-size: 20px;
- line-height: 64px;
- border-bottom: 1px solid #9ea9cd;
- }
- &.fullscreen {
- .c-device-dashboard-sensor__tip {
- padding-top: 32px;
- font-size: 64px;
- line-height: 90px;
- }
- .c-device-dashboard-sensor__current {
- margin-bottom: 90px;
- font-size: 16px;
- }
- }
- }
- </style>
|