2025-09-19 20:29:04 +08:00
|
|
|
|
<template>
|
2025-09-20 14:14:38 +08:00
|
|
|
|
<el-row style="height: 100%;">
|
|
|
|
|
|
<el-card style="width: 100%;border-radius: 12px;height: 100%;">
|
2025-09-23 10:50:47 +08:00
|
|
|
|
<div style="display: flex;width: 100%;justify-content: flex-end;align-items: center;padding-bottom: 15px;">
|
2025-09-20 14:14:38 +08:00
|
|
|
|
<TitleComponent title="实时视频监控" subtitle="查看所有已完成的巡检记录,跟进巡检报告" />
|
2025-09-19 20:29:04 +08:00
|
|
|
|
<span style="color: rgba(24, 109, 245, 1);display: flex;align-items: center; cursor: pointer;">
|
|
|
|
|
|
<span>
|
|
|
|
|
|
2025/06/30 12:00
|
|
|
|
|
|
刷新数据
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<el-icon>
|
2025-09-20 14:14:38 +08:00
|
|
|
|
<Refresh />
|
2025-09-19 20:29:04 +08:00
|
|
|
|
</el-icon>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
2025-09-20 14:14:38 +08:00
|
|
|
|
<div class="video-container">
|
|
|
|
|
|
<el-row gutter="20">
|
|
|
|
|
|
<!-- 扩展布局:左侧大视频 + 右侧小视频列 -->
|
|
|
|
|
|
<template v-if="isExpanded">
|
|
|
|
|
|
<!-- 左侧大视频(占 16 列) -->
|
|
|
|
|
|
<el-col :span="16">
|
|
|
|
|
|
<div class="item large" @click="() => { isExpanded = false; }">
|
|
|
|
|
|
<img :src="videoList[activeIndex].url" alt="">
|
|
|
|
|
|
<div class="title" v-if="isExpanded"
|
|
|
|
|
|
style="display: flex;justify-content: space-between;">
|
|
|
|
|
|
<div class="text">
|
|
|
|
|
|
{{ videoList[activeIndex].name }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="tools">
|
|
|
|
|
|
<img src="/assets/svg/huanyuan.svg" alt=""></img>
|
|
|
|
|
|
<img src="/assets/svg/quanpin.svg" alt=""></img>
|
|
|
|
|
|
<img src="/assets/svg/jietu.svg" alt="">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="title" v-else>{{ videoList[activeIndex].name }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
<!-- 右侧小视频列(占 8 列) -->
|
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
|
<el-row gutter="20">
|
|
|
|
|
|
<el-col :span="24" v-for="i in 3" :key="i">
|
|
|
|
|
|
<div class="item small" @click="() => {
|
2025-09-23 10:50:47 +08:00
|
|
|
|
// 计算要显示的视频索引 - 按照当前视频后面三个排序
|
|
|
|
|
|
const displayIndex = (activeIndex + i) % videoList.length;
|
|
|
|
|
|
activeIndex = displayIndex;
|
2025-09-20 14:14:38 +08:00
|
|
|
|
}">
|
2025-09-23 10:50:47 +08:00
|
|
|
|
<img :src="videoList[(activeIndex + i) % videoList.length].url" alt="">
|
|
|
|
|
|
<div class="title">{{ videoList[(activeIndex + i) % videoList.length].name }}
|
|
|
|
|
|
</div>
|
2025-09-20 14:14:38 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 普通布局:所有视频均匀排列 -->
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<el-col :span="8" v-for="(item, index) in videoList" :key="index">
|
|
|
|
|
|
<div class="item" @click="() => {
|
|
|
|
|
|
activeIndex = index;
|
|
|
|
|
|
isExpanded = true;
|
|
|
|
|
|
}">
|
|
|
|
|
|
<img :src="item.url" alt="">
|
|
|
|
|
|
<div class="title">{{ item.name }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-row>
|
2025-09-23 10:50:47 +08:00
|
|
|
|
<el-row v-if="!isExpanded">
|
2025-09-20 14:14:38 +08:00
|
|
|
|
<div class="pagination" v-if="activeTab !== 'record'">
|
|
|
|
|
|
<el-pagination layout="prev, pager, next, jumper, sizes" :total="totalRecords"
|
|
|
|
|
|
v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[20, 50, 100]"
|
|
|
|
|
|
@current-change="handlePageChange" @size-change="handleSizeChange"></el-pagination>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</div>
|
2025-09-19 20:29:04 +08:00
|
|
|
|
</el-card>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</template>
|
2025-09-20 14:14:38 +08:00
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref } from 'vue';
|
|
|
|
|
|
import { Refresh } from '@element-plus/icons-vue';
|
|
|
|
|
|
import TitleComponent from '@/components/TitleComponent';
|
|
|
|
|
|
const activeIndex = ref(-1); // 初始无选中,选中后为对应索引
|
|
|
|
|
|
const isExpanded = ref(false); // 初始为普通布局
|
|
|
|
|
|
const pageSize = ref(20);
|
|
|
|
|
|
const totalRecords = ref(100);
|
|
|
|
|
|
const videoList = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c144e8ba276a0e8a4a55c2.jpeg#bab7e2e06aae943525cacb13bd63e30d'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c144efb5e8b987e5ca6462.jpeg#5523cf094b2f8c3a79ea4eb330c99a30'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c144fbbad414f81995e90c.webp#230d8ca5ca39982518439db26e0ea899'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c1450640d5d2a02e2540b2.webp#adad2379a0b04d6968364e4fb1133f77'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c14543d56431f9d6f6808e.webp#16f0a0d8fab4f8ff3b39b04bfabac054'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c14578d56431f9d6f68981.jpg#e77150417f28a971be4846eb0be90373'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c145e03f22157da619a7ce.png#546ff44289a22bf175e1eca1f69cd8f9'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c1461fb5e8b987e5caa293.jpeg#870e4d2b88b487ecb8f2f0b956c45c08'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: 'A区d厂',
|
|
|
|
|
|
url: 'https://img.js.design/assets/img/68c1462dcbf9ed2271880b95.webp#ae7ae94ca84ce980e2d2281869335f06'
|
|
|
|
|
|
}
|
|
|
|
|
|
]);
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.video-container {
|
|
|
|
|
|
.item {
|
|
|
|
|
|
height: 220px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
border: 2px solid rgba(45, 119, 249, 1);
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
padding: 5px 0;
|
|
|
|
|
|
padding-left: 10px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
border-radius: 8px 8px 0px 0px;
|
|
|
|
|
|
background: linear-gradient(180deg, rgba(0, 0, 0, 0.73) 0%, rgba(0, 0, 0, 0.33) 100%);
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 大视频样式(高度与右侧三个小视频总高度对齐,考虑间距)
|
|
|
|
|
|
.large {
|
|
|
|
|
|
height: calc(220px * 3 + 20px * 2); // 高度为3个小视频高度加上2个间距
|
|
|
|
|
|
|
|
|
|
|
|
.tools {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 20px;
|
|
|
|
|
|
height: 20px;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin: 0 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 小视频样式(保持原高度,适配右侧单列)
|
|
|
|
|
|
.small {
|
|
|
|
|
|
height: 220px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|