|
|
@@ -1,53 +1,59 @@
|
|
|
<template>
|
|
|
- <div class="l-flex--row center c-info">
|
|
|
- <div
|
|
|
- v-if="loaded"
|
|
|
- class="linkState"
|
|
|
- >
|
|
|
+ <div v-loading="!loaded && loading">
|
|
|
+ <template v-if="loaded || !loading">
|
|
|
+ <warning
|
|
|
+ v-if="!loaded && !loading"
|
|
|
+ @click="getBoundThirdPartyDevices"
|
|
|
+ />
|
|
|
<div
|
|
|
- v-for="item in items"
|
|
|
- :key="item.key"
|
|
|
- :class="['co', item.key]"
|
|
|
- :style="getImg(item.key)"
|
|
|
+ v-else
|
|
|
+ class="l-flex__auto u-overflow-x--auto"
|
|
|
>
|
|
|
- <div
|
|
|
- v-if="Array.isArray(item.label)"
|
|
|
- class="ctext"
|
|
|
- >
|
|
|
- {{ item.label[0] }}<br>{{ item.label[1] }}
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- class="ctext"
|
|
|
- >
|
|
|
- {{ item.label }}
|
|
|
+ <div class="c-link-state">
|
|
|
+ <div
|
|
|
+ v-for="item in items"
|
|
|
+ :key="item.key"
|
|
|
+ class="o-link-device has-bg"
|
|
|
+ v-bind="getAttrs(item.key)"
|
|
|
+ >
|
|
|
+ <div class="o-link-device__name u-bold">{{ item.label }}</div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="line in lines"
|
|
|
+ :key="line.key"
|
|
|
+ class="o-line"
|
|
|
+ :class="line.className"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div
|
|
|
- v-for="line in lines"
|
|
|
- :key="line.key"
|
|
|
- :class="[
|
|
|
- 'line',
|
|
|
- line.class,
|
|
|
- {
|
|
|
- closed: lineToItem[line.key] && linkStateForm[lineToItem[line.key]] !== 0,
|
|
|
- trafficCameraUnbound: line.key === 5 && linkStateForm.trafficCamera === 2,
|
|
|
- }
|
|
|
- ]"
|
|
|
- />
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getDeviceBind } from '@/api/device'
|
|
|
+import { getBoundThirdPartyDevices } from '@/api/external'
|
|
|
+import { ThirdPartyDevice } from '@/constant'
|
|
|
import { ScreenshotCache } from '@/utils/cache'
|
|
|
+
|
|
|
+const KeyMap = {
|
|
|
+ [ThirdPartyDevice.GATEWAY]: 'gateway',
|
|
|
+ [ThirdPartyDevice.RECEIVING_CARD]: 'receive_card',
|
|
|
+ [ThirdPartyDevice.SENDING_CARD]: 'sending_device',
|
|
|
+ [ThirdPartyDevice.SCREEN]: 'led',
|
|
|
+ [ThirdPartyDevice.LED_CAMERA]: 'led_camera',
|
|
|
+ [ThirdPartyDevice.TRAFFIC_CAMERA]: 'traffic_camera'
|
|
|
+}
|
|
|
+
|
|
|
export default {
|
|
|
name: 'LinkState',
|
|
|
props: {
|
|
|
device: {
|
|
|
type: Object,
|
|
|
required: true
|
|
|
+ },
|
|
|
+ online: {
|
|
|
+ type: [Boolean, String],
|
|
|
+ default: false
|
|
|
}
|
|
|
},
|
|
|
data () {
|
|
|
@@ -70,8 +76,12 @@ export default {
|
|
|
key: 'sending_device'
|
|
|
},
|
|
|
{
|
|
|
- label: ['人流量监测', '摄像头'],
|
|
|
- key: 'trafficCamera'
|
|
|
+ label: '人流量监测摄像头',
|
|
|
+ key: 'traffic_camera'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'LED屏监测摄像头',
|
|
|
+ key: 'led_camera'
|
|
|
},
|
|
|
{
|
|
|
label: '接收卡',
|
|
|
@@ -82,116 +92,125 @@ export default {
|
|
|
key: 'led'
|
|
|
}
|
|
|
],
|
|
|
- lines: Array.from({ length: 7 }, (v, index) => {
|
|
|
- return {
|
|
|
- key: index + 1,
|
|
|
- class: `l${index + 1}`
|
|
|
- }
|
|
|
- }),
|
|
|
- lineToItem: {
|
|
|
- 1: 'msr',
|
|
|
- 2: 'device',
|
|
|
- 3: 'sending_device',
|
|
|
- 4: 'receive_card',
|
|
|
- 5: 'msr',
|
|
|
- 6: 'msr',
|
|
|
- 7: 'gateway'
|
|
|
+ lineFromeTo: {
|
|
|
+ 1: ['msr', 'device'],
|
|
|
+ 2: ['device', 'sending_device'],
|
|
|
+ 3: ['device', 'receive_card'],
|
|
|
+ 4: ['receive_card', 'led'],
|
|
|
+ 5: ['msr', 'gateway'],
|
|
|
+ 6: ['msr', 'led_camera', 'traffic_camera'],
|
|
|
+ 7: ['msr', 'traffic_camera'],
|
|
|
+ 8: ['msr', 'led_camera'],
|
|
|
+ 9: ['msr', 'led_camera'],
|
|
|
+ 10: ['gateway', 'led']
|
|
|
},
|
|
|
- linkStateForm: {
|
|
|
- // 0 开启 1 关闭 2未绑定
|
|
|
+ linkState: {
|
|
|
msr: 0,
|
|
|
- device: 2,
|
|
|
+ device: this.online ? 0 : 1,
|
|
|
+ led: this.online ? 0 : 1,
|
|
|
gateway: 2,
|
|
|
sending_device: 2,
|
|
|
- trafficCamera: 2,
|
|
|
- receive_card: 2,
|
|
|
- led: 2
|
|
|
+ traffic_camera: 2,
|
|
|
+ led_camera: 2,
|
|
|
+ receive_card: 2
|
|
|
},
|
|
|
+ loading: true,
|
|
|
loaded: false,
|
|
|
base64: null
|
|
|
}
|
|
|
},
|
|
|
- // created () {
|
|
|
- // ScreenshotCache.watch(this.device, this.onScreenshotUpdate, 10000)
|
|
|
- // },
|
|
|
- activated () {
|
|
|
- this.getDeviceBind()
|
|
|
- ScreenshotCache.watch(this.device, this.onScreenshotUpdate, 60 * 60 * 1000)
|
|
|
+ computed: {
|
|
|
+ lines () {
|
|
|
+ const lineFromeTo = this.lineFromeTo
|
|
|
+ const state = this.linkState
|
|
|
+ return Object.keys(lineFromeTo).map(key => {
|
|
|
+ const from = lineFromeTo[key][0]
|
|
|
+ const to = lineFromeTo[key].slice(1)
|
|
|
+ return {
|
|
|
+ key: `line${key}`,
|
|
|
+ className: [`l${key}`, state[from] === 0 && to.some(key => state[key] === 0) ? 'linked' : ''].join(' ')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ online () {
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ this.init()
|
|
|
+ this.$timer = setInterval(this.init, 10000)
|
|
|
},
|
|
|
beforeDestroy () {
|
|
|
- ScreenshotCache.unwatch(this.device.id)
|
|
|
+ if (this.online) {
|
|
|
+ ScreenshotCache.unwatch(this.device.id)
|
|
|
+ }
|
|
|
+ clearInterval(this.$timer)
|
|
|
},
|
|
|
methods: {
|
|
|
+ init () {
|
|
|
+ if (this.online) {
|
|
|
+ ScreenshotCache.watch(this.device, this.onScreenshotUpdate, 10000)
|
|
|
+ } else {
|
|
|
+ this.base64 = null
|
|
|
+ }
|
|
|
+ this.getBoundThirdPartyDevices()
|
|
|
+ },
|
|
|
onScreenshotUpdate ({ waiting, base64 }) {
|
|
|
- // console.log('waiting', waiting)
|
|
|
- // console.log('base64', base64)
|
|
|
- this.base64 = !waiting && base64 ? base64 : null
|
|
|
+ if (!waiting) {
|
|
|
+ this.base64 = base64
|
|
|
+ }
|
|
|
},
|
|
|
- getDeviceBind () {
|
|
|
- getDeviceBind(this.device)
|
|
|
- .then(({ data, success }) => {
|
|
|
- if (!success) { return }
|
|
|
- const map = {
|
|
|
- 0: 'gateway',
|
|
|
- 1: 'receive_card',
|
|
|
- 2: 'sending_device',
|
|
|
- // 3: 'led'
|
|
|
- 4: 'ledCamera',
|
|
|
- 5: 'trafficCamera'
|
|
|
-
|
|
|
- }
|
|
|
+ getBoundThirdPartyDevices () {
|
|
|
+ this.loading = true
|
|
|
+ getBoundThirdPartyDevices(this.device.id, true)
|
|
|
+ .then(({ data }) => {
|
|
|
const form = {
|
|
|
- device: this.device.onlineStatus === 1 && this.device.activate === 2 ? 0 : 1,
|
|
|
+ msr: 0,
|
|
|
+ device: this.online ? 0 : 1,
|
|
|
+ led: this.online ? 0 : 1,
|
|
|
gateway: 2,
|
|
|
sending_device: 2,
|
|
|
- trafficCamera: 2,
|
|
|
receive_card: 2,
|
|
|
- led: this.device.onlineStatus === 1 && this.device.activate === 2 ? 0 : 1,
|
|
|
- msr: 0
|
|
|
+ traffic_camera: 2,
|
|
|
+ led_camera: 2
|
|
|
}
|
|
|
for (const item of data) {
|
|
|
- form[map[item.deviceType]] = item.status === 1 ? 0 : 1
|
|
|
+ form[KeyMap[item.deviceType]] = item.status === 1 ? 0 : 1
|
|
|
}
|
|
|
- // const form = {
|
|
|
- // device: this.device.onlineStatus === 1 && this.device.activate === 2 ? 0 : 1,
|
|
|
- // gateway: 0,
|
|
|
- // sending_device: 2,
|
|
|
- // trafficCamera: 2,
|
|
|
- // receive_card: 0,
|
|
|
- // led: 0,
|
|
|
- // msr: 0
|
|
|
- // }
|
|
|
- this.linkStateForm = form
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log('err', err)
|
|
|
+ this.linkState = form
|
|
|
+ this.loaded = true
|
|
|
})
|
|
|
.finally(() => {
|
|
|
- this.loaded = true
|
|
|
+ this.loading = false
|
|
|
})
|
|
|
},
|
|
|
- getImg (key) {
|
|
|
- const value = this.linkStateForm[key]
|
|
|
- let background = ''
|
|
|
- let params = {}
|
|
|
+ getAttrs (key) {
|
|
|
+ const value = this.linkState[key]
|
|
|
+ let style = null
|
|
|
switch (key) {
|
|
|
- case 'msr':
|
|
|
- background = `url("${require('@/assets/linkState/icon_msr.svg')}")`
|
|
|
- break
|
|
|
case 'led':
|
|
|
- value === 0
|
|
|
- ? (background = `url("${this.base64 ? this.base64 : require('@/assets/linkState/led_default.jpg')}")`)
|
|
|
- : (params = { backgroundColor: '#333333' })
|
|
|
+ if (value === 0 && this.base64) {
|
|
|
+ style = {
|
|
|
+ backgroundImage: `url("${this.base64}")`
|
|
|
+ }
|
|
|
+ }
|
|
|
break
|
|
|
default:
|
|
|
- if (value === 2) {
|
|
|
- background = `url("${require('@/assets/linkState/icon_unbound.svg')}")`
|
|
|
- } else {
|
|
|
- background = `url("${require(`@/assets/linkState/icon_${key === 'trafficCamera' || key === 'ledCamera' ? 'camera' : key}_${value === 0 ? 'online' : 'offline'}.svg`)}")`
|
|
|
- }
|
|
|
break
|
|
|
}
|
|
|
- return { backgroundImage: background, ...params }
|
|
|
+ return {
|
|
|
+ 'class': [
|
|
|
+ key,
|
|
|
+ value === 0
|
|
|
+ ? 'online'
|
|
|
+ : value === 1
|
|
|
+ ? 'offline'
|
|
|
+ : 'unbind'
|
|
|
+ ].join(' '),
|
|
|
+ style
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -199,88 +218,189 @@ export default {
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@mixin getPosition($left, $top, $width, $height) {
|
|
|
- left: $left;
|
|
|
top: $top;
|
|
|
+ left: $left;
|
|
|
width: $width;
|
|
|
height: $height;
|
|
|
}
|
|
|
|
|
|
-.linkState {
|
|
|
- width: 1072px;
|
|
|
- height: 452px;
|
|
|
+.c-link-state {
|
|
|
position: relative;
|
|
|
- .co {
|
|
|
- z-index: 1;
|
|
|
- position: absolute;
|
|
|
- background-position: center;
|
|
|
- background-size: cover;
|
|
|
- background-repeat: no-repeat;
|
|
|
+ min-width: 1024px;
|
|
|
+ min-height: 490px;
|
|
|
+ overflow-x: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.o-line {
|
|
|
+ position: absolute;
|
|
|
+ background-color: $border;
|
|
|
+
|
|
|
+ &.linked {
|
|
|
+ background-color: #026af2;
|
|
|
}
|
|
|
- .line {
|
|
|
- position: absolute;
|
|
|
- background: #a1c9ff;
|
|
|
- &.closed {
|
|
|
- background: #d5d9e4;
|
|
|
- }
|
|
|
+
|
|
|
+ &.l1 {
|
|
|
+ transform: skewY(-30deg);
|
|
|
+ transform-origin: left;
|
|
|
+ @include getPosition(180px, 178px, 122px, 1px);
|
|
|
}
|
|
|
- .ctext {
|
|
|
- height: 20px;
|
|
|
- line-height: 20px;
|
|
|
- white-space: nowrap;
|
|
|
- text-align: center;
|
|
|
- width: 100%;
|
|
|
- bottom: -30px;
|
|
|
- position: absolute;
|
|
|
- color: #333333;
|
|
|
+
|
|
|
+ &.l2 {
|
|
|
+ @include getPosition(402px, 92px, 107px, 1px);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.l3 {
|
|
|
+ @include getPosition(638px, 92px, 107px, 1px);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.l4 {
|
|
|
+ @include getPosition(808px, 129px, 1px, 80px);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.l5 {
|
|
|
+ transform: skewY(30deg);
|
|
|
+ transform-origin: left;
|
|
|
+ @include getPosition(170px, 244px, 122px, 1px);
|
|
|
}
|
|
|
- .msr {
|
|
|
- @include getPosition(11px, 80px, 242px, 236px);
|
|
|
+
|
|
|
+ &.l6 {
|
|
|
+ @include getPosition(234px, 209px, 258px, 1px);
|
|
|
}
|
|
|
- .device {
|
|
|
- @include getPosition(280px, 38px, 138px, 138px);
|
|
|
+
|
|
|
+ &.l7 {
|
|
|
+ @include getPosition(490px, 209px, 1px, 105px);
|
|
|
}
|
|
|
- .sending_device {
|
|
|
- @include getPosition(515px, 38px, 138px, 138px);
|
|
|
+
|
|
|
+ &.l8 {
|
|
|
+ @include getPosition(490px, 314px, 52px, 1px);
|
|
|
}
|
|
|
- .receive_card {
|
|
|
- @include getPosition(750px, 38px, 138px, 138px);
|
|
|
+
|
|
|
+ &.l9 {
|
|
|
+ @include getPosition(490px, 209px, 52px, 1px);
|
|
|
}
|
|
|
- .trafficCamera {
|
|
|
- @include getPosition(599px, 225px, 79px, 79px);
|
|
|
+
|
|
|
+ &.l10 {
|
|
|
+ @include getPosition(402px, 369px, 268px, 1px);
|
|
|
}
|
|
|
- .gateway {
|
|
|
- @include getPosition(280px, 279px, 138px, 138px);
|
|
|
+}
|
|
|
+
|
|
|
+.o-link-device {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 1;
|
|
|
+
|
|
|
+ &__name {
|
|
|
+ position: absolute;
|
|
|
+ top: 100%;
|
|
|
+ left: 50%;
|
|
|
+ color: $black;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1;
|
|
|
+ white-space: nowrap;
|
|
|
+ transform: translateX(-50%);
|
|
|
}
|
|
|
- .led {
|
|
|
- @include getPosition(704px, 233px, 349px, 197px);
|
|
|
+
|
|
|
+ &.unbind {
|
|
|
+ background-image: url("~@/assets/linkState/icon_unbound.svg");
|
|
|
}
|
|
|
- .l1 {
|
|
|
- transform: skewY(-30deg);
|
|
|
- transform-origin: left;
|
|
|
- @include getPosition(192px, 216px, 122px, 1px);
|
|
|
+
|
|
|
+ &.msr {
|
|
|
+ @include getPosition(0, 42px, 242px, 236px);
|
|
|
+ background-image: url("~@/assets/linkState/icon_msr.svg");
|
|
|
}
|
|
|
- .l2 {
|
|
|
- @include getPosition(413px, 130px, 107px, 1px);
|
|
|
+
|
|
|
+ &.device {
|
|
|
+ @include getPosition(270px, 0, 138px, 138px);
|
|
|
+
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/linkState/icon_device_online.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/linkState/icon_device_offline.svg");
|
|
|
+ }
|
|
|
}
|
|
|
- .l3 {
|
|
|
- @include getPosition(648px, 130px, 107px, 1px);
|
|
|
+
|
|
|
+ &.sending_device {
|
|
|
+ @include getPosition(504px, 0, 138px, 138px);
|
|
|
+
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/linkState/icon_sending_device_online.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/linkState/icon_sending_device_offline.svg");
|
|
|
+ }
|
|
|
}
|
|
|
- .l4 {
|
|
|
- @include getPosition(819px, 167px, 1px, 66px);
|
|
|
+
|
|
|
+ &.receive_card {
|
|
|
+ @include getPosition(740px, 0, 138px, 138px);
|
|
|
+
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/linkState/icon_receive_card_online.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/linkState/icon_receive_card_offline.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ .o-link-device__name {
|
|
|
+ transform: translateX(8px);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.traffic_camera {
|
|
|
+ @include getPosition(528px, 162px, 79px, 79px);
|
|
|
}
|
|
|
- .l5 {
|
|
|
- @include getPosition(247px, 248px, 366px, 1px);
|
|
|
- &.trafficCameraUnbound {
|
|
|
- width: 364px;
|
|
|
+
|
|
|
+ &.led_camera {
|
|
|
+ @include getPosition(528px, 262px, 79px, 79px);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.traffic_camera,
|
|
|
+ &.led_camera {
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/linkState/icon_camera_online.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/linkState/icon_camera_offline.svg");
|
|
|
}
|
|
|
}
|
|
|
- .l6 {
|
|
|
- transform: skewY(30deg);
|
|
|
- transform-origin: left;
|
|
|
- @include getPosition(192px, 280px, 110px, 1px);
|
|
|
+
|
|
|
+ &.gateway {
|
|
|
+ @include getPosition(270px, 278px, 138px, 138px);
|
|
|
+
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/linkState/icon_gateway_online.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/linkState/icon_gateway_offline.svg");
|
|
|
+ }
|
|
|
}
|
|
|
- .l7 {
|
|
|
- @include getPosition(413px, 370px, 291px, 1px);
|
|
|
+
|
|
|
+ &.led {
|
|
|
+ @include getPosition(670px, 209px, 352px, 198px);
|
|
|
+ background-color: rgba(#000, 0.8);
|
|
|
+ background-position: center center;
|
|
|
+ background-size: contain;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+
|
|
|
+ &.online {
|
|
|
+ background-image: url("~@/assets/image_no_program.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ &.offline {
|
|
|
+ background-image: url("~@/assets/image_offline.svg");
|
|
|
+ }
|
|
|
+
|
|
|
+ .o-link-device__name {
|
|
|
+ top: -8px;
|
|
|
+ left: auto;
|
|
|
+ right: 0;
|
|
|
+ bottom: auto;
|
|
|
+ transform: translateY(-100%);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</style>
|