|
@@ -1,85 +1,67 @@
|
|
<template>
|
|
<template>
|
|
<div class="app-container">
|
|
<div class="app-container">
|
|
<div class="block">
|
|
<div class="block">
|
|
- <el-date-picker
|
|
|
|
- v-model="queryTime"
|
|
|
|
- type="date"
|
|
|
|
- :placeholder="this.$t('watch.dateKeywords')"
|
|
|
|
- value-format="yyyy-MM-dd">
|
|
|
|
|
|
+ <el-date-picker v-model="queryTime" type="date" :placeholder="this.$t('watch.dateKeywords')"
|
|
|
|
+ value-format="yyyy-MM-dd">
|
|
</el-date-picker>
|
|
</el-date-picker>
|
|
- <el-button type="primary" plain style="margin-left: 30px" v-loading.fullscreen.lock="fullscreenLoading" @click="getNewLocation">
|
|
|
|
|
|
+ <el-button type="primary" plain style="margin-left: 30px" v-loading.fullscreen.lock="fullscreenLoading"
|
|
|
|
+ @click="getNewLocation">
|
|
{{ this.$t('watch.getNewPlace') }}</el-button>
|
|
{{ this.$t('watch.getNewPlace') }}</el-button>
|
|
<el-tag v-if="myTitle" style="margin-left: 20px;" type="warning">{{ myTitle }}</el-tag>
|
|
<el-tag v-if="myTitle" style="margin-left: 20px;" type="warning">{{ myTitle }}</el-tag>
|
|
|
|
+
|
|
|
|
+<div class="color-legend">
|
|
|
|
+ <div class="legend-item">
|
|
|
|
+ <span class="color-dot green"></span>
|
|
|
|
+ <span>{{ this.$t('he20250514.currentPosition') }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="legend-item">
|
|
|
|
+ <span class="color-dot red"></span>
|
|
|
|
+ <span>{{ this.$t('he20250514.aiarmArea') }}</span>
|
|
|
|
+ </div>
|
|
|
|
+</div>
|
|
</div>
|
|
</div>
|
|
<div class="location-map">
|
|
<div class="location-map">
|
|
<div class="grid-background"></div>
|
|
<div class="grid-background"></div>
|
|
-
|
|
|
|
|
|
+ <!-- <svg class="path-overlay" :viewBox="viewBox"> -->
|
|
|
|
+ <!-- 背景虚线路径 -->
|
|
|
|
+ <!-- <path :d="pathData" class="movement-path-bg" stroke="#f7da98" stroke-width="3" stroke-dasharray="8,8"
|
|
|
|
+ fill="none" /> -->
|
|
|
|
+ <!-- 动态实线路径 -->
|
|
|
|
+ <!-- <path :d="pathData" class="movement-path" stroke="#409EFF" stroke-width="3" fill="none" /> -->
|
|
|
|
+ <!-- 移动点 -->
|
|
|
|
+ <!-- <circle v-if="pathData" class="moving-dot" r="6">
|
|
|
|
+ <animateMotion :path="pathData" dur="3s" repeatCount="indefinite" />
|
|
|
|
+ </circle>
|
|
|
|
+ </svg> -->
|
|
<div class="beacon-grid">
|
|
<div class="beacon-grid">
|
|
<el-card
|
|
<el-card
|
|
- v-for="item in beaconDevices"
|
|
|
|
- :key="item.id"
|
|
|
|
- :id="'myFrame'+item.id"
|
|
|
|
- class="beacon-point"
|
|
|
|
- :class="{
|
|
|
|
- 'active': isBeaconActive(item.id),
|
|
|
|
- 'fence': item.device_type === 39
|
|
|
|
- }"
|
|
|
|
- :style="getBeaconStyle(item)">
|
|
|
|
- <div :class="['beacon-content', {
|
|
|
|
- 'active': isBeaconActive(item.id),
|
|
|
|
- 'fence': item.device_type === 39
|
|
|
|
- }]">
|
|
|
|
|
|
+ v-for="item in beaconDevices"
|
|
|
|
+ :key="item.id" :id="'myFrame' + item.id"
|
|
|
|
+ class="beacon-point" :class="{
|
|
|
|
+ 'active': isBeaconActive(item.id),
|
|
|
|
+ 'fence': item.device_type === 39
|
|
|
|
+ }"
|
|
|
|
+ :style="getBeaconStyle(item)">
|
|
|
|
+ <div :class="['beacon-content', {'active': isBeaconActive(item.id), 'fence': item.device_type === 39 }]">
|
|
<div class="beacon-icon">
|
|
<div class="beacon-icon">
|
|
- <div :class="['radar-wave', {
|
|
|
|
- 'fence-wave': item.device_type === 39
|
|
|
|
- }]" v-if="isBeaconActive(item.id)"></div>
|
|
|
|
- <svg-icon
|
|
|
|
- :id="'myIcon' + item.id"
|
|
|
|
- icon-class="footmark"
|
|
|
|
- class="footmark-icon"
|
|
|
|
- :style="{
|
|
|
|
- display: isBeaconActive(item.id) ? 'inline-block' : 'none',
|
|
|
|
- color: item.device_type === 39 ? '#fff' : ''
|
|
|
|
- }" />
|
|
|
|
|
|
+ <div :class="['radar-wave', {'fence-wave': item.device_type === 39}]" v-if="isBeaconActive(item.id)"></div>
|
|
|
|
+ <svg-icon :id="'myIcon' + item.id" icon-class="footmark" class="footmark-icon"
|
|
|
|
+ :style="{display: isBeaconActive(item.id) ? 'inline-block' : 'none',color: item.device_type === 39 ? '#fff' : '' }" />
|
|
</div>
|
|
</div>
|
|
<div class="beacon-name">{{ item.name }}</div>
|
|
<div class="beacon-name">{{ item.name }}</div>
|
|
- <div :id="'myText' + item.id" class="sequence-number"></div>
|
|
|
|
|
|
+ <!-- <div :id="'myText' + item.id" class="sequence-number"></div> -->
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <svg class="path-overlay" :viewBox="viewBox">
|
|
|
|
- <path
|
|
|
|
- :d="pathData"
|
|
|
|
- class="movement-path-bg"
|
|
|
|
- stroke="#E1E1E1"
|
|
|
|
- stroke-width="3"
|
|
|
|
- stroke-dasharray="5,5"
|
|
|
|
- fill="none" />
|
|
|
|
- <path
|
|
|
|
- :d="pathData"
|
|
|
|
- class="movement-path"
|
|
|
|
- fill="none" />
|
|
|
|
- <circle
|
|
|
|
- v-if="pathData"
|
|
|
|
- class="moving-dot"
|
|
|
|
- r="6"
|
|
|
|
- fill="#409EFF">
|
|
|
|
- <animateMotion
|
|
|
|
- :path="pathData"
|
|
|
|
- dur="3s"
|
|
|
|
- repeatCount="indefinite" />
|
|
|
|
- </circle>
|
|
|
|
- </svg>
|
|
|
|
|
|
+
|
|
|
|
+
|
|
</div>
|
|
</div>
|
|
<div v-if="locationList.length > 0" class="timeline-container">
|
|
<div v-if="locationList.length > 0" class="timeline-container">
|
|
<el-timeline>
|
|
<el-timeline>
|
|
- <el-timeline-item
|
|
|
|
- v-for="(item, index) in locationList"
|
|
|
|
- :key="index"
|
|
|
|
- :timestamp="formatterCreateTime(item.create_time)"
|
|
|
|
- :type="getTimelineItemType(index)">
|
|
|
|
- <el-card class="timeline-card" :class="{'current-location': index === 0}">
|
|
|
|
|
|
+ <el-timeline-item v-for="(item, index) in locationList"
|
|
|
|
+ :key="index"
|
|
|
|
+ :timestamp="formatterCreateTime(item.create_time)" :type="getTimelineItemType(index)">
|
|
|
|
+ <el-card class="timeline-card" :class="{ 'current-location': index === 0 }">
|
|
<div class="location-info">
|
|
<div class="location-info">
|
|
<i class="el-icon-location-outline"></i>
|
|
<i class="el-icon-location-outline"></i>
|
|
<span>{{ item.full_name }}</span>
|
|
<span>{{ item.full_name }}</span>
|
|
@@ -89,17 +71,9 @@
|
|
</el-timeline-item>
|
|
</el-timeline-item>
|
|
</el-timeline>
|
|
</el-timeline>
|
|
</div>
|
|
</div>
|
|
- <el-pagination
|
|
|
|
- v-if="pageData"
|
|
|
|
- slot="pagination"
|
|
|
|
- :current-page="pageData.page_no"
|
|
|
|
- :page-sizes="[20, 50, 100, 200]"
|
|
|
|
- :page-size="pageData.page_size"
|
|
|
|
- layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
- :total="pageData.data_total"
|
|
|
|
- @size-change="handlePageSizeChange"
|
|
|
|
- @current-change="handlePageCurrentChange"
|
|
|
|
- />
|
|
|
|
|
|
+ <el-pagination v-if="pageData" slot="pagination" :current-page="pageData.page_no" :page-sizes="[20, 50, 100, 200]"
|
|
|
|
+ :page-size="pageData.page_size" layout="total, sizes, prev, pager, next, jumper" :total="pageData.data_total"
|
|
|
|
+ @size-change="handlePageSizeChange" @current-change="handlePageCurrentChange" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -123,8 +97,7 @@ export default {
|
|
default: false
|
|
default: false
|
|
}
|
|
}
|
|
},
|
|
},
|
|
-
|
|
|
|
- data: function() {
|
|
|
|
|
|
+ data: function () {
|
|
return {
|
|
return {
|
|
beaconDevices: [],
|
|
beaconDevices: [],
|
|
locationList: [],
|
|
locationList: [],
|
|
@@ -145,7 +118,8 @@ export default {
|
|
myTitle: '',
|
|
myTitle: '',
|
|
pathData: '',
|
|
pathData: '',
|
|
viewBox: '0 0 1000 1000',
|
|
viewBox: '0 0 1000 1000',
|
|
- gridPositions: null
|
|
|
|
|
|
+ gridPositions: null,
|
|
|
|
+
|
|
}
|
|
}
|
|
},
|
|
},
|
|
watch: {
|
|
watch: {
|
|
@@ -190,7 +164,7 @@ export default {
|
|
}
|
|
}
|
|
_this.locationList = []
|
|
_this.locationList = []
|
|
if (_this.tableData.length > 0) {
|
|
if (_this.tableData.length > 0) {
|
|
- _this.changeStyle()
|
|
|
|
|
|
+ _this.changeStyle()
|
|
}
|
|
}
|
|
})
|
|
})
|
|
},
|
|
},
|
|
@@ -202,7 +176,7 @@ export default {
|
|
_this.myTitle = this.$t('watch.notCovered')
|
|
_this.myTitle = this.$t('watch.notCovered')
|
|
}
|
|
}
|
|
this.tableData.reverse()
|
|
this.tableData.reverse()
|
|
- for (let i = 0; i< _this.tableData.length; i++) {
|
|
|
|
|
|
+ for (let i = 0; i < _this.tableData.length; i++) {
|
|
(function (t, data) {
|
|
(function (t, data) {
|
|
setTimeout(function () {
|
|
setTimeout(function () {
|
|
if (myId) {
|
|
if (myId) {
|
|
@@ -217,7 +191,7 @@ export default {
|
|
prevElement.style.color = prevBeacon?.device_type === 39 ? 'white' : '#333'
|
|
prevElement.style.color = prevBeacon?.device_type === 39 ? 'white' : '#333'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- const currentElement = document.getElementById('myFrame'+data.beacon_device_id)
|
|
|
|
|
|
+ const currentElement = document.getElementById('myFrame' + data.beacon_device_id)
|
|
if (currentElement) {
|
|
if (currentElement) {
|
|
const beacon = _this.beaconDevices.find(b => b.id === data.beacon_device_id)
|
|
const beacon = _this.beaconDevices.find(b => b.id === data.beacon_device_id)
|
|
if (beacon && beacon.device_type === 39) {
|
|
if (beacon && beacon.device_type === 39) {
|
|
@@ -228,7 +202,7 @@ export default {
|
|
currentElement.style.color = 'white'
|
|
currentElement.style.color = 'white'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- document.getElementById('myIcon'+data.beacon_device_id).style.display='inline'
|
|
|
|
|
|
+ document.getElementById('myIcon' + data.beacon_device_id).style.display = 'inline'
|
|
_this.$notify({
|
|
_this.$notify({
|
|
title: data.full_name,
|
|
title: data.full_name,
|
|
message: unixToDate(data.create_time) + _this.$t('watch.in') + data.full_name + _this.$t('watch.nearby'),
|
|
message: unixToDate(data.create_time) + _this.$t('watch.in') + data.full_name + _this.$t('watch.nearby'),
|
|
@@ -238,19 +212,22 @@ export default {
|
|
})
|
|
})
|
|
myId = 'myFrame'+data.beacon_device_id
|
|
myId = 'myFrame'+data.beacon_device_id
|
|
_this.locationList.unshift(data)
|
|
_this.locationList.unshift(data)
|
|
- let text = document.getElementById('myText'+data.beacon_device_id)
|
|
|
|
- if (text.innerText) {
|
|
|
|
- text.innerText = text.innerText + '、'+ (i+1)
|
|
|
|
- } else {
|
|
|
|
- text.innerText = (i+1)
|
|
|
|
- }
|
|
|
|
|
|
+ // let text = document.getElementById('myText' + data.beacon_device_id)
|
|
|
|
+ // if (text.innerText) {
|
|
|
|
+ // text.innerText = text.innerText + '、' + (i + 1)
|
|
|
|
+ // } else {
|
|
|
|
+ // text.innerText = (i + 1)
|
|
|
|
+ // }
|
|
if (_this.clearList.find(p => p === data.beacon_device_id) == null) {
|
|
if (_this.clearList.find(p => p === data.beacon_device_id) == null) {
|
|
_this.clearList.push(data.beacon_device_id)
|
|
_this.clearList.push(data.beacon_device_id)
|
|
}
|
|
}
|
|
|
|
+ // if (t === _this.tableData.length - 1) {
|
|
|
|
+ // _this.updateMovementPath()
|
|
|
|
+ // }
|
|
}, 250 * t)
|
|
}, 250 * t)
|
|
})(i, _this.tableData[i])
|
|
})(i, _this.tableData[i])
|
|
}
|
|
}
|
|
- this.updateMovementPath()
|
|
|
|
|
|
+ // this.updateMovementPath()
|
|
},
|
|
},
|
|
sx() {
|
|
sx() {
|
|
this.queryTime = null
|
|
this.queryTime = null
|
|
@@ -289,8 +266,8 @@ export default {
|
|
} else {
|
|
} else {
|
|
element.style = ''
|
|
element.style = ''
|
|
}
|
|
}
|
|
- document.getElementById('myIcon'+item).style.display='none'
|
|
|
|
- document.getElementById('myText'+item).innerText = ''
|
|
|
|
|
|
+ document.getElementById('myIcon' + item).style.display = 'none'
|
|
|
|
+ document.getElementById('myText' + item).innerText = ''
|
|
})
|
|
})
|
|
},
|
|
},
|
|
formatterCreateTime(data) {
|
|
formatterCreateTime(data) {
|
|
@@ -305,7 +282,7 @@ export default {
|
|
}, 30000)
|
|
}, 30000)
|
|
this.websock.send(this.deviceId)
|
|
this.websock.send(this.deviceId)
|
|
},
|
|
},
|
|
- initWebSocket: function() {
|
|
|
|
|
|
+ initWebSocket: function () {
|
|
const stockbase = DeviceUrl.replace('http', 'ws')
|
|
const stockbase = DeviceUrl.replace('http', 'ws')
|
|
this.websock = new WebSocket(stockbase + '/web-socket/device_location/' + this.deviceId)
|
|
this.websock = new WebSocket(stockbase + '/web-socket/device_location/' + this.deviceId)
|
|
this.websock.onopen = this.websocketonopen
|
|
this.websock.onopen = this.websocketonopen
|
|
@@ -313,13 +290,13 @@ export default {
|
|
this.websock.onmessage = this.websocketonmessage
|
|
this.websock.onmessage = this.websocketonmessage
|
|
this.websock.onclose = this.websocketclose
|
|
this.websock.onclose = this.websocketclose
|
|
},
|
|
},
|
|
- websocketonopen: function() {
|
|
|
|
|
|
+ websocketonopen: function () {
|
|
console.log(this.$t('deviceManage.webSocketSuccess'))
|
|
console.log(this.$t('deviceManage.webSocketSuccess'))
|
|
},
|
|
},
|
|
- websocketonerror: function(e) {
|
|
|
|
|
|
+ websocketonerror: function (e) {
|
|
console.log(this.$t('deviceManage.webSocketError'))
|
|
console.log(this.$t('deviceManage.webSocketError'))
|
|
},
|
|
},
|
|
- websocketonmessage: function(e) {
|
|
|
|
|
|
+ websocketonmessage: function (e) {
|
|
console.log(this.$t('action.getMsg'), e.data)
|
|
console.log(this.$t('action.getMsg'), e.data)
|
|
const data = JSON.parse(e.data)
|
|
const data = JSON.parse(e.data)
|
|
if (data.beacon_device_id) {
|
|
if (data.beacon_device_id) {
|
|
@@ -327,24 +304,26 @@ export default {
|
|
this.fullscreenLoading = false
|
|
this.fullscreenLoading = false
|
|
let size = this.tableData.length
|
|
let size = this.tableData.length
|
|
if (size > 0) {
|
|
if (size > 0) {
|
|
- document.getElementById('myFrame'+this.tableData[(size - 1)].beacon_device_id).style = 'background: #d3dce6'
|
|
|
|
|
|
+ document.getElementById('myFrame' + this.tableData[(size - 1)].beacon_device_id).style = 'background: #d3dce6'
|
|
}
|
|
}
|
|
- document.getElementById('myFrame'+data.beacon_device_id).style = 'color: white;background: #3DCB0A'
|
|
|
|
- document.getElementById('myIcon'+data.beacon_device_id).style.display='inline'
|
|
|
|
|
|
+ document.getElementById('myFrame' + data.beacon_device_id).style = 'color: white;background: #3DCB0A'
|
|
|
|
+ document.getElementById('myIcon' + data.beacon_device_id).style.display = 'inline'
|
|
this.$notify({
|
|
this.$notify({
|
|
title: data.full_name,
|
|
title: data.full_name,
|
|
message: unixToDate(data.create_time) + this.$t('watch.in') + data.full_name + this.$t('watch.nearby'),
|
|
message: unixToDate(data.create_time) + this.$t('watch.in') + data.full_name + this.$t('watch.nearby'),
|
|
showClose: false,
|
|
showClose: false,
|
|
offset: 100
|
|
offset: 100
|
|
})
|
|
})
|
|
- let text = document.getElementById('myText'+data.beacon_device_id)
|
|
|
|
- if (text.innerText) {
|
|
|
|
- text.innerText = text.innerText + '、'+ (size+1)
|
|
|
|
- } else {
|
|
|
|
- text.innerText = (i+1)
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ // let text = document.getElementById('myText' + data.beacon_device_id)
|
|
|
|
+ // if (text.innerText) {
|
|
|
|
+ // text.innerText = text.innerText + '、' + (size + 1)
|
|
|
|
+ // } else {
|
|
|
|
+ // text.innerText = (i + 1)
|
|
|
|
+ // }
|
|
this.tableData.push(data)
|
|
this.tableData.push(data)
|
|
this.locationList.unshift(data)
|
|
this.locationList.unshift(data)
|
|
|
|
+ console.log('websocketonmessage连接赋值', this.locationList)
|
|
if (this.clearList.find(p => p === data.beacon_device_id) == null) {
|
|
if (this.clearList.find(p => p === data.beacon_device_id) == null) {
|
|
this.clearList.push(data.beacon_device_id)
|
|
this.clearList.push(data.beacon_device_id)
|
|
}
|
|
}
|
|
@@ -377,17 +356,16 @@ export default {
|
|
}
|
|
}
|
|
},
|
|
},
|
|
isBeaconActive(beaconId) {
|
|
isBeaconActive(beaconId) {
|
|
- return this.locationList.length > 0 &&
|
|
|
|
|
|
+ return this.locationList.length > 0 &&
|
|
this.locationList[0].beacon_device_id === beaconId
|
|
this.locationList[0].beacon_device_id === beaconId
|
|
},
|
|
},
|
|
updateMovementPath() {
|
|
updateMovementPath() {
|
|
if (this.locationList.length < 2 || !this.gridPositions) return
|
|
if (this.locationList.length < 2 || !this.gridPositions) return
|
|
-
|
|
|
|
|
|
+
|
|
const points = this.locationList.map(location => {
|
|
const points = this.locationList.map(location => {
|
|
const pos = this.gridPositions[location.beacon_device_id]
|
|
const pos = this.gridPositions[location.beacon_device_id]
|
|
return `${pos.x * 100},${pos.y * 100}`
|
|
return `${pos.x * 100},${pos.y * 100}`
|
|
})
|
|
})
|
|
-
|
|
|
|
this.pathData = `M ${points.join(' L ')}`
|
|
this.pathData = `M ${points.join(' L ')}`
|
|
},
|
|
},
|
|
getTimelineItemType(index) {
|
|
getTimelineItemType(index) {
|
|
@@ -403,20 +381,46 @@ export default {
|
|
.location-map {
|
|
.location-map {
|
|
position: relative;
|
|
position: relative;
|
|
margin: 20px 0;
|
|
margin: 20px 0;
|
|
- height: 600px;
|
|
|
|
|
|
+ height: 200px;
|
|
background: #f8fafc;
|
|
background: #f8fafc;
|
|
border-radius: 8px;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
padding: 20px;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+.block {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+.color-legend {
|
|
|
|
+ margin-left: auto;
|
|
|
|
+ display: flex;
|
|
|
|
+ gap: 20px;
|
|
|
|
+}
|
|
|
|
+.legend-item {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ gap: 8px;
|
|
|
|
+}
|
|
|
|
+.color-dot {
|
|
|
|
+ width: 12px;
|
|
|
|
+ height: 12px;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+
|
|
|
|
+ &.green {
|
|
|
|
+ background: #3DCB0A;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.red {
|
|
|
|
+ background: #F56C6C;
|
|
|
|
+ }
|
|
|
|
+}
|
|
.grid-background {
|
|
.grid-background {
|
|
position: absolute;
|
|
position: absolute;
|
|
top: 0;
|
|
top: 0;
|
|
left: 0;
|
|
left: 0;
|
|
right: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
bottom: 0;
|
|
- background-image:
|
|
|
|
|
|
+ background-image:
|
|
linear-gradient(rgba(200, 200, 200, 0.1) 1px, transparent 1px),
|
|
linear-gradient(rgba(200, 200, 200, 0.1) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(200, 200, 200, 0.1) 1px, transparent 1px);
|
|
linear-gradient(90deg, rgba(200, 200, 200, 0.1) 1px, transparent 1px);
|
|
background-size: 20px 20px;
|
|
background-size: 20px 20px;
|
|
@@ -424,80 +428,84 @@ export default {
|
|
|
|
|
|
.beacon-grid {
|
|
.beacon-grid {
|
|
display: grid;
|
|
display: grid;
|
|
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
|
|
|
|
+ grid-template-columns: repeat(auto-fit, minmax(75px, 1fr));
|
|
gap: 20px;
|
|
gap: 20px;
|
|
- height: 100%;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
.beacon-point {
|
|
.beacon-point {
|
|
position: relative;
|
|
position: relative;
|
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
- background: white;
|
|
|
|
|
|
+ background: #cfdce0;
|
|
border: none;
|
|
border: none;
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
-
|
|
|
|
&:hover {
|
|
&:hover {
|
|
transform: translateY(-2px);
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.1);
|
|
box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.1);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
&.active {
|
|
&.active {
|
|
transform: scale(1.05);
|
|
transform: scale(1.05);
|
|
background: #3DCB0A;
|
|
background: #3DCB0A;
|
|
box-shadow: 0 0 25px rgba(61, 203, 10, 0.4);
|
|
box-shadow: 0 0 25px rgba(61, 203, 10, 0.4);
|
|
-
|
|
|
|
|
|
+
|
|
.beacon-content {
|
|
.beacon-content {
|
|
color: white;
|
|
color: white;
|
|
-
|
|
|
|
|
|
+
|
|
.sequence-number {
|
|
.sequence-number {
|
|
color: rgba(255, 255, 255, 0.8);
|
|
color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
&.fence {
|
|
&.fence {
|
|
background: #F56C6C !important;
|
|
background: #F56C6C !important;
|
|
-
|
|
|
|
|
|
+
|
|
.beacon-content {
|
|
.beacon-content {
|
|
color: white !important;
|
|
color: white !important;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
&:hover {
|
|
&:hover {
|
|
box-shadow: 0 8px 15px -3px rgba(245, 108, 108, 0.4);
|
|
box-shadow: 0 8px 15px -3px rgba(245, 108, 108, 0.4);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
&.active {
|
|
&.active {
|
|
box-shadow: 0 0 25px rgba(245, 108, 108, 0.6);
|
|
box-shadow: 0 0 25px rgba(245, 108, 108, 0.6);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
.beacon-content {
|
|
.beacon-content {
|
|
- text-align: center;
|
|
|
|
- padding: 10px;
|
|
|
|
-
|
|
|
|
|
|
+ position: relative; // 添加相对
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center; // 添加水平居中
|
|
|
|
+ align-items: center;
|
|
|
|
+
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+
|
|
&.active {
|
|
&.active {
|
|
color: white;
|
|
color: white;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
&.fence {
|
|
&.fence {
|
|
color: white;
|
|
color: white;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
.beacon-name {
|
|
.beacon-name {
|
|
- margin: 8px 0;
|
|
|
|
|
|
+ // margin: 12px 0;
|
|
|
|
+ text-align: center; // 文字居中
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
|
|
.beacon-icon {
|
|
.beacon-icon {
|
|
- position: relative;
|
|
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 8px;
|
|
|
|
+ top: 50%;
|
|
|
|
+ transform: translateY(-50%); // 调整垂直居中位置
|
|
width: 48px;
|
|
width: 48px;
|
|
height: 48px;
|
|
height: 48px;
|
|
- margin: 0 auto 12px;
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- justify-content: center;
|
|
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ align-items: center; /* 垂直居中对齐雷达波和图标 */
|
|
}
|
|
}
|
|
|
|
|
|
.radar-wave {
|
|
.radar-wave {
|
|
@@ -507,7 +515,7 @@ export default {
|
|
border-radius: 50%;
|
|
border-radius: 50%;
|
|
background: rgba(61, 203, 10, 0.2);
|
|
background: rgba(61, 203, 10, 0.2);
|
|
animation: radar-pulse 2s infinite;
|
|
animation: radar-pulse 2s infinite;
|
|
-
|
|
|
|
|
|
+
|
|
&.fence-wave {
|
|
&.fence-wave {
|
|
background: rgba(245, 108, 108, 0.2);
|
|
background: rgba(245, 108, 108, 0.2);
|
|
}
|
|
}
|
|
@@ -545,8 +553,14 @@ export default {
|
|
|
|
|
|
.timeline-container {
|
|
.timeline-container {
|
|
margin: 20px 0;
|
|
margin: 20px 0;
|
|
- max-height: 300px;
|
|
|
|
|
|
+ max-height: 475px;
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
|
|
+ ::v-deep .el-timeline-item__tail{
|
|
|
|
+ left:6px
|
|
|
|
+ }
|
|
|
|
+ ::v-deep .el-timeline-item__node--normal {
|
|
|
|
+ left:0 ;
|
|
|
|
+}
|
|
}
|
|
}
|
|
|
|
|
|
.timeline-card {
|
|
.timeline-card {
|