205 lines
5.3 KiB
Vue
205 lines
5.3 KiB
Vue
<template>
|
||
<el-card class="playback-panel" header="轨迹控制台">
|
||
<el-row class="device-info" v-if="currentLog">
|
||
<el-col :span="24" class="info-item">
|
||
<span class="label">时间:</span>
|
||
<span class="value">{{ currentLog.at | dv}}</span>
|
||
</el-col>
|
||
<el-col :span="24" class="info-item">
|
||
<span class="label">位置:</span>
|
||
<span class="value">{{currentLog.longitude | dv}},{{currentLog.latitude | dv}}</span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">定位类型:</span>
|
||
<span class="value"><dict-tag :options="dict.type.device_location_type" :value="currentLog.type" size="mini"/></span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">状态:</span>
|
||
<span class="value"><dict-tag :options="dict.type.device_status" :value="currentLog.status" size="mini"/></span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">速度:</span>
|
||
<span class="value">{{ currentLog.speed | dv}} KM/H</span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">电压:</span>
|
||
<span class="value">{{ currentLog.voltage | dv}} V</span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">4G:</span>
|
||
<span class="value">{{ currentLog.signal | dv}}</span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">卫星:</span>
|
||
<span class="value">{{ currentLog.satellites | dv}}</span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">锁状态:</span>
|
||
<span class="value"><dict-tag :options="dict.type.device_lock_status" :value="currentLog.lockStatus" size="mini"/></span>
|
||
</el-col>
|
||
<el-col :span="12" class="info-item">
|
||
<span class="label">电门:</span>
|
||
<span class="value"><dict-tag :options="dict.type.device_quality" :value="currentLog.quality" size="mini"/></span>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<div class="playback-controls">
|
||
<el-slider
|
||
:value="sliderValue"
|
||
:max="maxIndex"
|
||
:format-tooltip="formatTooltip"
|
||
@input="handleSliderChange">
|
||
</el-slider>
|
||
|
||
<div class="control-buttons">
|
||
<el-button-group>
|
||
<el-button size="mini" :icon="isPlaying ? 'el-icon-video-pause' : 'el-icon-video-play'" @click="togglePlay">
|
||
{{ isPlaying ? '暂停' : '播放' }}
|
||
</el-button>
|
||
<el-button
|
||
v-for="speed in [1, 2, 4, 8]"
|
||
:key="speed"
|
||
size="mini"
|
||
:type="playbackSpeed === speed ? 'primary' : ''"
|
||
@click="setPlaybackSpeed(speed)">
|
||
{{ speed }}x
|
||
</el-button>
|
||
</el-button-group>
|
||
|
||
<el-button-group>
|
||
<el-button size="mini" icon="el-icon-arrow-left" @click="handlePrev">
|
||
</el-button>
|
||
<el-button size="mini" icon="el-icon-arrow-right" @click="handleNext">
|
||
</el-button>
|
||
</el-button-group>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'PlaybackPanel',
|
||
dicts: ['device_status', 'device_lock_status', 'device_quality', 'device_location_type'],
|
||
props: {
|
||
currentLog: {
|
||
type: Object,
|
||
default: () => ({})
|
||
},
|
||
maxIndex: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
isPlaying: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
playbackSpeed: {
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
currentIndex: {
|
||
type: Number,
|
||
required: true
|
||
},
|
||
locationLogList: {
|
||
type: Array,
|
||
default: () => []
|
||
}
|
||
},
|
||
computed: {
|
||
sliderValue() {
|
||
return this.currentIndex;
|
||
}
|
||
},
|
||
methods: {
|
||
formatTooltip(value) {
|
||
return this.locationLogList?.[value]?.at;
|
||
},
|
||
handleSliderChange(index) {
|
||
this.$emit('slider-change', index);
|
||
},
|
||
togglePlay() {
|
||
this.$emit('toggle-play');
|
||
},
|
||
setPlaybackSpeed(speed) {
|
||
this.$emit('speed-change', speed);
|
||
},
|
||
handlePrev() {
|
||
if (this.currentIndex > 0) {
|
||
this.$emit('slider-change', this.currentIndex - 1);
|
||
}
|
||
},
|
||
handleNext() {
|
||
if (this.currentIndex < this.maxIndex) {
|
||
this.$emit('slider-change', this.currentIndex + 1);
|
||
}
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.playback-panel {
|
||
position: absolute;
|
||
top: 60px;
|
||
right: 15px;
|
||
transform: none;
|
||
z-index: 100;
|
||
width: 400px;
|
||
background-color: rgba(255,255,255,0.5);
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
|
||
.device-info {
|
||
padding: 8px;
|
||
margin-bottom: 4px;
|
||
background-color: #f5f7fa7b;
|
||
border-radius: 4px;
|
||
|
||
.info-item {
|
||
font-size: 12px;
|
||
line-height: 1.4;
|
||
|
||
.label {
|
||
color: #606266;
|
||
}
|
||
|
||
.value {
|
||
color: #303133;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.playback-controls {
|
||
.time-display {
|
||
text-align: center;
|
||
margin-bottom: 16px;
|
||
font-size: 12px;
|
||
color: #606266;
|
||
}
|
||
|
||
.el-slider {
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.control-buttons {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 10px;
|
||
|
||
.el-button {
|
||
padding: 7px 12px;
|
||
}
|
||
|
||
.el-button-group {
|
||
.el-button {
|
||
margin-left: -1px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|