Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
|
f00434a820 | 1 day ago |
|
d8c58dd183 | 2 days ago |
|
dfa0eafb16 | 6 days ago |
|
ddfd3e8d4a | 1 week ago |
|
445ae91686 | 1 week ago |
|
d364741783 | 2 weeks ago |
|
abbab281af | 3 weeks ago |
|
d0a2edeb6e | 3 weeks ago |
|
d8e35d30a0 | 3 weeks ago |
|
4480923404 | 4 weeks ago |
|
301da206e9 | 4 weeks ago |
|
1c20ab4c0c | 4 weeks ago |
|
b6923a9b6a | 4 weeks ago |
|
03cb778c4b | 1 month ago |
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-11 11:29:02
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-19 11:39:52
|
||||
* @FilePath: \5G-Loading-Bay-Web\mock\poleMonitor.ts
|
||||
* @Description: 撑杆监测
|
||||
*/
|
||||
import { MockMethod } from "vite-plugin-mock";
|
||||
import { poleMonitorListData, fileListData } from "./pools/commonData";
|
||||
import { fetchCurrPageByList, fetchMockSuccessFullByOther } from "./utils/apiMock";
|
||||
|
||||
export default [
|
||||
{
|
||||
url: "/api/v1/record/generator_result/",
|
||||
method: "post",
|
||||
response: req => {
|
||||
// console.log(req);
|
||||
return {...fetchMockSuccessFullByOther(fileListData)}
|
||||
}
|
||||
}
|
||||
] as MockMethod[];
|
After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 193 KiB |
After Width: | Height: | Size: 317 B |
Before Width: | Height: | Size: 342 KiB |
Before Width: | Height: | Size: 800 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 713 KiB After Width: | Height: | Size: 964 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 405 KiB |
After Width: | Height: | Size: 567 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 755 KiB |
After Width: | Height: | Size: 498 B |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 642 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 563 B |
After Width: | Height: | Size: 497 B |
After Width: | Height: | Size: 450 KiB |
After Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 230 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 240 KiB |
After Width: | Height: | Size: 271 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 789 B |
After Width: | Height: | Size: 334 KiB |
@ -0,0 +1,255 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-14 10:33:46
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-27 16:22:40
|
||||
* @FilePath: \5G-Web\src\components\Charts\appearanceDailyAlertChart.vue
|
||||
* @Description: 外观日告警统计
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
function initChart() {
|
||||
const chartDom = document.getElementById("appearanceDailyAlertChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
// TODO 截取加载半月数据
|
||||
let xAxisData = [];
|
||||
let typesData = [];
|
||||
for (let key in props.datas) {
|
||||
xAxisData.push(key + "日");
|
||||
if (props.datas[key] && Object.keys(props.datas[key])?.length) {
|
||||
typesData.push(...Object.keys(props.datas[key]));
|
||||
}
|
||||
}
|
||||
typesData = Array.from(new Set(typesData));
|
||||
console.log(typesData, "typesData");
|
||||
const colorArrs = [
|
||||
{
|
||||
name: "搭扣未扣",
|
||||
color: "rgba(212, 145, 20, 0.9)",
|
||||
color1: "rgba(212, 145, 20, 0.3)",
|
||||
},
|
||||
{
|
||||
name: "小门搭扣丢失",
|
||||
color: "rgba(0, 157, 255, 0.9)",
|
||||
color1: "rgba(0, 157, 255, 0.3)",
|
||||
},
|
||||
{
|
||||
name: "门折页座脱落",
|
||||
color: "rgba(44, 188, 204, 0.9)",
|
||||
color1: "rgba(44, 188, 204, 0.3)",
|
||||
},
|
||||
{
|
||||
name: "下侧门板缺失",
|
||||
color: "rgba(13, 233, 138, 0.9)",
|
||||
color1: "rgba(13, 233, 138, 0.3)",
|
||||
},
|
||||
{
|
||||
name: "小门外胀",
|
||||
color: "rgba(198, 81, 14, 0.9)",
|
||||
color1: "rgba(198, 81, 14, 0.3)",
|
||||
},
|
||||
{
|
||||
name: "小窗裂纹",
|
||||
color: "rgba(255, 209, 92, 0.9)",
|
||||
color1: "rgba(255, 209, 92, 0.3)",
|
||||
},
|
||||
];
|
||||
|
||||
// const startData = [
|
||||
// {
|
||||
// name: "搭扣未扣",
|
||||
// data: [
|
||||
// 80, 30, 120, 80, 100, 60, 70, 50, 40, 60, 110, 30, 80, 100, 120, 150,
|
||||
// ],
|
||||
// color: "rgba(212, 145, 20, 0.9)",
|
||||
// color1: "rgba(212, 145, 20, 0.3)",
|
||||
// },
|
||||
// {
|
||||
// name: "小门搭扣丢失",
|
||||
// data: [
|
||||
// 100, 20, 220, 180, 120, 180, 100, 120, 100, 140, 160, 20, 180, 140, 80,
|
||||
// 170,
|
||||
// ],
|
||||
// color: "rgba(0, 157, 255, 0.9)",
|
||||
// color1: "rgba(0, 157, 255, 0.3)",
|
||||
// },
|
||||
// {
|
||||
// name: "门折页座脱落",
|
||||
// data: [
|
||||
// 150, 180, 200, 190, 180, 50, 80, 100, 80, 140, 120, 190, 150, 60, 100,
|
||||
// 120,
|
||||
// ],
|
||||
// color: "rgba(44, 188, 204, 0.9)",
|
||||
// color1: "rgba(44, 188, 204, 0.3)",
|
||||
// },
|
||||
// {
|
||||
// name: "下侧门板缺失",
|
||||
// data: [
|
||||
// 120, 140, 180, 170, 80, 140, 130, 110, 140, 100, 100, 140, 120, 80, 140,
|
||||
// 140,
|
||||
// ],
|
||||
// color: "rgba(13, 233, 138, 0.9)",
|
||||
// color1: "rgba(13, 233, 138, 0.3)",
|
||||
// },
|
||||
// {
|
||||
// name: "小门外胀",
|
||||
// data: [
|
||||
// 100, 120, 80, 100, 50, 70, 150, 120, 100, 140, 60, 100, 60, 150, 120,
|
||||
// 170,
|
||||
// ],
|
||||
// color: "rgba(198, 81, 14, 0.9)",
|
||||
// color1: "rgba(198, 81, 14, 0.3)",
|
||||
// },
|
||||
// {
|
||||
// name: "小窗裂纹",
|
||||
// data: [
|
||||
// 150, 160, 180, 170, 150, 80, 100, 140, 120, 80, 140, 80, 120, 80, 100,
|
||||
// 150,
|
||||
// ],
|
||||
// color: "rgba(255, 209, 92, 0.9)",
|
||||
// color1: "rgba(255, 209, 92, 0.3)",
|
||||
// },
|
||||
// ];
|
||||
let finalData = [];
|
||||
colorArrs.forEach((lineItem, lineIndex) => {
|
||||
const currInitValues = new Array(xAxisData.length).fill(0);
|
||||
Object.keys(props.datas).forEach((key, index) => {
|
||||
if (
|
||||
props.datas[key] &&
|
||||
Object.keys(props.datas[key]).includes(lineItem.name)
|
||||
) {
|
||||
currInitValues[index] = props.datas[key][lineItem.name];
|
||||
}
|
||||
});
|
||||
// for (let key in props.datas) {
|
||||
// if(props.datas[key] && Object.keys(props.datas[key]).includes(lineItem.name)){
|
||||
// currInitValues[Number(key)-1] = props.datas[key][lineItem.name];
|
||||
// }
|
||||
// }
|
||||
finalData.push({
|
||||
...lineItem,
|
||||
data: currInitValues,
|
||||
});
|
||||
});
|
||||
const seriesOptions = [];
|
||||
const legendData = [];
|
||||
|
||||
finalData.forEach((item) => {
|
||||
legendData.push(item.name);
|
||||
seriesOptions.push({
|
||||
name: item.name,
|
||||
type: "line",
|
||||
color: item.color,
|
||||
symbolSize: 9,
|
||||
symbol: "none",
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: "line",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: item.color1,
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(255, 209, 92, 0)",
|
||||
},
|
||||
],
|
||||
global: false,
|
||||
},
|
||||
},
|
||||
data: item.data,
|
||||
});
|
||||
});
|
||||
|
||||
let option = {
|
||||
backgroundColor: "transparent",
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
orient: "horizontal",
|
||||
right: 0,
|
||||
top: "5%",
|
||||
icon: "rect",
|
||||
textStyle: {
|
||||
fontFamily: "PingFangSC-Semibold",
|
||||
fontSize: 14,
|
||||
color: "#FFFFFF",
|
||||
padding: [0, 2],
|
||||
},
|
||||
data: legendData,
|
||||
},
|
||||
grid: {
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "25%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
data: xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: "dashed",
|
||||
color: "rgba(255,255,255,0.1)",
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
series: seriesOptions,
|
||||
};
|
||||
mainChart.setOption(option);
|
||||
}
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<div id="appearanceDailyAlertChart" style="width: 960px; height: 100%"></div>
|
||||
</template>
|
@ -0,0 +1,242 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-14 10:33:22
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-26 17:09:24
|
||||
* @FilePath: \5G-Web\src\components\Charts\appearanceDailyDetectionChart.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import * as echarts from "echarts";
|
||||
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
function initChart() {
|
||||
const chartDom = document.getElementById("appearanceDailyDetectionChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
let finalData = [];
|
||||
|
||||
for (let key in props.datas) {
|
||||
finalData.push({
|
||||
name: key + "日",
|
||||
value: props.datas[key],
|
||||
});
|
||||
}
|
||||
// TODO 转移到mock数据中
|
||||
// const finalData = [
|
||||
// {
|
||||
// name: "1日",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "2日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "3日",
|
||||
// value: 195,
|
||||
// },
|
||||
// {
|
||||
// name: "4日",
|
||||
// value: 115,
|
||||
// },
|
||||
// {
|
||||
// name: "5日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "6日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "7日",
|
||||
// value: 56,
|
||||
// },
|
||||
// {
|
||||
// name: "8日",
|
||||
// value: 45,
|
||||
// },
|
||||
// {
|
||||
// name: "9日",
|
||||
// value: 15,
|
||||
// },
|
||||
// {
|
||||
// name: "10日",
|
||||
// value: 48,
|
||||
// },
|
||||
// {
|
||||
// name: "11日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "12日",
|
||||
// value: 128,
|
||||
// },
|
||||
// {
|
||||
// name: "13日",
|
||||
// value: 34,
|
||||
// },
|
||||
// {
|
||||
// name: "14日",
|
||||
// value: 123,
|
||||
// },
|
||||
// {
|
||||
// name: "15日",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "16日",
|
||||
// value: 148,
|
||||
// },
|
||||
// ];
|
||||
const createSvg = (shadowColor, shadowBlur) => `
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px" y="0px"
|
||||
viewBox="0 0 32 128"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<style>
|
||||
.st2 {
|
||||
fill: transparent;
|
||||
stroke: ${shadowColor};
|
||||
stroke-width: ${shadowBlur}px;
|
||||
filter: url(#chart-inset-shadow);
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<filter id="chart-inset-shadow" width="200%" height="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" result="gass" stdDeviation="${
|
||||
shadowBlur * 0.75
|
||||
}" />
|
||||
<feMerge>
|
||||
<feMergeNode in="gass" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<path class="st2" d="M0 0 L32 0 L32 128 L0 128 Z" />
|
||||
</svg>
|
||||
`;
|
||||
const svgString = createSvg("rgba(7, 131, 250, 1)", 8);
|
||||
const svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
|
||||
const barWidth = 16;
|
||||
const DOMURL = window.URL || window.webkitURL || window;
|
||||
const insetShadowUrl = DOMURL.createObjectURL(svg);
|
||||
let xAxisData = [];
|
||||
let seriesData1 = [];
|
||||
finalData.forEach((item) => {
|
||||
xAxisData.push(item.name);
|
||||
seriesData1.push(item.value);
|
||||
});
|
||||
|
||||
const option = {
|
||||
backgroundColor: "",
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
grid: {
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "15%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
data: xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: "dashed",
|
||||
color: "rgba(255,255,255,0.1)",
|
||||
width: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: seriesData1,
|
||||
type: "pictorialBar",
|
||||
symbol: "image://" + insetShadowUrl,
|
||||
barWidth: barWidth,
|
||||
legendHoverLink: false,
|
||||
},
|
||||
{
|
||||
tooltip: {
|
||||
show: false,
|
||||
},
|
||||
data: seriesData1,
|
||||
type: "bar",
|
||||
barWidth: barWidth,
|
||||
itemStyle: {
|
||||
color: "transparent",
|
||||
borderWidth: 1,
|
||||
borderColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(45, 230, 255, 1)",
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(7, 131, 250, 1)",
|
||||
},
|
||||
]),
|
||||
shadowColor: "blue",
|
||||
shadowBlur: 12,
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
mainChart.setOption(option);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="main-chart"
|
||||
ref="mainChartRef"
|
||||
id="appearanceDailyDetectionChart"
|
||||
style="width: 862px; height: 100%"
|
||||
></div>
|
||||
</template>
|
@ -0,0 +1,216 @@
|
||||
<script setup lang="ts">
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
function initChart() {
|
||||
const chartDom = document.getElementById("diggerDailyDistanceChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
let finalData = [];
|
||||
|
||||
for (let key in props.datas) {
|
||||
finalData.push({
|
||||
name: key + "日",
|
||||
value: props.datas[key],
|
||||
});
|
||||
}
|
||||
// let finalData = [
|
||||
// {
|
||||
// name: "1日",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "2日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "3日",
|
||||
// value: 195,
|
||||
// },
|
||||
// {
|
||||
// name: "4日",
|
||||
// value: 115,
|
||||
// },
|
||||
// {
|
||||
// name: "5日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "6日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "7日",
|
||||
// value: 56,
|
||||
// },
|
||||
// {
|
||||
// name: "8日",
|
||||
// value: 45,
|
||||
// },
|
||||
// {
|
||||
// name: "9日",
|
||||
// value: 15,
|
||||
// },
|
||||
// {
|
||||
// name: "10日",
|
||||
// value: 48,
|
||||
// },
|
||||
// {
|
||||
// name: "11日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "12日",
|
||||
// value: 128,
|
||||
// },
|
||||
// {
|
||||
// name: "13日",
|
||||
// value: 34,
|
||||
// },
|
||||
// {
|
||||
// name: "14日",
|
||||
// value: 123,
|
||||
// },
|
||||
// {
|
||||
// name: "15日",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "16日",
|
||||
// value: 148,
|
||||
// },
|
||||
// ];
|
||||
let xAxisData = [];
|
||||
let seriesData2 = [];
|
||||
|
||||
finalData.forEach((item) => {
|
||||
xAxisData.push(item.name);
|
||||
seriesData2.push(item.value);
|
||||
});
|
||||
let option = {
|
||||
tooltip: {
|
||||
textStyle: {
|
||||
color: "#000",
|
||||
},
|
||||
padding: [10, 10],
|
||||
trigger: "axis",
|
||||
backgroundColor: "#fff",
|
||||
borderColor: "rgba(112, 119, 242, 0.8)",
|
||||
borderWidth: 1,
|
||||
},
|
||||
grid: {
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "15%",
|
||||
containLabel: true,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xAxisData,
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#35414D",
|
||||
type: "dashed",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: "line",
|
||||
data: seriesData2,
|
||||
symbolSize: 10,
|
||||
symbol: "circle",
|
||||
smooth: false,
|
||||
yAxisIndex: 0,
|
||||
label: {
|
||||
show: false,
|
||||
// textStyle: {
|
||||
// color: "#FFD15C",
|
||||
// fontSize: 20,
|
||||
// fontFamily: "DIN",
|
||||
// fontWeight: "bold",
|
||||
// },
|
||||
position: "top",
|
||||
formatter: function (p) {
|
||||
return p.value > 0 ? p.value : "";
|
||||
},
|
||||
},
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(255, 209, 92, 1)",
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(255, 209, 92, 1)",
|
||||
},
|
||||
]),
|
||||
shadowColor: "rgba(255, 209, 92, 0.4)",
|
||||
shadowBlur: 10,
|
||||
shadowOffsetY: 10,
|
||||
},
|
||||
itemStyle: {
|
||||
color: "rgba(255, 209, 92, 1)",
|
||||
borderColor: "",
|
||||
borderWidth: 3,
|
||||
shadowColor: "rgba(255, 209, 92, 01)",
|
||||
shadowBlur: 5,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mainChart.setOption(option);
|
||||
}
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="diggerDailyDistanceChart" style="width: 960px; height: 100%"></div>
|
||||
</template>
|
@ -0,0 +1,303 @@
|
||||
<script setup lang="ts">
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
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: {
|
||||
color: color,
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
dataArr.push({
|
||||
name: (i + 1).toString(),
|
||||
value: smallvalue,
|
||||
itemStyle: {
|
||||
color: "rgba(0,0,0,0)",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return dataArr;
|
||||
}
|
||||
function initChart() {
|
||||
const chartDom = document.getElementById("diggerHourlyDistanceChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
let finalData = [];
|
||||
|
||||
for (let key in props.datas) {
|
||||
finalData.push({
|
||||
name: key + ":00",
|
||||
value: props.datas[key],
|
||||
});
|
||||
}
|
||||
// let finalData = [
|
||||
// {
|
||||
// name: "05:00",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "06:00",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "07:00",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "08:00",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "09:00",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "10:00",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "11:00",
|
||||
// value: 56,
|
||||
// },
|
||||
// {
|
||||
// name: "12:00",
|
||||
// value: 45,
|
||||
// },
|
||||
// {
|
||||
// name: "13:00",
|
||||
// value: 34,
|
||||
// },
|
||||
// {
|
||||
// name: "14:00",
|
||||
// value: 123,
|
||||
// },
|
||||
// {
|
||||
// name: "15:00",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "16:00",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "17:00",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "18:00",
|
||||
// value: 123,
|
||||
// },
|
||||
// {
|
||||
// name: "19:00",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "20:00",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "21:00",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "22:00",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "23:00",
|
||||
// value: 95,
|
||||
// },
|
||||
// ];
|
||||
let xAxisData = [];
|
||||
let seriesData1 = [];
|
||||
|
||||
finalData.forEach((item) => {
|
||||
xAxisData.push(item.name);
|
||||
seriesData1.push(item.value);
|
||||
});
|
||||
|
||||
const dom = 200;
|
||||
const barWidth = dom / 10;
|
||||
const colors = [
|
||||
{
|
||||
type: "linear",
|
||||
x: 1,
|
||||
x2: 1,
|
||||
y: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(216,216,216,0)",
|
||||
},
|
||||
{
|
||||
offset: 0.5,
|
||||
color: "rgba(103,236,228,0.53)",
|
||||
},
|
||||
{
|
||||
offset: 0,
|
||||
color: "#00FEEE",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const colors1 = [
|
||||
{
|
||||
type: "linear",
|
||||
x: 0,
|
||||
x2: 0,
|
||||
y: 1,
|
||||
y2: 0,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0.3,
|
||||
color: "#4bcde4",
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "#4b88e4",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const option = {
|
||||
backgroundColor: "transparent",
|
||||
//X轴
|
||||
xAxis: {
|
||||
name: "X",
|
||||
nameTextStyle: {
|
||||
color: "#FFFFFF",
|
||||
padding: [0, 0, 0, 50],
|
||||
},
|
||||
|
||||
data: xAxisData,
|
||||
show: true,
|
||||
type: "category",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#35414D",
|
||||
type: "dashed",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
},
|
||||
/**区域位置*/
|
||||
grid: {
|
||||
// Adjust grid for spacing
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "15%",
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
barWidth: barWidth,
|
||||
symbolOffset: ["10%", "50%"],
|
||||
itemStyle: {
|
||||
color: function (params) {
|
||||
return colors[0];
|
||||
},
|
||||
},
|
||||
data: seriesData1,
|
||||
tooltip: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// 实体柱状图底部
|
||||
z: 4,
|
||||
type: "pictorialBar",
|
||||
data: seriesData1,
|
||||
|
||||
symbolOffset: ["0%", "0%"],
|
||||
symbolSize: [barWidth, barWidth * 0.3],
|
||||
itemStyle: {
|
||||
color: function (params) {
|
||||
return "rgba(0,255,252,0.1)";
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
// 实体柱状图顶部
|
||||
z: 3,
|
||||
type: "pictorialBar",
|
||||
symbolPosition: "end",
|
||||
data: seriesData1,
|
||||
symbolOffset: ["0%", "-50%"],
|
||||
symbolSize: [barWidth, barWidth * 0.3],
|
||||
itemStyle: {
|
||||
borderWidth: 0,
|
||||
color: function (params) {
|
||||
return colors1[0];
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mainChart.setOption(option);
|
||||
}
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="diggerHourlyDistanceChart" style="width: 862px; height: 100%"></div>
|
||||
</template>
|
@ -0,0 +1,285 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-14 10:31:16
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-27 13:44:55
|
||||
* @FilePath: \5G-Web\src\components\Charts\poleDailyAlertChart.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
// const propsData = {
|
||||
// xAxisData: [
|
||||
// "1日",
|
||||
// "2日",
|
||||
// "3日",
|
||||
// "4日",
|
||||
// "5日",
|
||||
// "6日",
|
||||
// "7日",
|
||||
// "8日",
|
||||
// "9日",
|
||||
// "10日",
|
||||
// "11日",
|
||||
// "12日",
|
||||
// "13日",
|
||||
// "14日",
|
||||
// "15日",
|
||||
// "16日",
|
||||
// ],
|
||||
// legendData: ["撑杆断裂", "撑杆锈蚀", "撑杆穿孔"],
|
||||
// seriesData: {
|
||||
// 撑杆断裂: [
|
||||
// 210, 80, 120, 100, 90, 120, 110, 140, 130, 120, 120, 125, 130, 160, 150,
|
||||
// 100,
|
||||
// ],
|
||||
// 撑杆锈蚀: [
|
||||
// 70, 110, 140, 120, 140, 70, 80, 170, 160, 140, 140, 130, 140, 120, 90,
|
||||
// 110,
|
||||
// ],
|
||||
// 撑杆穿孔: [
|
||||
// 80, 150, 180, 160, 80, 60, 70, 180, 190, 170, 160, 140, 130, 80, 100,
|
||||
// 150,
|
||||
// ],
|
||||
// },
|
||||
// };
|
||||
|
||||
const initChart = () => {
|
||||
const chartDom = document.getElementById("poleDailyAlertChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
const seriesBaseData = [
|
||||
{
|
||||
// name: "撑杆断裂",
|
||||
// data: propsData.seriesData["撑杆断裂"],
|
||||
type: "line",
|
||||
smooth: true, //true曲线; false折线
|
||||
symbol: "none",
|
||||
itemStyle: {
|
||||
color: "#ffc600", //改变折线点的颜色
|
||||
lineStyle: {
|
||||
color: "#ffc600", //改变折线颜色
|
||||
type: "solid",
|
||||
},
|
||||
},
|
||||
areaStyle: {
|
||||
//折线图颜色半透明
|
||||
color: {
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(255,198,0, 0.5)", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(255,198,0, 0.1)", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
global: false, // 缺省为 false
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// name: "撑杆锈蚀",
|
||||
// data: propsData.seriesData["撑杆锈蚀"],
|
||||
type: "line",
|
||||
smooth: true, //true曲线; false折线
|
||||
symbol: "none",
|
||||
|
||||
itemStyle: {
|
||||
color: "#24adfe", //改变折线点的颜色
|
||||
lineStyle: {
|
||||
color: "#24adfe", //改变折线颜色
|
||||
type: "solid",
|
||||
},
|
||||
},
|
||||
areaStyle: {
|
||||
//折线图颜色半透明
|
||||
color: {
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(36,173,254, 0.5)", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(52,112,252, 0.1)", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
global: false, // 缺省为 false
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// name: "撑杆穿孔",
|
||||
// data: propsData.seriesData["撑杆穿孔"],
|
||||
type: "line",
|
||||
smooth: true, //true曲线; false折线
|
||||
symbol: "none",
|
||||
|
||||
itemStyle: {
|
||||
color: "#0DE98A", //改变折线点的颜色
|
||||
lineStyle: {
|
||||
color: "#0DE98A", //改变折线颜色
|
||||
type: "solid",
|
||||
},
|
||||
},
|
||||
areaStyle: {
|
||||
//折线图颜色半透明
|
||||
color: {
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(13, 233, 138, 0.5)", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(13, 233, 138, 0.1)", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
global: false, // 缺省为 false
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
const maxTypesLength = seriesBaseData.length;
|
||||
|
||||
let xAxisData = [];
|
||||
let typesData = [];
|
||||
|
||||
for (let key in props.datas) {
|
||||
xAxisData.push(key + "日");
|
||||
if (props.datas[key] && Object.keys(props.datas[key])?.length) {
|
||||
typesData.push(...Object.keys(props.datas[key]));
|
||||
}
|
||||
}
|
||||
const legendData = Array.from(new Set(typesData)).slice(0, maxTypesLength);
|
||||
|
||||
|
||||
|
||||
let finalSeriesData = [];
|
||||
|
||||
legendData.forEach((v, vIndex) => {
|
||||
const currInitValues = new Array(xAxisData.length).fill(0);
|
||||
Object.keys(props.datas).forEach((key, index) => {
|
||||
if (props.datas[key] && Object.keys(props.datas[key]).includes(v)) {
|
||||
currInitValues[index] = props.datas[key][v];
|
||||
}
|
||||
});
|
||||
finalSeriesData.push({
|
||||
...seriesBaseData[vIndex],
|
||||
name: v,
|
||||
data: currInitValues,
|
||||
});
|
||||
});
|
||||
const option = {
|
||||
backgroundColor: "#061740",
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 0,
|
||||
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "25%",
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
left: "right",
|
||||
top: "1",
|
||||
padding: [10, 0, 0, 0],
|
||||
data: legendData,
|
||||
//图例滚动
|
||||
// type: 'scroll',
|
||||
//图例文字样式
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
},
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: "category",
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
data: xAxisData,
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
interval: 1,
|
||||
axisLabel: {
|
||||
formatter: "{value} ",
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
//坐标轴线样式
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: "solid", //solid实线;dashed虚线
|
||||
color: "rgba(36, 173, 254, 0.2)",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
series: finalSeriesData,
|
||||
};
|
||||
mainChart.setOption(option);
|
||||
};
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="poleDailyAlertChart" style="width: 960px; height: 100%"></div>
|
||||
</template>
|
@ -0,0 +1,222 @@
|
||||
<script lang="ts" setup>
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
datas: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const initChart = () => {
|
||||
const chartDom = document.getElementById("poleDailyDetectionChart");
|
||||
const mainChart = echarts.init(chartDom);
|
||||
let finalData = [];
|
||||
|
||||
for (let key in props.datas) {
|
||||
finalData.push({
|
||||
name: key + "日",
|
||||
value: props.datas[key],
|
||||
});
|
||||
}
|
||||
// const data1 = [
|
||||
// {
|
||||
// name: "1日",
|
||||
// value: 220,
|
||||
// },
|
||||
// {
|
||||
// name: "2日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "3日",
|
||||
// value: 195,
|
||||
// },
|
||||
// {
|
||||
// name: "4日",
|
||||
// value: 245,
|
||||
// },
|
||||
// {
|
||||
// name: "5日",
|
||||
// value: 148,
|
||||
// },
|
||||
// {
|
||||
// name: "6日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "7日",
|
||||
// value: 56,
|
||||
// },
|
||||
// {
|
||||
// name: "8日",
|
||||
// value: 45,
|
||||
// },
|
||||
// {
|
||||
// name: "9日",
|
||||
// value: 250,
|
||||
// },
|
||||
// {
|
||||
// name: "10日",
|
||||
// value: 48,
|
||||
// },
|
||||
// {
|
||||
// name: "11日",
|
||||
// value: 95,
|
||||
// },
|
||||
// {
|
||||
// name: "12日",
|
||||
// value: 128,
|
||||
// },
|
||||
// {
|
||||
// name: "13日",
|
||||
// value: 34,
|
||||
// },
|
||||
// {
|
||||
// name: "14日",
|
||||
// value: 123,
|
||||
// },
|
||||
// {
|
||||
// name: "15日",
|
||||
// value: 175,
|
||||
// },
|
||||
// {
|
||||
// name: "16日",
|
||||
// value: 148,
|
||||
// },
|
||||
// ];
|
||||
let xAxisData = [];
|
||||
let seriesData1 = [];
|
||||
finalData.forEach((item) => {
|
||||
xAxisData.push(item.name);
|
||||
seriesData1.push(item.value);
|
||||
});
|
||||
var barWidth = 16;
|
||||
var barWidthBg = 25;
|
||||
const color = [
|
||||
{
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(16, 53, 41, 0.10)",
|
||||
},
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(57, 161, 59, 1)",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const seriesData = xAxisData.map((item, index) => {
|
||||
return {
|
||||
value: seriesData1[index],
|
||||
itemStyle: {
|
||||
borderRadius: [2, 2, 0, 0],
|
||||
color: color[0],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const option = {
|
||||
grid: {
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
bottom: "5%",
|
||||
top: "15%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
data: xAxisData,
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: "#B4C0CC",
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#B4C0CC",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: "#B4C0CC",
|
||||
fontSize: 12,
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#B4C0CC",
|
||||
opacity: 0.2,
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "bar",
|
||||
data: seriesData,
|
||||
barWidth: barWidth,
|
||||
},
|
||||
{
|
||||
type: "bar",
|
||||
data: seriesData,
|
||||
barWidth: barWidthBg,
|
||||
barGap: "-120%",
|
||||
itemStyle: {
|
||||
opacity: 0.2,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "pictorialBar",
|
||||
data: seriesData,
|
||||
symbolPosition: "end",
|
||||
symbolSize: [barWidth, 7],
|
||||
z: 12,
|
||||
symbolOffset: [-3, -3],
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "pictorialBar",
|
||||
data: seriesData,
|
||||
symbolPosition: "end",
|
||||
symbolSize: [barWidthBg, 6],
|
||||
itemStyle: {
|
||||
opacity: 0.2,
|
||||
},
|
||||
z: 11,
|
||||
symbolOffset: [-3, -3],
|
||||
},
|
||||
],
|
||||
};
|
||||
mainChart.setOption(option);
|
||||
};
|
||||
watch(
|
||||
() => props.datas,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="poleDailyDetectionChart" style="width: 862px; height: 100%"></div>
|
||||
</template>
|
@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<span>
|
||||
报表下载
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import ExcelJS from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
|
||||
// 模拟列表数据 (替换成你的真实数据)
|
||||
const listData = [
|
||||
{
|
||||
trainCode: 'T-20250508',
|
||||
trainType: 'C54K',
|
||||
occurrenceTime: 5785.67354,
|
||||
alarmType: '车辆损坏',
|
||||
faultType: '搭扣未扣',
|
||||
},
|
||||
];
|
||||
|
||||
// 模拟图片 URL (替换成你的真实图片URL)
|
||||
const imageUrl = ref(''); // Replace with the actual image URL
|
||||
const placeholderImageUrl = 'https://via.placeholder.com/150'; // Fallback
|
||||
|
||||
const convertImageToBase64 = async (url: string) => {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const blob = await response.blob();
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result as string);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error loading image:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const saveToExcel = async () => {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Sheet1');
|
||||
|
||||
// 1. 设置列宽 (根据你的内容调整)
|
||||
worksheet.getColumn('A').width = 15;
|
||||
worksheet.getColumn('B').width = 15;
|
||||
worksheet.getColumn('C').width = 15;
|
||||
worksheet.getColumn('D').width = 10; // Smaller width for '车型'
|
||||
worksheet.getColumn('E').width = 15;
|
||||
worksheet.getColumn('F').width = 15;
|
||||
worksheet.getColumn('G').width = 15;
|
||||
worksheet.getColumn('H').width = 10;
|
||||
worksheet.getColumn('I').width = 10;
|
||||
|
||||
|
||||
// 2. 添加头部数据
|
||||
worksheet.getCell('A1').value = '进场时间';
|
||||
worksheet.getCell('B1').value = '出场时间';
|
||||
worksheet.getCell('A3').value = '车厢编号';
|
||||
worksheet.getCell('C3').value = '1234567890'; // Example Value
|
||||
|
||||
// 3. 添加表格头部
|
||||
worksheet.getCell('C5').value = '列车编号';
|
||||
worksheet.getCell('D5').value = '车型';
|
||||
worksheet.getCell('E5').value = '发生时间';
|
||||
worksheet.getCell('F5').value = '告警类型';
|
||||
worksheet.getCell('G5').value = '故障类型';
|
||||
|
||||
// 4. 填充表格数据
|
||||
listData.forEach((item, index) => {
|
||||
const row = index + 6; // 从第6行开始
|
||||
worksheet.getCell(`C${row}`).value = item.trainCode;
|
||||
worksheet.getCell(`D${row}`).value = item.trainType;
|
||||
worksheet.getCell(`E${row}`).value = item.occurrenceTime;
|
||||
worksheet.getCell(`F${row}`).value = item.alarmType;
|
||||
worksheet.getCell(`G${row}`).value = item.faultType;
|
||||
});
|
||||
|
||||
// 5. 添加图片
|
||||
|
||||
// Load the image (using a data URL or URL)
|
||||
try {
|
||||
if (imageUrl.value) {
|
||||
const base64Image = await convertImageToBase64(imageUrl.value);
|
||||
|
||||
if (base64Image) {
|
||||
const imageId = workbook.addImage({
|
||||
base64: base64Image,
|
||||
extension: 'png', // Adjust extension if needed (jpeg, etc.)
|
||||
});
|
||||
|
||||
// Add the image to the worksheet
|
||||
worksheet.addImage(imageId, {
|
||||
tl: { col: 2, row: 8 }, // Top left corner of the image (C9 in Excel)
|
||||
br: { col: 7, row: 25 }, // Bottom right corner of the image (H26 in Excel)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error adding image:', error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 6. 添加 "车身缺陷" 文本
|
||||
worksheet.getCell('A17').value = '车身缺陷';
|
||||
|
||||
// 7. 设置 H 列的背景色
|
||||
for (let i = 8; i <= 28; i++) {
|
||||
const cell = worksheet.getCell(`H${i}`);
|
||||
cell.fill = {
|
||||
type: 'pattern',
|
||||
pattern: 'solid',
|
||||
fgColor: { argb: 'ADD8E6' }, // Light blue color
|
||||
};
|
||||
}
|
||||
|
||||
// 8. (Optional) Style the header rows
|
||||
const headerRange = 'A1:G5'; // Adjust as needed
|
||||
worksheet.getCell(headerRange).font = { bold: true };
|
||||
worksheet.getCell(headerRange).alignment = { vertical: 'middle', horizontal: 'center' }; // Center align headers
|
||||
|
||||
// 9. 下载 Excel 文件
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '车辆信息.xlsx');
|
||||
};
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
// Pre-load the image (or use a placeholder if loading fails)
|
||||
imageUrl.value = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/No-Image-Placeholder.svg/1665px-No-Image-Placeholder.svg.png'
|
||||
});
|
||||
|
||||
|
||||
</script>
|
@ -0,0 +1,53 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-06 15:52:40
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-09-05 14:00:15
|
||||
* @FilePath: \vite-ai\data-dashboard\src\components\contentHeader.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div class="flex items-center justify-between content_header_wrap"
|
||||
:style="{ 'background-image': `url(${sub_title_bg})`, 'background-size': 'cover', 'background-repeat': 'no-repeat', 'background-position': 'left bottom' }">
|
||||
<!-- 左侧标题区域 -->
|
||||
<div class="flex items-center left-section pl-[16px]">
|
||||
<img src="@/assets/common/sub_title_icon.png" class="w-[20px] h-[20px]">
|
||||
<div class="fg-title ml-[12px]">
|
||||
{{ title }}
|
||||
<slot name="title"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧内容 -->
|
||||
<div>
|
||||
<slot name="extra"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import sub_title_bg from '@/assets/home/sub_title_bg.png';
|
||||
// 定义组件 props
|
||||
const props = withDefaults(defineProps<{
|
||||
// bgLayout: number | string; // 背景样式 1855 918 800 450
|
||||
title: string; // 标题
|
||||
}>(), {
|
||||
// bgLayout: 1855,
|
||||
title: ""
|
||||
});
|
||||
|
||||
// 计算是否显示右侧内容
|
||||
// const bgImageUrl = computed(() => {
|
||||
// switch (Number(props.bgLayout)) {
|
||||
// default:
|
||||
// return sub_title_bg;
|
||||
// }
|
||||
// });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content_header_wrap {
|
||||
width: 431px;
|
||||
height: 38px;
|
||||
// border-image: linear-gradient(90deg, rgba(25, 61, 72, 0), rgba(67, 215, 226, 1), rgba(29, 65, 76, 0)) 1 1;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,168 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-14 13:38:30
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-20 09:46:29
|
||||
* @FilePath: \5G-Web\src\views\dashboard\components\SwpierMonitor.vue
|
||||
* @Description: 外观、撑杆统一封装轮播图&视频组件
|
||||
-->
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Player from "@/components/videoPlayer/Player.vue";
|
||||
import SwiperPlayer from "./swiperPlayer.vue";
|
||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||
import { Navigation, Scrollbar, Mousewheel, Pagination } from "swiper/modules";
|
||||
import "swiper/css";
|
||||
import "swiper/scss";
|
||||
import "swiper/scss/navigation";
|
||||
|
||||
interface Props {
|
||||
value: number;
|
||||
fileList: Record<string, any>[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: "update:value", val: boolean): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
value: false,
|
||||
fileList: [],
|
||||
});
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
|
||||
const modules = [Navigation, Scrollbar];
|
||||
const activeIndex = ref(-1);
|
||||
const swiperRef = ref(null);
|
||||
const isPlaying = ref<boolean>(false); // 是否播放
|
||||
const currFile = ref<Record<string, any>>({}); // 详情数据
|
||||
|
||||
const togglePlay = () => {
|
||||
isPlaying.value = !isPlaying.value;
|
||||
};
|
||||
|
||||
const handleSlideClick = (index) => {
|
||||
if (activeIndex.value === index) {
|
||||
togglePlay(); // 播放 暂停
|
||||
} else {
|
||||
isPlaying.value = false;
|
||||
emit("update:value", index);
|
||||
currFile.value = props.fileList[index];
|
||||
}
|
||||
};
|
||||
const onSwiper = (swiper) => {
|
||||
swiperRef.value = swiper;
|
||||
console.log("Swiper 实例已获取:", swiper);
|
||||
};
|
||||
const onSlideChange = () => {
|
||||
console.log("slide change");
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.fileList,
|
||||
(newVal) => {
|
||||
currFile.value = newVal?.[0];
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(newVal) => {
|
||||
console.log("swiperFile_newVal", newVal);
|
||||
activeIndex.value = newVal;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full fg-swiper-file-wrap">
|
||||
<!-- 缩略图区域 -->
|
||||
<div class="flex" v-if="fileList?.length > 0">
|
||||
<div class="thumbnail-container">
|
||||
<swiper
|
||||
ref="swiperRef"
|
||||
:modules="modules"
|
||||
:slides-per-view="4"
|
||||
:space-between="12"
|
||||
:navigation="true"
|
||||
:scrollbar="{ draggable: false }"
|
||||
:centered-slides="false"
|
||||
:observer="true"
|
||||
:observeParents="true"
|
||||
@swiper="onSwiper"
|
||||
@slideChange="onSlideChange"
|
||||
>
|
||||
<swiper-slide
|
||||
v-for="(file, index) in fileList"
|
||||
:key="index"
|
||||
@click="handleSlideClick(index)"
|
||||
:class="{ 'active-slide': activeIndex === index }"
|
||||
>
|
||||
<img
|
||||
:src="file?.image_url"
|
||||
v-if="file?.image_url"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<SwiperPlayer
|
||||
class="cursor-pointer"
|
||||
:videoUrl="file?.video_url"
|
||||
v-else-if="file?.video_url"
|
||||
:isPlaying="isPlaying && activeIndex === index"
|
||||
/>
|
||||
<div v-else>
|
||||
<!-- 视频【图片】加载失败 -->
|
||||
</div>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.fg-swiper-file-wrap {
|
||||
.thumbnail-container {
|
||||
overflow: visible;
|
||||
margin-right: 16px;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.swiper-slide {
|
||||
img,
|
||||
video {
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.active-slide img,
|
||||
.active-slide video {
|
||||
border-radius: 4px;
|
||||
border: 2px solid #2ecce0;
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.swiper-button-prev::after,
|
||||
.swiper-button-next::after {
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 修改按钮悬停样式 */
|
||||
.swiper-button-prev:hover,
|
||||
.swiper-button-next:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,147 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-14 13:38:30
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-09-10 11:42:43
|
||||
* @FilePath: \5G-Web\src\views\dashboard\components\SwpierMonitor.vue
|
||||
* @Description: 外观、撑杆统一封装轮播图&视频组件
|
||||
-->
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Player from "@/components/videoPlayer/Player.vue";
|
||||
import SwiperPlayer from "./swiperPlayer.vue";
|
||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||
import { Navigation, Scrollbar, Mousewheel, Pagination } from "swiper/modules";
|
||||
import "swiper/css";
|
||||
import "swiper/scss";
|
||||
import "swiper/scss/navigation";
|
||||
|
||||
interface Props {
|
||||
fileList: string[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: "update:value", val: boolean): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
fileList: [],
|
||||
});
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
|
||||
const modules = [Navigation, Scrollbar];
|
||||
const activeIndex = ref(-1);
|
||||
const swiperRef = ref(null);
|
||||
// const isPlaying = ref<boolean>(false); // 是否播放
|
||||
const currFile = ref<Record<string, any>>({}); // 详情数据
|
||||
|
||||
// const togglePlay = () => {
|
||||
// isPlaying.value = !isPlaying.value;
|
||||
// };
|
||||
|
||||
|
||||
const onSwiper = (swiper) => {
|
||||
swiperRef.value = swiper;
|
||||
console.log("Swiper 实例已获取:", swiper);
|
||||
};
|
||||
const onSlideChange = () => {
|
||||
console.log("slide change");
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.fileList,
|
||||
(newVal) => {
|
||||
currFile.value = newVal?.[0];
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full swiper-images-wrap">
|
||||
<!-- 缩略图区域 -->
|
||||
<div class="flex" v-if="fileList?.length > 0">
|
||||
<div class="thumbnail-container">
|
||||
<swiper
|
||||
ref="swiperRef"
|
||||
:modules="modules"
|
||||
:slides-per-view="2"
|
||||
:space-between="12"
|
||||
:navigation="true"
|
||||
:scrollbar="{ draggable: false }"
|
||||
:centered-slides="false"
|
||||
:observer="true"
|
||||
:observeParents="true"
|
||||
@swiper="onSwiper"
|
||||
@slideChange="onSlideChange"
|
||||
>
|
||||
<swiper-slide
|
||||
v-for="(file, index) in fileList"
|
||||
:key="index"
|
||||
:class="{ 'active-slide': activeIndex === index }"
|
||||
>
|
||||
<img
|
||||
:src="file"
|
||||
v-if="file"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<div v-else>
|
||||
<!-- 视频【图片】加载失败 -->
|
||||
</div>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.swiper-images-wrap {
|
||||
.thumbnail-container {
|
||||
overflow: visible;
|
||||
margin-right: 16px;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 1150px;
|
||||
.swiper-slide {
|
||||
img,
|
||||
video {
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.active-slide img,
|
||||
.active-slide video {
|
||||
width: 568px;
|
||||
border-radius: 4px;
|
||||
border: 2px solid #2ecce0;
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.swiper-button-prev::after,
|
||||
.swiper-button-next::after {
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 修改按钮悬停样式 */
|
||||
.swiper-button-prev:hover,
|
||||
.swiper-button-next:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,62 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-08-19 11:04:59
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-08-20 09:46:44
|
||||
* @FilePath: \5G-Web\src\components\Swiper\swiperPlayer.vue
|
||||
* @Description: 作为轮播文件中的视频块
|
||||
-->
|
||||
<template>
|
||||
<div class="flex items-center justify-center w-full h-full position-relative">
|
||||
<video
|
||||
ref="videoRef"
|
||||
:controls="false"
|
||||
muted
|
||||
:src="videoUrl"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style="object-fit: cover"
|
||||
@error="handleVideoError"
|
||||
v-if="!isVideoError"
|
||||
></video>
|
||||
<div class="bg_error_img" v-if="isVideoError"></div>
|
||||
<div :class="{ bg_icon: true, playing: isPlaying }" v-if="!isVideoError">
|
||||
<!-- {{ isPlaying }} -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps<{
|
||||
videoUrl: string;
|
||||
isPlaying: boolean;
|
||||
}>();
|
||||
const videoRef = ref<HTMLVideoElement | null>(null);
|
||||
const isVideoError = ref<boolean>(false);
|
||||
|
||||
const handleVideoError = () => {
|
||||
console.log("handleVideoError");
|
||||
isVideoError.value = true;
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bg_error_img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("@/assets/common/load_file_error.png") no-repeat center center;
|
||||
background-size: 50%;
|
||||
border: 1px dashed red;
|
||||
}
|
||||
|
||||
.bg_icon {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("@/assets/common/player_icon_1.png") no-repeat center center;
|
||||
background-size: 40px;
|
||||
|
||||
&.playing {
|
||||
background: url("@/assets/common/player_icon_2.png") no-repeat center center;
|
||||
background-size: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,52 @@
|
||||
export const dataViewConfig = {
|
||||
monthArr: [
|
||||
{
|
||||
name: "1月",
|
||||
value: "1",
|
||||
},
|
||||
{
|
||||
name: "2月",
|
||||
value: "2",
|
||||
},
|
||||
{
|
||||
name: "3月",
|
||||
value: "3",
|
||||
},
|
||||
{
|
||||
name: "4月",
|
||||
value: "4",
|
||||
},
|
||||
{
|
||||
name: "5月",
|
||||
value: "5",
|
||||
},
|
||||
{
|
||||
name: "6月",
|
||||
value: "6",
|
||||
},
|
||||
{
|
||||
name: "7月",
|
||||
value: "7",
|
||||
},
|
||||
{
|
||||
name: "8月",
|
||||
value: "8",
|
||||
},
|
||||
{
|
||||
name: "9月",
|
||||
value: "9",
|
||||
},
|
||||
{
|
||||
name: "10月",
|
||||
value: "10",
|
||||
},
|
||||
{
|
||||
name: "11月",
|
||||
value: "11",
|
||||
},
|
||||
{
|
||||
name: "12月",
|
||||
value: "12",
|
||||
},
|
||||
],
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
export const useDict = () => {
|
||||
// 外观监测故障类型
|
||||
const fetchAppearanceFaultTypeList = () => {
|
||||
return [
|
||||
"侧开门门板变形",
|
||||
"侧墙板外胀",
|
||||
"扶手变形",
|
||||
"扶梯变形",
|
||||
"配属标记不清",
|
||||
"下侧门折页圆销丢失",
|
||||
"载重标记不清",
|
||||
"搭扣未搭",
|
||||
];
|
||||
};
|
||||
|
||||
const fetchPoleFaultTypeList = () => {
|
||||
return ["钢管破损", "钢管锈蚀"];
|
||||
};
|
||||
return {
|
||||
fetchAppearanceFaultTypeList,
|
||||
fetchPoleFaultTypeList
|
||||
};
|
||||
};
|
@ -1,7 +1,14 @@
|
||||
// src/assets/fonts.scss
|
||||
@font-face {
|
||||
font-family: 'DingTalk JinBuTi'; // 自定义字体名称
|
||||
src: url('@/assets/fonts/DingTalk JinBuTi.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
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,121 +1,43 @@
|
||||
.appearance-monitor-warp {
|
||||
box-sizing: border-box;
|
||||
padding-top: 32px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.appearance-monitor-main-content {
|
||||
background-image: url("@/assets/appearanceMonitor/appearanceMonitor-main-bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
height: 584px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.search-section {
|
||||
padding: 16px 0;
|
||||
}
|
||||
.appearance-monitor-search-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
// align-items: center;
|
||||
.appearance-monitor-right {
|
||||
box-sizing: border-box;
|
||||
width:970px;
|
||||
// display: flex;
|
||||
background-image: url("@/assets/common/carbtmBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.appearance-monitor-body {
|
||||
padding: 0 24px;
|
||||
}
|
||||
.right-panel {
|
||||
width: calc(
|
||||
100% - var(--fg-swiper-monitor-slide-iamge-width) -
|
||||
var(--fg-swiper-monitor-main-iamge-width) - var(--fg-box-margin) * 2
|
||||
);
|
||||
.el-scrollbar__view {
|
||||
background: transparent !important;
|
||||
height: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
.appearance-monitor-search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 16px 0;
|
||||
.appearance-monitor-banner {
|
||||
.left-panel {
|
||||
width: calc(
|
||||
var(--fg-swiper-monitor-slide-iamge-width) +
|
||||
var(--fg-swiper-monitor-main-iamge-width) + var(--fg-box-margin)
|
||||
);
|
||||
max-height: 480px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.right-panel{
|
||||
.el-scrollbar__view {
|
||||
background: transparent !important;
|
||||
height: 600px;
|
||||
}
|
||||
.fixed_pagination{
|
||||
padding: 12px 20px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.appearance-monitor-left {
|
||||
width: 49%;
|
||||
background-image: url("@/assets/common/boderBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.monitor-left-top {
|
||||
box-sizing: border-box;
|
||||
padding: 32px 16px 20px;
|
||||
min-height: 600px;
|
||||
|
||||
.file-preview-screen {
|
||||
width: 100%;
|
||||
height: 590px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 460px;
|
||||
object-fit: cover
|
||||
}
|
||||
video {
|
||||
width: 100%;
|
||||
max-height: calc(100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
.monitor-left-bottom {
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
margin-bottom: 29px;
|
||||
overflow: visible;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.swiper-slide {
|
||||
width: 20%;
|
||||
border-radius:4px;
|
||||
height: 144px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 144px;
|
||||
border-radius:4px;
|
||||
object-fit: cover
|
||||
}
|
||||
}
|
||||
.active-slide img,
|
||||
.active-slide video {
|
||||
border-radius:4px;
|
||||
border: 2px solid #2ECCE0;
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.swiper-button-prev::after,
|
||||
.swiper-button-next::after {
|
||||
font-size: 12px ;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* 修改按钮悬停样式 */
|
||||
.swiper-button-prev:hover,
|
||||
.swiper-button-next:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty-bg {
|
||||
box-sizing: border-box;
|
||||
width: 892px;
|
||||
height: 815px;
|
||||
background-image: url("@/assets/common/emptyBg.png");
|
||||
background-size: 156px 102px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,149 +1,129 @@
|
||||
.data-overview-wrap {
|
||||
padding-top: 30px;
|
||||
// background: #002a5c;
|
||||
height: 852px;
|
||||
color: white;
|
||||
font-family: "Arial", sans-serif;
|
||||
.grid-container {
|
||||
display: flex;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
.grid-item {
|
||||
// background: rgba(74, 126, 191, 0.1);
|
||||
background-image: url("@/assets/common/gridItemBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
// border-radius: 8px;
|
||||
width: 50%;
|
||||
|
||||
&>li{
|
||||
width: 50%;
|
||||
}
|
||||
&>li:last-child{
|
||||
margin-left: 12px;
|
||||
}
|
||||
.module-header {
|
||||
color: #4a7ebf;
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 4px;
|
||||
.month-btn,
|
||||
.week-btn {
|
||||
width: 70px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
color: #FFF;
|
||||
background: #0F2839;
|
||||
color: #fff;
|
||||
background: #0f2839;
|
||||
border: none;
|
||||
}
|
||||
.week-btn {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.active-btn {
|
||||
background: #0B345E;
|
||||
border: 1px solid #3FDDEB;
|
||||
.active-btn {
|
||||
background: #0b345e;
|
||||
border: 1px solid #3fddeb;
|
||||
}
|
||||
}
|
||||
.chart-container {
|
||||
// margin-top: 0px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
.chart-container-bar {
|
||||
// margin-top: 0px;
|
||||
width: 100%;
|
||||
height: 340px;
|
||||
width: 431px;
|
||||
height: 221px;
|
||||
background: url("@/assets/home/sub_content_bg.png") no-repeat center;
|
||||
}
|
||||
.chart-pie-bg{
|
||||
margin-top: 19px;
|
||||
background-image: url("@/assets/common/gridItemPieBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
.grid-item-pie {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.device-list {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
padding: 0 16px 20px;
|
||||
gap: 10px;
|
||||
|
||||
.device-card {
|
||||
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;
|
||||
|
||||
.status-bar {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.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: 100% 100%;
|
||||
}
|
||||
|
||||
.monitor-images {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
gap: 16px;
|
||||
padding: 20px 16px 20px 16px;
|
||||
.monitor-images-left,
|
||||
.monitor-images-right {
|
||||
flex: 1;
|
||||
padding: 32px 16px 15px;
|
||||
flex-wrap: wrap;
|
||||
.monitor-images-item {
|
||||
width: calc(50% - 8px);
|
||||
height: 349px;
|
||||
border: 1px dashed #ccc;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 256px;
|
||||
// height: 100%;
|
||||
}
|
||||
.fault-info {
|
||||
position: absolute;
|
||||
padding: 0 10px;
|
||||
// miomwidth: 80px;
|
||||
height: 28px;
|
||||
background: rgba(0,0,0,0.6);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 16px 16px 16px 16px;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
font-size: 14px;
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.rightInfo-box {
|
||||
|
||||
// background: linear-gradient(180deg, rgba(7, 16, 19, 0) 0%, #081417 100%);
|
||||
|
||||
.right-info-content {
|
||||
height: 359px;
|
||||
background: linear-gradient(180deg, rgba(7, 16, 19, 0) 0%, #081417 100%);
|
||||
box-shadow: inset 2px 2px 4px 0px rgba(32, 174, 254, 0.6),
|
||||
inset -2px -2px 4px 0px rgba(32, 174, 254, 0.6);
|
||||
border-radius: 0px 0px 0px 0px;
|
||||
border: 1px solid #1fc6ff;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.device-info-box {
|
||||
.total-device {
|
||||
.device-total-icon {
|
||||
width: 96px;
|
||||
height: 102px;
|
||||
background: url("@/assets/common/deviceTotal.png") no-repeat center;
|
||||
background-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.device-list {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
padding: 24px 16px 24px;
|
||||
gap: 16px;
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.train-info-box{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,122 +1,38 @@
|
||||
.digger-monitor-warp {
|
||||
box-sizing: border-box;
|
||||
padding-top: 32px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
// align-items: center;
|
||||
.digger-monitor-right {
|
||||
box-sizing: border-box;
|
||||
width:970px;
|
||||
// display: flex;
|
||||
background-image: url("@/assets/common/carbtmBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.digger-monitor-main-content {
|
||||
background-image: url("@/assets/diggerMonitor/diggerMonitor-main-bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: bottom;
|
||||
background-repeat: no-repeat;
|
||||
height: 586px;
|
||||
margin-top: 20px;
|
||||
|
||||
.digger-monitor-search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.right-panel{
|
||||
.el-scrollbar__view {
|
||||
background: transparent !important;
|
||||
height: 600px;
|
||||
}
|
||||
.fixed_pagination{
|
||||
padding: 12px 20px 15px;
|
||||
}
|
||||
.digger-monitor-body {
|
||||
padding: 0 24px;
|
||||
}
|
||||
.digger-monitor-search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 24px 0 16px;;
|
||||
}
|
||||
.right-panel {
|
||||
width: calc(
|
||||
100% - var(--fg-swiper-monitor-slide-iamge-width) -
|
||||
var(--fg-swiper-monitor-main-iamge-width) - var(--fg-box-margin) * 2
|
||||
);
|
||||
.el-scrollbar__view {
|
||||
background: transparent !important;
|
||||
height: 360px;
|
||||
}
|
||||
|
||||
|
||||
.digger-monitor-left {
|
||||
width: 49%;
|
||||
background-image: url("@/assets/common/boderBg.png");
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
.monitor-left-top {
|
||||
box-sizing: border-box;
|
||||
padding: 32px 16px 20px;
|
||||
min-height: 600px;
|
||||
.file-preview-screen {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 492px;
|
||||
// background-color: red;
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
max-height: calc(100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
.monitor-left-bottom {
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
margin-bottom: 29px;
|
||||
overflow: visible;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.swiper-slide {
|
||||
width: 20%;
|
||||
border-radius:4px;
|
||||
height: 144px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 144px;
|
||||
border-radius:4px;
|
||||
object-fit: cover
|
||||
}
|
||||
}
|
||||
.active-slide img,
|
||||
.active-slide video {
|
||||
border-radius:4px;
|
||||
border: 2px solid #2ECCE0;
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.swiper-button-prev::after,
|
||||
.swiper-button-next::after {
|
||||
font-size: 12px ;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* 修改按钮悬停样式 */
|
||||
.swiper-button-prev:hover,
|
||||
.swiper-button-next:hover {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty-bg {
|
||||
box-sizing: border-box;
|
||||
width: 892px;
|
||||
height: 815px;
|
||||
background-image: url("@/assets/common/emptyBg.png");
|
||||
background-size: 156px 102px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
.digger-monitor-banner {
|
||||
.left-panel {
|
||||
width: calc(
|
||||
var(--fg-swiper-monitor-slide-iamge-width) +
|
||||
var(--fg-swiper-monitor-main-iamge-width) + var(--fg-box-margin)
|
||||
);
|
||||
max-height: 480px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|