feat: 初步完成首页静态交互开发

dev
donghao 4 weeks ago
parent 03cb778c4b
commit b6923a9b6a

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

@ -0,0 +1,281 @@
<template>
<div class="chart1-container">
<!-- 主环形图 -->
<div class="main-chart" ref="mainChartRef"></div>
<!-- 右侧统计面板 -->
<div class="stats-panel">
<div class="chart-items">
<div class="chart-item" v-for="(item, index) in chartData" :key="index">
<!-- ECharts 小饼图容器 -->
<div class="mini-chart" :ref="chartRefs[index]"></div>
<!-- 文本内容 -->
<div class="item-text">
<span class="percent" :style="{ color: item.color }"
>{{ item.value }}%</span
>
<span class="desc">{{ item.name }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, watchEffect } from "vue";
import * as echarts from "echarts";
interface ChartItem {
percent: number;
desc: string;
color: string;
pieData: number[]; // [65, 35]
pieColors: string[]; //
}
export default defineComponent({
name: "Chart1",
setup() {
//
const mainChartRef = ref<HTMLDivElement | null>(null);
const miniChartRef = ref<HTMLDivElement | null>(null);
//
let mainChart: echarts.ECharts | null = null;
let miniChart: echarts.ECharts | null = null;
// ECharts ref
const chartRefs = ref<Ref<HTMLDivElement | null>[]>([]);
// const chartData = [
// {
// percent: 65,
// desc: "",
// color: "#488AFE",
// pieData: [65, 35],
// pieColors: ["#488AFE", "#ffffff44"],
// },
// {
// percent: 35,
// desc: "",
// color: "#F7D36D",
// pieData: [35, 65],
// pieColors: ["#F7D36D", "#ffffff44"],
// },
// ];
//
const chartData = [
{ value: 65, name: "撑杆折断", color: "#488AFE" },
{ value: 35, name: "撑杆弯曲", color: "#F7D36D" },
];
//
const initMainChart = () => {
if (!mainChartRef.value) return;
//
if (mainChart) {
mainChart.dispose();
}
mainChart = echarts.init(mainChartRef.value);
//
const blueGradient = new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{ offset: 0, color: "#488AFE" },
{ offset: 1, color: "#0E5BCC" },
]);
const yellowGradient = new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{ offset: 0, color: "#F7D36D" },
{ offset: 1, color: "#E6B83D" },
]);
const option = {
backgroundColor: "transparent",
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b}: {c}%",
},
series: [
{
name: "状态占比",
type: "pie",
radius: ["50%", "80%"], //
center: ["50%", "50%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 8,
borderColor: "#0b1b3a", //
borderWidth: 2,
},
label: {
show: false,
position: "center",
},
emphasis: {
label: {
show: true,
fontSize: "20",
fontWeight: "bold",
color: "#fff",
},
},
labelLine: {
show: false,
},
data: [
{
value: chartData[0].value,
name: chartData[0].name,
itemStyle: { color: blueGradient },
},
{
value: chartData[1].value,
name: chartData[1].name,
itemStyle: { color: yellowGradient },
},
],
},
],
};
mainChart.setOption(option);
};
//
const handleResize = () => {
mainChart?.resize();
miniChart?.resize();
};
onMounted(() => {
initMainChart();
window.addEventListener("resize", handleResize);
chartData.forEach((item, index) => {
const myChart = echarts.init(
chartRefs.value[index].value as HTMLDivElement
);
const option = {
series: [
{
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "50%"],
data: item.pieData,
itemStyle: {
color: (params: any) => item.pieColors[params.dataIndex],
borderColor: "#0b1b3a", //
borderWidth: 1,
},
label: { show: false },
labelLine: { show: false },
},
],
};
myChart.setOption(option);
});
});
//
const cleanup = () => {
window.removeEventListener("resize", handleResize);
mainChart?.dispose();
miniChart?.dispose();
};
//
watchEffect((onCleanup) => {
onCleanup(cleanup);
});
return {
mainChartRef,
miniChartRef,
chartRefs,
chartData,
};
},
});
</script>
<style lang="scss" scoped>
.chart1-container {
display: flex;
align-items: center;
gap: 24px;
padding: 20px;
border-radius: 12px;
width: 100%;
height: 100%;
//
.main-chart {
width: 100%;
height: 100%;
position: relative;
//
&::after {
content: "总计";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 18px;
font-weight: 500;
text-align: center;
line-height: 1.5;
}
}
//
.chart-items {
display: flex;
flex-direction: column;
gap: 10px;
.chart-item {
display: flex;
align-items: center;
gap: 8px;
.mini-chart {
width: 40px;
height: 40px;
}
.item-text {
display: flex;
flex-direction: column;
.percent {
font-weight: bold;
margin-bottom: 2px;
}
.desc {
font-size: 14px;
color: #ccc;
}
}
}
}
}
//
@media (max-width: 500px) {
.chart1-container {
flex-direction: column;
.main-chart {
width: 200px;
height: 200px;
}
}
}
</style>

@ -1,28 +1,4 @@
<template>
<div class="chart1-container">
<!-- 主环形图 -->
<div class="main-chart" ref="mainChartRef"></div>
<!-- 右侧统计面板 -->
<div class="stats-panel">
<div class="chart-items">
<div class="chart-item" v-for="(item, index) in chartData" :key="index">
<!-- ECharts 小饼图容器 -->
<div class="mini-chart" :ref="chartRefs[index]"></div>
<!-- 文本内容 -->
<div class="item-text">
<span class="percent" :style="{ color: item.color }"
>{{ item.value }}%</span
>
<span class="desc">{{ item.name }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { defineComponent, onMounted, ref, watchEffect } from "vue";
import * as echarts from "echarts";
interface ChartItem {
@ -33,249 +9,425 @@ interface ChartItem {
pieColors: string[]; //
}
export default defineComponent({
name: "Chart1",
setup() {
//
const mainChartRef = ref<HTMLDivElement | null>(null);
const miniChartRef = ref<HTMLDivElement | null>(null);
//
let mainChart: echarts.ECharts | null = null;
let miniChart: echarts.ECharts | null = null;
// ECharts ref
const chartRefs = ref<Ref<HTMLDivElement | null>[]>([]);
// const chartData = [
// {
// percent: 65,
// desc: "",
// color: "#488AFE",
// pieData: [65, 35],
// pieColors: ["#488AFE", "#ffffff44"],
// },
// {
// percent: 35,
// desc: "",
// color: "#F7D36D",
// pieData: [35, 65],
// pieColors: ["#F7D36D", "#ffffff44"],
// },
// ];
//
const chartData = [
{ value: 65, name: "撑杆折断", color: "#488AFE" },
{ value: 35, name: "撑杆弯曲", color: "#F7D36D" },
];
//
const initMainChart = () => {
if (!mainChartRef.value) return;
//
if (mainChart) {
mainChart.dispose();
}
mainChart = echarts.init(mainChartRef.value);
//
const blueGradient = new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{ offset: 0, color: "#488AFE" },
{ offset: 1, color: "#0E5BCC" },
]);
const yellowGradient = new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{ offset: 0, color: "#F7D36D" },
{ offset: 1, color: "#E6B83D" },
]);
const option = {
backgroundColor: "transparent",
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b}: {c}%",
//
const mainChartRef = ref<HTMLDivElement | null>(null);
const miniChartRef = ref<HTMLDivElement | null>(null);
//
let mainChart: echarts.ECharts | null = null;
let miniChart: echarts.ECharts | null = null;
// ECharts ref
const chartRefs = ref<Ref<HTMLDivElement | null>[]>([]);
// const chartData = [
// {
// percent: 65,
// desc: "",
// color: "#488AFE",
// pieData: [65, 35],
// pieColors: ["#488AFE", "#ffffff44"],
// },
// {
// percent: 35,
// desc: "",
// color: "#F7D36D",
// pieData: [35, 65],
// pieColors: ["#F7D36D", "#ffffff44"],
// },
// ];
//
const chartData = [
{ value: 65, name: "撑杆折断", color: "#488AFE" },
{ value: 35, name: "撑杆弯曲", color: "#F7D36D" },
];
function Pie() {
let dataArr = [];
for (var i = 0; i < 150; i++) {
if (i % 3 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: 10,
itemStyle: {
normal: {
color: "#fff",
borderWidth: 0,
borderColor: "rgba(0,0,0,0)",
},
},
});
} else {
dataArr.push({
name: (i + 1).toString(),
value: 25,
itemStyle: {
normal: {
color: "rgba(0,0,0,0)",
borderWidth: 0,
borderColor: "rgba(0,0,0,0)",
},
},
series: [
});
}
}
return dataArr;
}
//
const initMainChart = () => {
const chartDom = document.getElementById("poleMonitorChart");
const mainChart = echarts.init(chartDom);
const option = {
backgroundColor: "#031845",
tooltip: {
trigger: "item",
formatter: "{b} : {d}% <br/> {c}",
},
legend: {
orient: "horizontal",
icon: "circle",
bottom: 20,
x: "center",
textStyle: {
color: "#fff",
},
data: ["呜哈哈", "穷哈哈", "吾叉叉", "穷叉叉"],
},
series: [
{
type: "pie",
radius: ["35%", "50%"],
center: ["50%", "50%"],
color: [
"#0E7CE2",
"#FF8352",
"#E271DE",
"#F8456B",
"#00FFFF",
"#4AEAB0",
],
itemStyle: {
normal: {
borderColor: "#031845",
borderWidth: 10,
},
},
data: [
{
name: "状态占比",
type: "pie",
radius: ["50%", "80%"], //
center: ["50%", "50%"],
avoidLabelOverlap: false,
value: 335,
name: "呜哈哈",
},
{
value: 310,
name: "穷哈哈",
},
{
value: 234,
name: "吾叉叉",
},
{
value: 235,
name: "穷叉叉",
},
],
labelLine: {
normal: {
show: false,
},
},
label: {
normal: {
show: false,
},
},
},
{
type: "pie",
radius: ["12%", "14%"],
center: ["50%", "50%"],
color: ["#ffffff", "red"],
startAngle: 105,
data: [
{
value: 30,
name: "",
itemStyle: {
borderRadius: 8,
borderColor: "#0b1b3a", //
borderWidth: 2,
},
label: {
show: false,
position: "center",
normal: {
color: "transparent",
},
},
emphasis: {
label: {
show: true,
fontSize: "20",
fontWeight: "bold",
color: "#fff",
},
{
value: 5,
name: "",
itemStyle: {
normal: {
color: "transparent",
},
},
labelLine: {
show: false,
},
{
value: 65,
name: "ddd",
itemStyle: {
normal: {
color: "#ffffff",
},
},
data: [
{
value: chartData[0].value,
name: chartData[0].name,
itemStyle: { color: blueGradient },
},
],
labelLine: {
normal: {
show: false,
},
},
label: {
normal: {
show: false,
},
},
},
{
type: "pie",
radius: [0, "16%"],
center: ["50%", "50%"],
startAngle: 90,
data: [
{
value: 25,
name: "1",
itemStyle: {
normal: {
color: "transparent",
borderWidth: 4,
borderColor: "#ffffff",
},
{
value: chartData[1].value,
name: chartData[1].name,
itemStyle: { color: yellowGradient },
},
},
{
value: 75,
name: "2",
itemStyle: {
normal: {
color: "transparent",
},
],
},
},
],
};
mainChart.setOption(option);
};
selectedOffset: 10,
labelLine: {
normal: {
show: false,
},
},
label: {
normal: {
show: false,
},
},
},
{
type: "pie",
radius: ["53%", "54%"],
center: ["50%", "50%"],
color: [
"blue",
"transparent",
"blue",
"transparent",
"blue",
"transparent",
],
data: [
{
value: 17,
name: "11",
},
{
value: 17,
name: "22",
},
{
value: 17,
name: "33",
},
{
value: 17,
name: "44",
},
{
value: 17,
name: "55",
},
{
value: 17,
name: "66",
},
],
labelLine: {
normal: {
show: false,
},
},
label: {
normal: {
show: false,
},
},
},
{
type: "pie",
zlevel: 0,
silent: true,
radius: ["25%", "26%"],
z: 10,
label: {
normal: {
show: false,
},
},
labelLine: {
normal: {
show: false,
},
},
data: Pie(),
},
{
type: "pie",
zlevel: 0,
silent: true,
radius: ["34%", "36%"],
z: 10,
startAngle: 90,
label: {
normal: {
show: false,
},
},
color: ["red", "blue", "red", "blue"],
//
const handleResize = () => {
mainChart?.resize();
miniChart?.resize();
};
labelLine: {
normal: {
show: false,
},
},
onMounted(() => {
initMainChart();
window.addEventListener("resize", handleResize);
chartData.forEach((item, index) => {
const myChart = echarts.init(
chartRefs.value[index].value as HTMLDivElement
);
const option = {
series: [
{
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "50%"],
data: item.pieData,
itemStyle: {
color: (params: any) => item.pieColors[params.dataIndex],
borderColor: "#0b1b3a", //
borderWidth: 1,
data: [
{
name: "r1",
value: 25,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "rgba(51,149,191,0.5)",
},
{
offset: 1,
color: "rgba(51,149,191,0)",
},
]),
},
label: { show: false },
labelLine: { show: false },
},
],
};
myChart.setOption(option);
});
});
//
const cleanup = () => {
window.removeEventListener("resize", handleResize);
mainChart?.dispose();
miniChart?.dispose();
};
},
{
name: "r2",
value: 25,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "rgba(0,0,0,0)",
},
{
offset: 1,
color: "rgba(51,149,191,0.5)",
},
]),
},
},
},
{
name: "r3",
value: 25,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "rgba(51,149,191,0)",
},
{
offset: 1,
color: "rgba(51,149,191,0.5)",
},
]),
},
},
},
{
name: "r4",
value: 25,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "rgba(51,149,191,0.5)",
},
{
offset: 1,
color: "rgba(0,0,0,0)",
},
]),
},
},
},
],
},
],
};
mainChart.setOption(option);
};
//
const handleResize = () => {
mainChart?.resize();
// miniChart?.resize();
};
onMounted(() => {
initMainChart();
window.addEventListener("resize", handleResize);
});
//
watchEffect((onCleanup) => {
onCleanup(cleanup);
});
//
const cleanup = () => {
window.removeEventListener("resize", handleResize);
mainChart?.dispose();
miniChart?.dispose();
};
return {
mainChartRef,
miniChartRef,
chartRefs,
chartData,
};
},
//
watchEffect((onCleanup) => {
onCleanup(cleanup);
});
</script>
<style lang="scss" scoped>
.chart1-container {
display: flex;
align-items: center;
gap: 24px;
padding: 20px;
border-radius: 12px;
width: 100%;
height: 100%;
//
.main-chart {
width: 100%;
height: 100%;
position: relative;
//
&::after {
content: "总计";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 18px;
font-weight: 500;
text-align: center;
line-height: 1.5;
}
}
//
.chart-items {
display: flex;
flex-direction: column;
gap: 10px;
.chart-item {
display: flex;
align-items: center;
gap: 8px;
.mini-chart {
width: 40px;
height: 40px;
}
.item-text {
display: flex;
flex-direction: column;
.percent {
font-weight: bold;
margin-bottom: 2px;
}
.desc {
font-size: 14px;
color: #ccc;
}
}
}
}
}
//
@media (max-width: 500px) {
.chart1-container {
flex-direction: column;
.main-chart {
width: 200px;
height: 200px;
}
}
}
</style>
<template>
<div
class="main-chart"
ref="mainChartRef"
id="poleMonitorChart"
style="width: 100%; height: 100%"
></div>
</template>

@ -1,65 +1,212 @@
<template>
<div id="pieChart" style="width: 100%; height: 100%"></div>
</template>
<script setup>
<script setup lang="ts">
import * as echarts from "echarts";
function generateData(totalNum, bigvalue, smallvalue, color) {
let dataArr = [];
for (var i = 0; i < totalNum; i++) {
if (i % 2 === 0) {
dataArr.push({
name: (i + 1).toString(),
value: bigvalue,
itemStyle: {
normal: {
color: color,
borderWidth: 0,
},
},
});
} else {
dataArr.push({
name: (i + 1).toString(),
value: smallvalue,
itemStyle: {
normal: {
color: "rgba(0,0,0,0)",
borderWidth: 0,
},
},
});
}
}
return dataArr;
}
function initChart() {
const chartDom = document.getElementById("pieChart");
const myChart = echarts.init(chartDom);
const chartDom = document.getElementById("vehicleMonitorChart");
const mainChart = echarts.init(chartDom);
let bgColor = "";
let title = "总量";
let color = [
"#c065e7",
"#765deb",
"#3862d8",
"#6a89E2",
"#219CF9",
"#6efbbf",
"#40c057",
"#ffd351",
"#ff8e43",
"#f56b6d",
];
let echartData = [
{
name: "A类",
value: "3720",
},
{
name: "B类",
value: "2920",
},
{
name: "C类",
value: "2200",
},
{
name: "D类",
value: "1420",
},
{
name: "E类",
value: "3200",
},
{
name: "F类",
value: "2420",
},
{
name: "G类",
value: "2200",
},
{
name: "H类",
value: "1420",
},
{
name: "I类",
value: "3200",
},
{
name: "J类",
value: "2420",
},
];
let formatNumber = function (num) {
let reg = /(?=(\B)(\d{3})+$)/g;
return num.toString().replace(reg, ",");
};
let total = echartData.reduce((a, b) => {
return a + b.value * 1;
}, 0);
const option = {
backgroundColor: "",
backgroundColor: bgColor,
color: color,
tooltip: {
trigger: "item",
formatter: "{b}: {c} ({d}%)",
},
title: [
{
text: "",
top: 20,
left: 20,
textStyle: {
fontSize: 14,
color: "#666666",
fontWeight: 400,
},
show: false,
},
],
series: [
{
type: "pie",
radius: ["10%", "50%"],
avoidLabelOverlap: false,
label: {
show: true,
position: "outer",
formatter: "{b}: {d}%",
color: "#fff", // Set label text color to white
zlevel: 2,
roseType: "radius",
radius: ["10%", "65%"],
center: ["50%", "50%"],
data: echartData,
hoverAnimation: false,
itemStyle: {
normal: {
// borderColor: bgColor,
// borderWidth: 2,
},
},
labelLine: {
normal: {
length: 20,
length2: 30,
lineStyle: {
// color: '#e6e6e6'
},
},
},
label: {
show: true,
lineStyle: {
color: "#fff", // Set label line color to white
position: "outside",
formatter: "{name|{b}{d}%}\n{icon|}",
rich: {
icon: {
backgroundColor: "inherit",
borderRadius: 3,
width: 3,
height: 3,
padding: [3, 3, 0, -12],
},
name: {
fontSize: "10",
padding: [-12, 15, -20, 15],
color: "#fff",
},
},
},
data: [
{ value: 45, name: "小门搭扣丢失", itemStyle: { color: "#29ABE2" } },
{ value: 21, name: "门折页座脱落", itemStyle: { color: "#1BBC9B" } },
{ value: 8, name: "小窗裂纹", itemStyle: { color: "#F64747" } },
{ value: 6, name: "搭扣未搭", itemStyle: { color: "#9B59B6" } },
{ value: 5, name: "搭扣未搭", itemStyle: { color: "#F9690E" } },
{ value: 5, name: "下侧门板缺失", itemStyle: { color: "#F7CA18" } },
{
value: 10,
name: "Other",
itemStyle: { color: "rgba(255,255,255,0.1)" },
label: { show: false },
labelLine: { show: false },
}, // Remaining percentage
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
{
//
type: "pie",
zlevel: 1,
silent: true, //
radius: ["0%", "75%"],
center: ["50%", "50%"],
itemStyle: {
normal: {
show: false,
color: "#0E4E89",
},
},
labelLine: {
show: false,
normal: {
length: 10,
length2: 0,
lineStyle: {
color: "transparent",
},
},
},
label: {
show: false,
},
data: [100],
},
{
name: "不动外圆",
type: "pie",
zlevel: 1,
silent: true,
radius: ["74%", "75%"],
label: {
show: false,
},
data: generateData(300, 2, 1, "#3F7D97"),
},
],
};
myChart.setOption(option);
mainChart.setOption(option);
}
onMounted(() => {
initChart();
});
</script>
<template>
<div id="vehicleMonitorChart" style="width: 100%; height: 100%"></div>
</template>

@ -82,12 +82,12 @@
.el-table__header > thead {
color: #9fb5d7;
background-color: #104284 !important;
background-color: #0841A0 !important;
tr {
background-color: #104284 !important;
background-color: #0841A0 !important;
}
th {
background-color: #104284 !important;
background-color: #0841A0 !important;
}
}
}
@ -127,12 +127,12 @@
.el-table__header > thead {
color: #9fb5d7;
background-color: #104284 !important;
background-color: #0841A0 !important;
tr {
background-color: #104284 !important;
background-color: #0841A0 !important;
}
th {
background-color: #104284 !important;
background-color: #0841A0 !important;
}
}
}

@ -31,10 +31,9 @@
//
.fg-title {
font-family: "DingTalk JinBuTi"; //
font-family: "DouyinSansBold"; //
//
font-size: 16px;
font-weight: 700; //
color: #96e6ff; // ,
//
background: linear-gradient(to bottom, #ffffff, #96e6ff);
@ -42,6 +41,12 @@
background-clip: text;
-webkit-text-fill-color: transparent;
}
// 1
.fg-mark1 {
font-family: "DingTalk JinBuTi"; //
//
color: #1cecf5; // ,
}
//
.fg-icon {
width: 17px;
@ -65,6 +70,10 @@
@apply fg-button;
background: #009dff;
}
.fg-button-primary1 {
@apply fg-button;
background: #22bacb;
}
//
.fg-dialog {
@ -74,6 +83,8 @@
background-position: center;
background-repeat: no-repeat;
padding: 0 !important;
width: 816px;
height: 640px;
&.fg-dialog2 {
width: 1202px;
height: 602px;
@ -84,7 +95,7 @@
background-color: transparent;
background-image: url("@/assets/common/dialog_head_bg.png");
background-repeat: no-repeat;
.fg-dialog-header-close {
width: 50px;
height: 50px;
@ -92,7 +103,7 @@
right: -17px;
top: -17px;
z-index: 999999 !important;
cursor: pointer;
background-image: url("@/assets/common/dialog_close_icon.png");
background-size: 100% 100%;
background-position: center;

@ -159,6 +159,9 @@
height: 32px;
}
}
.el-progress-bar__outer{
background: rgba(255,255,255,0.3);
}
/* 修改下拉菜单背景色 */
.el-select-dropdown {

@ -1,9 +1,14 @@
// src/assets/fonts.scss
@font-face {
font-family: "DingTalk JinBuTi"; //
font-family: "DingTalk JinBuTi"; // 1
src: url("@/assets/fonts/DingTalk JinBuTi.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "DouyinSansBold"; // 2
src: url("@/assets/fonts/DouyinSansBold.otf") format("truetype");
font-weight: normal;
font-style: normal;
}

@ -1,6 +1,6 @@
.data-overview-wrap {
padding-top: 30px;
height: 849px;
height: 852px;
color: white;
font-family: "Arial", sans-serif;
.grid-container {
@ -37,29 +37,28 @@
}
}
.onTime-monitor-box {
// background: red;
.realTime-monitor-box {
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
margin: 0 24px;
background: url("@/assets/home/realTime_monitor_bg.png") no-repeat center;
background-size: contain;
}
.monitor-images {
width: 948px;
display: flex;
box-sizing: border-box;
gap: 16px;
padding: 20px 16px;
flex-wrap: wrap;
.monitor-images-item {
width: calc(50% - 8px);
// background-color: red;
height: 349px;
border: 1px dashed #ccc;
}
.monitor-images-left,
.monitor-images-right {
// flex: 1;
// position: relative;
position: relative;
img {
width: 100%;
// height: 100%;
@ -81,53 +80,34 @@
}
}
.device-info-box {
background: linear-gradient(180deg, rgba(7, 16, 19, 0) 0%, #081417 100%);
.device-info {
.total-device {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 15px;
.device-icon {
width: 80px;
height: 90px;
background: url("@/assets/common/deviceTotal.png") no-repeat center;
background-size: 100%;
}
.device-count {
margin-left: 15px;
.count-number {
font-size: 24px;
font-weight: bold;
.total-device {
.device-total-icon {
width: 80px;
height: 90px;
background: url("@/assets/common/deviceTotal.png") no-repeat center;
background-size: 100%;
}
}
}
.device-list {
box-sizing: border-box;
display: grid;
// grid-template-columns: repeat(3, 1fr);
padding: 0 16px 20px;
gap: 10px;
.device-card {
.device-list {
box-sizing: border-box;
// background: rgba(74, 126, 191, 0.1);
background-image: url("@/assets/common/deviceCardBg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
padding: 16px;
// border-radius: 4px;
display: grid;
padding: 24px 16px 24px;
gap: 16px;
.status-bar {
margin-top: 5px;
.device-card {
box-sizing: border-box;
width: 399px;
height: 195px;
background-image: url("@/assets/common/device_info_bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
padding: 16px;
}
}
}

@ -5,11 +5,13 @@ import TotalChart from "@/components/Charts/totalChart.vue";
import PoleMonitorChart from "@/components/Charts/poleMonitorChart.vue";
import VehicleMonitorChart from "@/components/Charts/vehicleMonitorChart.vue";
import HomeSubTitle from "@/components/HeaderBar/homeSubTitle.vue";
// import HomeSubTitle from "@/components/HomeSubTitle.vue";
import BarChart from "./components/BarChart.vue";
import PieChart from "./components/PieChart.vue";
import PieChartSmall from "./components/PieChartSmall.vue";
import DeviceStatus from "./components/DeviceStatus.vue";
import car_device_icon from "@/assets/home/car_device_icon.png";
import pole_device_icon from "@/assets/home/pole_device_icon.png";
import excavator_device_icon from "@/assets/home/excavator_device_icon.png";
import {
getDataOverviewApi,
getDeviceInfowApi,
@ -44,9 +46,7 @@ const searchForm = reactive({
pole: "1",
});
const deviceTotal = ref(0);
const carDevice = ref({});
const poleDevice = ref({});
const excavatorDevice = ref({});
const carFaultTotal = ref([]);
const poleFaultTotal = ref([]);
const imageFault = ref([]);
@ -54,6 +54,31 @@ const activeBtn = ref("month");
const isAlarmOpen = ref<Boolean>(false); //
const currentRow = ref<Record<string, any>>({}); //
const currFileList = ref<Record<string, any>[]>([]); //
const deviceInfo = reactive({
list: [
{
name: "车体检测设备",
bindVal: {
total: 0,
},
icon: car_device_icon,
},
{
name: "撑杆检测设备",
bindVal: {
total: 0,
},
icon: pole_device_icon,
},
{
name: "钩机检测设备",
bindVal: {
total: 0,
},
icon: excavator_device_icon,
},
],
});
const websocketStore = useWebSocketStore();
// messages
@ -94,10 +119,23 @@ const getDeviceInfo = async () => {
if (isSuccessApi(res)) {
const { data } = res;
deviceTotal.value = data.deviceTotal;
carDevice.value = data.appearance;
poleDevice.value = data.pole;
excavatorDevice.value = data.excavator;
// deviceStatus.value = data
deviceInfo.list = [
{
name: "车体检测设备",
bindVal: data?.appearance,
icon: car_device_icon,
},
{
name: "撑杆检测设备",
bindVal: data?.pole,
icon: pole_device_icon,
},
{
name: "钩机检测设备",
bindVal: data?.excavator,
icon: excavator_device_icon,
},
];
}
} catch (error) {
console.error("获取设备信息出错:", error);
@ -170,7 +208,7 @@ onMounted(() => {
<div class="grid-container">
<div class="grid-item">
<div class="module-header">
<HomeSubTitle title="检测总量汇总" >
<HomeSubTitle title="检测总量汇总">
<template #extra>
<div>
<el-button
@ -203,7 +241,7 @@ onMounted(() => {
</div>
<div class="grid-item">
<div class="module-header">
<HomeSubTitle title="车体监测" >
<HomeSubTitle title="车体监测">
<template #extra>
<el-select
v-model="searchForm.car"
@ -272,59 +310,55 @@ onMounted(() => {
</div>
</div>
<!-- 中部检测模块 -->
<div class="onTime-monitor-box">
<div class="module-header fg-title">
实时监测画面
<div class="realTime-monitor-box">
<div class="monitor-images">
<div class="w-full h-[35px] fg-title ">实时监测画面</div>
<div class="monitor-images-left monitor-images-item">
<img :src="imageFault[0]?.url" />
<div class="fault-info">{{ imageFault[0]?.fault_type }}</div>
</div>
<div class="monitor-images">
<div class="monitor-images-left monitor-images-item">
<img :src="imageFault[0]?.url" />
<div class="fault-info">{{ imageFault[0]?.fault_type }}</div>
</div>
<div class="monitor-images-right monitor-images-item">
<img :src="imageFault[1]?.url" />
<div class="fault-info">{{ imageFault[1]?.fault_type }}</div>
</div>
<div class="monitor-images-left monitor-images-item">
<img :src="imageFault[0]?.url" />
<div class="fault-info">{{ imageFault[0]?.fault_type }}</div>
</div>
<div class="monitor-images-right monitor-images-item">
<img :src="imageFault[1]?.url" />
<div class="fault-info">{{ imageFault[1]?.fault_type }}</div>
</div>
<div class="monitor-images-right monitor-images-item">
<img :src="imageFault[1]?.url" />
<div class="fault-info">{{ imageFault[1]?.fault_type }}</div>
</div>
<div class="monitor-images-left monitor-images-item">
<img :src="imageFault[0]?.url" />
<div class="fault-info">{{ imageFault[0]?.fault_type }}</div>
</div>
<div class="monitor-images-right monitor-images-item">
<img :src="imageFault[1]?.url" />
<div class="fault-info">{{ imageFault[1]?.fault_type }}</div>
</div>
</div>
</div>
<!-- 设备信息 -->
<div class="grid-container">
<div class="device-info-box">
<div class="module-header">
<HomeSubTitle title="设备信息">
</HomeSubTitle>
<HomeSubTitle title="设备信息"> </HomeSubTitle>
</div>
<div class="device-info">
<div class="total-device">
<div class="device-icon"></div>
<div class="device-count">
<div>设备总数</div>
<div class="count-number">{{ deviceTotal }}</div>
</div>
</div>
<div class="device-list">
<div class="device-card">
<div class="mb-3">车体检测设备: {{ carDevice?.total || 0 }}</div>
<DeviceStatus :deviceStatus="carDevice" />
</div>
<div class="device-card">
<div class="mb-3">撑杆检测设备: {{ poleDevice?.total || 0 }}</div>
<DeviceStatus :deviceStatus="poleDevice" />
</div>
<div class="device-card">
<div class="mb-3">
钩机检测设备: {{ excavatorDevice?.total || 0 }}
<div class="flex items-center justify-center total-device">
<div class="device-total-icon mt-[24px]"></div>
<div class="device-count ml-[24px]">
<div class="fg-mark1 text-[32px] font-bold">
{{ deviceTotal }}
</div>
<DeviceStatus :deviceStatus="excavatorDevice" />
<div class="text-[14px]">设备总数</div>
</div>
</div>
<ul class="device-list">
<li class="device-card" v-for="(v, k) in deviceInfo.list" :key="k">
<div
class="device-card-head text-[16px] flex items-center mb-[12px]"
>
<img :src="v.icon" alt="" class="w-[32px]" />
<span class="ml-[12px]">{{ v.name }}</span>
<span class="font-bold">{{ v.bindVal?.total || 0 }}</span>
</div>
<DeviceStatus :deviceStatus="v.bindVal" />
</li>
</ul>
</div>
</div>
<AlarmModal

@ -1,21 +1,59 @@
.device-status-wrap{
.device-status-wrap {
height: 813px;
background-image: url("@/assets/common/device_status_bg_line.png");
background-image: url("@/assets/deviceStatus/device_status_bg.png");
background-size: 100% 100%;
background-position: bottom;
background-repeat: no-repeat;
}
.device-status-content-box{
.device-status-content-box {
.el-scrollbar__view {
background: transparent !important;
height: 600px;
}
.el-table__inner-wrapper{
.el-table__inner-wrapper {
background-color: transparent !important;
}
.el-table__body-wrapper, .el-scrollbar__wrap, .el-scrollbar{
.el-table__body-wrapper,
.el-scrollbar__wrap,
.el-scrollbar {
background: transparent !important;
}
}
.device-status-tag {
width: 78px;
height: 24px;
border-radius: 14px;
border: 1px solid #52c41a;
color: #52c41a;
display: flex;
align-items: center;
justify-content: center;
.dot {
display: inline-block;
margin-right: 8px;
width: 8px;
height: 8px;
background: #52c41a;
border-radius: 50%;
}
}
.device-status-tag-online{
@extend .device-status-tag;
}
.device-status-tag-outline {
@extend .device-status-tag;
border: 1px solid #999999;
color: #999999;
.dot {
background: #999999;
}
}
.device-status-tag-error {
@extend .device-status-tag;
border: 1px solid #e80d0d;
color: #e80d0d;
.dot {
background: #e80d0d;
}
}
}

@ -2,13 +2,11 @@
<div class="bg-basic-content">
<div class="device-status-wrap">
<div class="device-status-header mt-[32px]">
<ContentHeader bgLayout="1855">
<template #title>
<div class="w-[200px] bg_title bg_title_6"></div>
</template>
</ContentHeader>
<div class="mt-[24px] py-[16px] pl-[69px] flex items-center">
<div class="fg-title">设备状态</div>
</div>
</div>
<div class="px-[16px] device-status-content-box">
<div class="px-[24px] device-status-content-box">
<div class="mt-[16px] bg-transparent baseTable_wrap full_table">
<BaseTable
class="bg-transparent baseTable_box"
@ -23,19 +21,10 @@
<template v-slot:actionBar="{ row }">
<ul class="flex table_action_box">
<li
class="flex items-center mr-[16px]"
class="flex items-center mr-[12px]"
@click="openCurrent(row)"
>
<el-button text>
<span
:style="{
fontSize: '14px',
color: '#37DBFF',
}"
>
即时视频
</span>
</el-button>
<div class="fg-button-primary1">即时视频</div>
</li>
<li class="flex items-center" @click="openHistory(row)">
@ -68,7 +57,7 @@
</div>
</template>
<script setup lang="ts">
<script setup lang="tsx">
import { BaseTable } from "@/components/CustomTable";
import ContentHeader from "@/components/ContentHeader.vue";
import HistoryVideoModal from "./components/HistoryVideoModal.vue";
@ -88,6 +77,7 @@ defineOptions({
const alarmLevelStatusEnum = {
online: {
color: "#52C41A",
className: "device-status-tag-online",
value: "1",
label: "在线",
isDelete: true,
@ -96,6 +86,7 @@ const alarmLevelStatusEnum = {
},
offline: {
color: "#999999",
className: "device-status-tag-outline",
value: "2",
label: "离线",
isDelete: false,
@ -104,6 +95,7 @@ const alarmLevelStatusEnum = {
},
error: {
color: "#E80D0D",
className: "device-status-tag-error",
value: "3",
label: "故障",
isDelete: false,
@ -113,6 +105,8 @@ const alarmLevelStatusEnum = {
notFound: {
//
color: "#E80D0D",
className: "device-status-tag-error",
value: "4444",
label: "未知",
isDelete: false,
@ -155,6 +149,7 @@ const columns = [
{
label: "设备位置",
property: "device_position",
width: 550,
},
{
label: "设备状态",
@ -164,40 +159,18 @@ const columns = [
const currentLevelObj =
alarmLevelStatusEnum[val?.device_status] ||
alarmLevelStatusEnum.notFound;
return h(
"div",
{
style: {
fontSize: "14px",
display: "flex",
alignItems: "center",
lineHeight: "20px",
color: currentLevelObj?.color,
},
},
[
h("img", {
src: currentLevelObj?.icon,
style: {
width: "20px",
height: "20px",
marginRight: "12px",
},
}),
h(
"span",
{
fontSize: "14px",
},
currentLevelObj?.label
),
]
return (
<div className={currentLevelObj.className}>
<span className="dot"></span>
<span>{currentLevelObj?.label}</span>
</div>
);
},
},
{
type: "action",
label: "操作",
width: 210,
},
];
const pagination = ref({ currentPage: 1, pageSize: 10, total: 0 });

@ -1,14 +1,15 @@
.pole-monitor-wrap {
background-image: url("@/assets/common/bg_banner_1.png");
background-size: cover;
background-image: url("@/assets/poleMonitor/poleMonitor_main_bg.png");
background-size: 100% 100%;
background-position: bottom;
background-repeat: no-repeat;
height: 823px;
// width: 1866px;
height: 592px;
.search-section {
padding: 16px 0;
}
.pole-main-content {
width: 100%;
padding: 0 24px;
}
.pole-monitor-search-box {
@ -18,17 +19,20 @@
margin: 16px 0;
}
.right-panel {
// margin-right: 48px;
width: calc(100% - 190px - 682px);
.el-scrollbar__view {
background: transparent !important;
height: 600px;
height: 360px;
}
}
.pole-monitor-main {
.pole-monitor-banner {
.left-panel {
width: 870px;
height: 400px;
margin-right: 16px;
// background-color: red;
&.empty-bg {
height: 680px;
height: 100%;
background-image: url("@/assets/common/emptyBg.png");
background-size: 312px 204px;
background-position: center;
@ -36,51 +40,48 @@
}
.main-image {
box-sizing: border-box;
height: 511px;
width: 681px;
height: 400px;
position: relative;
background-color: #090f48;
border-radius: 4px;
overflow: hidden;
.file-preview-screen {
height: calc(100%);
display: flex;
justify-content: center;
align-items: center;
img {
img, video {
max-width: 100%;
max-height: 460px;
max-height: 400px;
object-fit: cover;
}
}
video {
width: 100%;
max-height: calc(100%);
}
.image-info {
position: absolute;
height: 52px;
line-height: 52px;
bottom: 0;
font-size: 14px;
padding: 0 16px;
width: 100%;
height: 29px;
line-height: 29px;
background: rgba(9, 15, 72, 0.6);
& > span {
margin-right: 10px;
}
}
}
.thumbnail-container {
width: 100%;
overflow: visible;
margin-right: 16px;
.swiper {
width: 100%;
height: 100%;
.swiper-slide {
width: 20%;
width: 155px;
border-radius: 4px;
height: 144px;
img {
width: 100%;
height: 144px;
img,
video {
width: 155px;
height: 91px;
border-radius: 4px;
object-fit: cover;
}

@ -1,16 +1,11 @@
<template>
<div class="pole-monitor-wrap mt-[32px]">
<div class="module-header">
<ContentHeader bgLayout="1855">
<template #title>
<div class="w-[200px] bg_title bg_title_3"></div>
</template>
<template #extra>
<div></div>
</template>
</ContentHeader>
<div class="fg-title pl-[54px] pt-[27px]">
<span class="text-[18px]">撑杆监测</span>
</div>
</div>
<div class="pole-main-content px-[16px]">
<div class="pole-main-content">
<!-- 搜索区域 -->
<div class="pole-monitor-search-box">
<el-select
@ -55,47 +50,26 @@
</el-button>
</div>
<!-- 主体内容区域 -->
<div class="flex justify-between pole-monitor-main">
<div class="flex justify-between pole-monitor-banner">
<!-- 左侧视频与缩略图区域 -->
<div class="left-panel" v-if="currFileList?.length">
<!-- 主图显示 -->
<div class="main-image">
<!-- <img src="https://picsum.phfotos/300/200?random=1" alt="监控画面"> -->
<!-- <video ref="refVideo" controls muted :src="currFile?.video_url" width="100%" height="100%" style="object-fit: fill;"></video> -->
<div class="file-preview-screen">
<Player
:src="currFile?.video_url"
:is-playing="isPlaying"
v-if="currFile?.video_url"
@play="isPlaying = true"
@pause="isPlaying = false"
/>
<img :src="currFile?.image_url" v-else-if="currFile?.image_url" />
<div v-else>
<!-- //TODO -->
</div>
</div>
<div class="image-info" v-if="currFile?.image_url">
<!-- //TODO -->
<span>: {{ currFile?.length }}</span>
<span>: {{ currFile?.width }}</span>
<span>: {{ currFile?.height }}</span>
<span>体积: {{ currFile?.volume }}</span>
<span>重量: {{ currFile?.weight }}</span>
</div>
</div>
<div class="flex left-panel" v-if="currFileList?.length">
<!-- 缩略图区域 -->
<div class="thumbnail-container mt-[16px] w-[870px]">
<div class="thumbnail-container">
<!-- //TODO -->
<swiper
ref="swiperRef"
:modules="modules"
:slides-per-view="3"
:slides-per-view="4"
:space-between="10"
navigation
:scrollbar="{ draggable: false }"
:mousewheel="true"
:pagination="{
clickable: true,
}"
:scrollbar="{ draggable: true }"
:centered-slides="false"
:observer="true"
:observeParents="true"
direction="vertical"
@swiper="onSwiper"
@slideChange="onSlideChange"
>
@ -122,10 +96,36 @@
</swiper-slide>
</swiper>
</div>
<!-- 主图显示 -->
<div class="main-image">
<!-- <img src="https://picsum.phfotos/300/200?random=1" alt="监控画面"> -->
<!-- <video ref="refVideo" controls muted :src="currFile?.video_url" width="100%" height="100%" style="object-fit: fill;"></video> -->
<div class="file-preview-screen">
<Player
:src="currFile?.video_url"
:is-playing="isPlaying"
v-if="currFile?.video_url"
@play="isPlaying = true"
@pause="isPlaying = false"
/>
<img :src="currFile?.image_url" v-else-if="currFile?.image_url" />
<div v-else>
<!-- //TODO -->
</div>
</div>
<div class="image-info" v-if="currFile?.image_url">
<!-- //TODO -->
<span>: {{ currFile?.length }}</span>
<span>: {{ currFile?.width }}</span>
<span>: {{ currFile?.height }}</span>
<span>体积: {{ currFile?.volume }}</span>
<span>重量: {{ currFile?.weight }}</span>
</div>
</div>
</div>
<div class="left-panel empty-bg" v-else></div>
<!-- 右侧表格区域 -->
<div class="flex-1 right-panel">
<div class="right-panel">
<div class="bg-transparent baseTable_wrap">
<BaseTable
class="bg-transparent baseTable_box"
@ -172,7 +172,7 @@ import ContentHeader from "@/components/ContentHeader.vue";
import { BaseTable } from "@/components/CustomTable";
import SwiperPlayer from "./components/SwiperPlayer.vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import { Navigation, Scrollbar } from "swiper/modules";
import { Navigation, Scrollbar, Mousewheel, Pagination } from "swiper/modules";
import {
getAppearanceMonitorApi,
getAppearanceMonitorDetailApi,
@ -189,7 +189,7 @@ import "swiper/scss/navigation";
defineOptions({
name: "PoleMonitorIndex",
});
const modules = [Navigation, Scrollbar];
const modules = [Navigation, Scrollbar, Mousewheel, Pagination];
const activeIndex = ref(-1);
const swiperRef = ref(null);
const columns = [

@ -2,41 +2,38 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-10 18:00:44
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-18 11:31:05
* @LastEditTime: 2025-08-13 15:58:03
* @FilePath: \5G-Loading-Bay-Web\src\views\dashboard\components\DeviceStatus.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { ref } from "vue";
defineOptions({
name: "DeviceStatus"
name: "DeviceStatus",
});
const props = defineProps({
deviceStatus: {
type: Object,
default: () => {}
}
default: () => {},
},
});
const deviceStatusOptions = ref<Record<string, any>[]>([
{
label: "在线",
color: "#52C41A",
bgColor: "#52C41A",
valueKey: "onlineCount" // 线
label: "在线设备",
bgColor: "linear-gradient( 270deg, #2E8702 0%, #52C41A 100%)",
valueKey: "onlineCount", // 线
},
{
label: "离线",
color: "#ccc",
bgColor: "#999999",
valueKey: "outlineCount" //
label: "离线设备",
bgColor: "linear-gradient( 270deg, #C2C0C0 0%, #9A9A9A 100%)",
valueKey: "outlineCount", //
},
{
label: "故障",
color: "#E80D0D",
bgColor: "#E80D0D",
valueKey: "errorCount" //
}
label: "故障设备",
bgColor: "linear-gradient( 270deg, #9D0101 0%, #E30C0C 100%)",
valueKey: "errorCount", //
},
]);
</script>
@ -45,36 +42,27 @@ const deviceStatusOptions = ref<Record<string, any>[]>([
<li
class="flex items-center justify-between w-full"
:style="{
marginBottom: '16px'
marginBottom: '16px',
}"
v-for="(v, k) in deviceStatusOptions"
:key="k"
>
<div
class="flex items-center justify-center"
:style="{
backgroundColor: v.bgColor,
width: '40px',
height: '40px',
borderRadius: '4px',
marginRight: '12px'
}"
>
<div v-if="v.valueKey === 'onlineCount'" class="deviceStatusOnline"></div>
<div v-if="v.valueKey === 'errorCount'" class="deviceStatusError"></div>
<div v-if="v.valueKey === 'outlineCount'" class="deviceStatusOutline"></div>
</div>
<div class="flex flex-col flex-1">
<div class="flex justify-between" style="margin-bottom: 4px">
<span>{{ v.label }}</span>
<span>{{ deviceStatus?.[v.valueKey] }}</span>
<span>{{ deviceStatus?.[v.valueKey] || 0 }}</span>
</div>
<div class="w-full">
<!-- // TODO -->
<el-progress
:show-text="false"
:stroke-width="8"
:percentage="deviceStatus?.[v.valueKey]"
:color="v.color"
:stroke-width="4"
:percentage="
Math.floor(
(deviceStatus?.[v.valueKey] / deviceStatus?.total) * 100
)
"
:color="v.bgColor"
/>
</div>
</div>
@ -83,24 +71,27 @@ const deviceStatusOptions = ref<Record<string, any>[]>([
</template>
<style lang="scss" scoped>
.deviceStatus_box {
li {
div {
.deviceStatusOnline {
width: 20px;
height: 20px;
background: url('@/assets/svg/deviceStatus/online.svg') no-repeat center center;
}
.deviceStatusError {
width: 20px;
height: 20px;
background: url('@/assets/svg/deviceStatus/error.svg') no-repeat center center;
}
.deviceStatusOutline {
width: 20px;
height: 20px;
background: url('@/assets/svg/deviceStatus/outline.svg') no-repeat center center;
}
}
li {
div {
.deviceStatusOnline {
width: 20px;
height: 20px;
background: url("@/assets/svg/deviceStatus/online.svg") no-repeat center
center;
}
.deviceStatusError {
width: 20px;
height: 20px;
background: url("@/assets/svg/deviceStatus/error.svg") no-repeat center
center;
}
.deviceStatusOutline {
width: 20px;
height: 20px;
background: url("@/assets/svg/deviceStatus/outline.svg") no-repeat
center center;
}
}
}
}
</style>

@ -1,127 +1,102 @@
<template>
<el-dialog class="realVideoModal-wrap" v-model="show" @close="handleClose">
<!-- 自定义标题栏 -->
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between video-dialog-header">
<div class="flex items-center justify-center header-left">
<div class="header-icon mr-[12px]"></div>
<p class="overflow-hidden whitespace-nowrap text-ellipsis max-w-[650px]">{{
info.device_name }}</p>
</div>
</div>
</template>
<!-- 视频播放区域 -->
<div class="relative video-container">
<RealPlayer :show="show" :videoSrc="info.url" />
<el-dialog
class="realVideoModal-wrap fg-dialog"
v-model="show"
@close="handleClose"
align-center
:show-close="false"
>
<!-- 自定义标题栏 -->
<template #header="{ close, titleId, titleClass }">
<div
class="flex items-center justify-between video-dialog-header fg-dialog-header"
>
<div class="flex items-center justify-center header-left pl-[24px]">
<div class="header-icon mr-[12px]"></div>
<p
class="overflow-hidden whitespace-nowrap text-ellipsis max-w-[650px]"
>
{{ info.device_name }}
</p>
</div>
</el-dialog>
<div class="fg-dialog-header-close" @click="close"></div>
</div>
</template>
<!-- 视频播放区域 -->
<div class="relative video-container">
<RealPlayer :show="show" :videoSrc="info.url" />
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import RealPlayer from '@/components/videoPlayer/RealPlayer.vue'
import { ref } from "vue";
import RealPlayer from "@/components/videoPlayer/RealPlayer.vue";
interface Props {
/** 弹窗显隐 */
value: boolean;
info: Record<string, any>;
/** 弹窗显隐 */
value: boolean;
info: Record<string, any>;
}
interface Emits {
(e: "update:value", val: boolean): void;
(e: "update:value", val: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
value: false,
info: {}
value: false,
info: {},
});
const emit = defineEmits<Emits>();
const isPlaying = ref(false);
const openReal = () => {
// isPlaying.value = !isPlaying.value;
// isPlaying.value = !isPlaying.value;
};
//
const handleClose = () => {
isPlaying.value = false;
// emits('close');
isPlaying.value = false;
// emits('close');
};
const show = computed({
get() {
return props.value;
},
set(val: boolean) {
emit("update:value", val);
}
get() {
return props.value;
},
set(val: boolean) {
emit("update:value", val);
},
});
</script>
<style lang="scss">
.realVideoModal-wrap.el-dialog {
border: none;
overflow: hidden;
box-shadow: none;
background-color: transparent;
background-image: url("@/assets/common/bg_real_dialog.png");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
width: 805px;
height: 612px;
padding: 0;
margin-top: calc(50vh - 316px);
.el-dialog__header.show-close {
padding: 0;
}
.el-dialog__close {
width: 56px;
height: 56px;
color: white;
font-size: 18px;
padding-top: 4px;
padding-right: 20px;
}
.video-dialog-header {
color: white;
padding: 0;
padding-top: 4px;
.header-left {
padding: 0 18px;
font-weight: bold;
font-size: 18px;
.header-icon {
margin-top: 8px;
width: 48px;
height: 48px;
background-image: url("@/assets/common/dialog_title_icon.png");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
}
.video-dialog-header {
color: white;
.header-left {
font-weight: bold;
font-size: 18px;
height: 48px;
.header-icon {
margin-top: 8px;
width: 40px;
height: 40px;
background-image: url("@/assets/common/dialog_title_icon.png");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
}
.video-container {
padding: 24px;
height: 550px;
// background: red;
.real-video-player {
border-radius: 0px 0px 4px 4px;
overflow: hidden;
}
}
.video-container {
padding: 24px 32px;
height: 566px;
.real-video-player {
border-radius: 0px 0px 4px 4px;
overflow: hidden;
}
}
}
</style>
</style>

@ -1,5 +1,5 @@
<template>
<el-dialog class="vehiclModal-wrap fg-dialog fg-dialog2" v-model="show" @close="handleClose" :show-close="false" >
<el-dialog class="vehiclModal-wrap fg-dialog fg-dialog2" v-model="show" @close="handleClose" align-center :show-close="false" >
<!-- 自定义标题栏 -->
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between vehicl-dialog-header fg-dialog-header">
@ -96,7 +96,6 @@ const itemCount = 16; // 这里可以根据实际需求动态设置
padding: 0 24px;
font-weight: bold;
font-size: 18px;
.header-icon {
margin-top: 4px;
width: 24px;

Loading…
Cancel
Save