|
|
@@ -0,0 +1,252 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ class="o-device u-pointer"
|
|
|
+ :data-id="device.id"
|
|
|
+ @click="onClick"
|
|
|
+ >
|
|
|
+ <div class="l-flex__none l-flex--row c-sibling-item--v o-device__block u-font-size u-bold">
|
|
|
+ <auto-text
|
|
|
+ class="l-flex__fill c-sibling-item"
|
|
|
+ :text="name"
|
|
|
+ />
|
|
|
+ <template v-if="hasStatus">
|
|
|
+ <el-tooltip
|
|
|
+ v-if="isOnline && hasPower"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <template #content>{{ powerStatusTip }}</template>
|
|
|
+ <i
|
|
|
+ class="l-flex__none c-sibling-item near o-device__status"
|
|
|
+ :class="switchStatusClass"
|
|
|
+ @click.stop
|
|
|
+ />
|
|
|
+ </el-tooltip>
|
|
|
+ <el-tooltip placement="top">
|
|
|
+ <template #content>{{ statusInfoTip }}</template>
|
|
|
+ <div
|
|
|
+ class="l-flex__none o-device__tip u-font-size--xs"
|
|
|
+ :class="statusClass"
|
|
|
+ >
|
|
|
+ <span class="u-color--white">{{ statusTip }}</span>
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ <i
|
|
|
+ v-else
|
|
|
+ class="l-flex__none c-sibling-item near el-icon-loading"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="l-flex__none l-flex--row c-sibling-item--v nearer o-device__block u-relative u-color--blue">
|
|
|
+ <i class="l-flex__none c-sibling-item el-icon-location-outline u-font-size" />
|
|
|
+ <auto-text
|
|
|
+ class="l-flex__auto c-sibling-item nearest u-font-size--xs u-bold"
|
|
|
+ :text="address"
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ v-if="isOnline && volume > -1"
|
|
|
+ class="l-flex__none o-device__volume u-color--white u-font-size--sm has-active"
|
|
|
+ @click.stop="onVolume"
|
|
|
+ >
|
|
|
+ <template v-if="volume === 0">
|
|
|
+ <svg-icon icon-class="mute" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <svg-icon
|
|
|
+ class="c-sibling-item"
|
|
|
+ icon-class="volume"
|
|
|
+ />
|
|
|
+ <span class="c-sibling-item nearest">{{ volume }}%</span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { ThirdPartyDevice } from '@/constant'
|
|
|
+import { parseTime } from '@/utils'
|
|
|
+import {
|
|
|
+ Status,
|
|
|
+ Power,
|
|
|
+ addListener,
|
|
|
+ removeListener
|
|
|
+} from '@/utils/adapter'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'DeviceCardSimple',
|
|
|
+ props: {
|
|
|
+ device: {
|
|
|
+ type: Object,
|
|
|
+ required: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ timestamp: '',
|
|
|
+ powerStatus: Status.LOADING,
|
|
|
+ switchStatus: Power.LOADING,
|
|
|
+ hasPower: true,
|
|
|
+ hasPowerRealStatus: false,
|
|
|
+ volume: -1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ name () {
|
|
|
+ return this.device.name
|
|
|
+ },
|
|
|
+ address () {
|
|
|
+ return this.device.address
|
|
|
+ },
|
|
|
+ powerStatusTip () {
|
|
|
+ return this.hasPower
|
|
|
+ ? this.powerStatus === Status.WARNING
|
|
|
+ ? `电源状态异常,${this.switchStatus === Power.LOADING ? '检测' : '最后上报'}时间 ${this.timestamp}`
|
|
|
+ : this.isPowerOpened
|
|
|
+ ? '屏幕已开启'
|
|
|
+ : '屏幕未开启'
|
|
|
+ : ''
|
|
|
+ },
|
|
|
+ isOnline () {
|
|
|
+ return this.device.onlineStatus === 1
|
|
|
+ },
|
|
|
+ hasStatus () {
|
|
|
+ return !this.isOnline || !this.hasPower || this.hasPowerRealStatus
|
|
|
+ },
|
|
|
+ isPowerOpened () {
|
|
|
+ return !this.hasPower || this.hasPowerRealStatus && (this.powerStatus === Status.OK && this.switchStatus !== Power.OFF)
|
|
|
+ },
|
|
|
+ isRealOnline () {
|
|
|
+ return this.hasStatus && this.isOnline && this.isPowerOpened
|
|
|
+ },
|
|
|
+ isRealOffline () {
|
|
|
+ return this.hasStatus && !this.isRealOnline
|
|
|
+ },
|
|
|
+ switchStatusClass () {
|
|
|
+ if (this.powerStatus === Status.WARNING) {
|
|
|
+ return 'el-icon-warning u-color--warning u-font-size--2xl'
|
|
|
+ }
|
|
|
+ return this.switchStatus === Power.ON ? 'on' : this.switchStatus === Power.OFF ? 'off' : 'other'
|
|
|
+ },
|
|
|
+ statusClass () {
|
|
|
+ return this.isOnline ? 'u-color--success dark' : 'u-color--error dark'
|
|
|
+ },
|
|
|
+ statusTip () {
|
|
|
+ return this.isOnline ? '在线' : '离线'
|
|
|
+ },
|
|
|
+ statusInfoTip () {
|
|
|
+ return this.device.lastOnline
|
|
|
+ ? this.isOnline
|
|
|
+ ? `${this.device.lastOnline} 上线`
|
|
|
+ : `${this.device.lastOnline} 离线`
|
|
|
+ : this.isOnline
|
|
|
+ ? '播控器正常运行中'
|
|
|
+ : '当前播控器离线了'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ isOnline: {
|
|
|
+ handler (val, old) {
|
|
|
+ if (val) {
|
|
|
+ addListener(this.device.id, this.onMessage)
|
|
|
+ } else {
|
|
|
+ if (old == null) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ removeListener(this.device.id, this.onMessage)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ if (this.isOnline) {
|
|
|
+ removeListener(this.device.id, this.onMessage)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onMessage (value) {
|
|
|
+ if (value.screen) {
|
|
|
+ this.volume = value.screen.volume
|
|
|
+ }
|
|
|
+ const multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
|
|
|
+ const powerStatus = multiCard.status
|
|
|
+ this.powerStatus = powerStatus
|
|
|
+ this.timestamp = multiCard.timestamp ? parseTime(multiCard.timestamp, '{y}-{m}-{d} {h}:{i}:{s}') : ''
|
|
|
+ this.hasPower = powerStatus > Status.NONE
|
|
|
+ this.hasPowerRealStatus = powerStatus !== Status.LOADING
|
|
|
+ this.switchStatus = multiCard.switchStatus
|
|
|
+ },
|
|
|
+ onClick () {
|
|
|
+ this.$router.push({
|
|
|
+ name: 'device-detail',
|
|
|
+ params: { id: this.device.id }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onVolume () {
|
|
|
+ const { id, productId, name } = this.device
|
|
|
+ this.$emit('volume', {
|
|
|
+ value: this.volume,
|
|
|
+ device: { id, productId, name }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.o-device {
|
|
|
+ display: inline-flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: $padding--md $padding--lg;
|
|
|
+ color: $black;
|
|
|
+ line-height: 1;
|
|
|
+ border-radius: $radius;
|
|
|
+ background-color: #fff;
|
|
|
+ box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.1), 0 2px 6px 0 rgba(0, 0, 0, 0.1);
|
|
|
+
|
|
|
+ &__block {
|
|
|
+ height: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__status {
|
|
|
+ display: inline-flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+
|
|
|
+ &.on {
|
|
|
+ background: url("~@/assets/icon_on.svg") 0 0 / 100% 100% no-repeat;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.off {
|
|
|
+ background: url("~@/assets/icon_off.svg") 0 0 / 100% 100% no-repeat;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.other {
|
|
|
+ width: 54px;
|
|
|
+ background: url("~@/assets/icon_on_2.svg") 0 0 / 100% 100% no-repeat;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &__tip {
|
|
|
+ display: inline-block;
|
|
|
+ position: relative;
|
|
|
+ left: $padding--lg;
|
|
|
+ padding: $padding--2xs $padding--sm $padding--2xs $padding;
|
|
|
+ margin-left: -$spacing--xs;
|
|
|
+ border-radius: $radius--sm 0 0 $radius--sm;
|
|
|
+ background-color: currentColor;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__volume {
|
|
|
+ display: inline-block;
|
|
|
+ position: relative;
|
|
|
+ left: $padding--lg;
|
|
|
+ padding: $padding--2xs;
|
|
|
+ margin-left: -$spacing--xs;
|
|
|
+ border-radius: $radius--sm 0 0 $radius--sm;
|
|
|
+ background-color: $gray--dark;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|