2025-05-21 11:24:53 +08:00
|
|
|
|
<template>
|
|
|
|
|
<div class="situation">
|
|
|
|
|
<div class="main">
|
|
|
|
|
<div class="title">
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
<img src="@/assets/images/ligner.png" alt="" />
|
|
|
|
|
<div class="w100% flex justify-between items-center">
|
|
|
|
|
<div class="subTitle flex items-center">
|
|
|
|
|
<img src="@/assets/images/jigong.png" alt="" />
|
|
|
|
|
<span>人员情况</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="hint">PERSONNEL SITUATION</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mark"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ligner"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="cardList">
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="iconImg">
|
|
|
|
|
<img src="@/assets/images/totalnumber.png" alt="" />
|
|
|
|
|
</div>
|
|
|
|
|
<p>总人数</p>
|
|
|
|
|
<div class="peopleNum">
|
2025-07-30 16:25:45 +08:00
|
|
|
|
<span>{{ constructionUserData?.headcount }}</span
|
|
|
|
|
>人
|
2025-05-21 11:24:53 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="iconImg">
|
|
|
|
|
<img src="@/assets/images/attendanceperson.png" alt="" />
|
|
|
|
|
</div>
|
|
|
|
|
<p>出勤人</p>
|
|
|
|
|
<div class="peopleNum">
|
2025-07-30 16:25:45 +08:00
|
|
|
|
<span>{{ constructionUserData?.responseCunt }}</span
|
|
|
|
|
>人
|
2025-05-21 11:24:53 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="iconImg">
|
|
|
|
|
<img src="@/assets/images/Attendancerate.png" alt="" />
|
|
|
|
|
</div>
|
|
|
|
|
<p>出勤率</p>
|
|
|
|
|
<div class="peopleNum">
|
2025-07-30 16:25:45 +08:00
|
|
|
|
<span>{{ constructionUserData?.ratio }} </span>%
|
2025-05-21 11:24:53 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="title">
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
<img src="@/assets/images/ligner.png" alt="" />
|
|
|
|
|
<div class="flex justify-between w100% items-center">
|
|
|
|
|
<div class="subTitle flex items-center">
|
|
|
|
|
<img src="@/assets/images/Machinery.png" alt="" />
|
|
|
|
|
<span>机械情况</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="hint">MECHANICAL CONDITION</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mark"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ligner"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="machinery" id="machineryMain"></div>
|
|
|
|
|
<div class="title">
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
<img src="@/assets/images/ligner.png" alt="" />
|
|
|
|
|
<div class="flex justify-between w100% items-center">
|
|
|
|
|
<div class="subTitle flex items-center">
|
|
|
|
|
<img src="@/assets/images/order.png" alt="" />
|
|
|
|
|
<span>材料情况</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="hint">MATERIAL STATUS</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mark"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ligner"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="order" id="orderMain"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="topleft"></div>
|
|
|
|
|
<div class="bottomright"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { getConstructionUserList, getMachineryrList, getMaterialsList } from '@/api/gis';
|
|
|
|
|
import { ConstructionUserVO, MachineryrVO, MaterialsVO } from '@/api/gis/type';
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
import { useUserStoreHook } from '@/store/modules/user';
|
|
|
|
|
import { enableEchartsAutoScroll } from '@/plugins/scrollEcharts';
|
|
|
|
|
const userStore = useUserStoreHook();
|
|
|
|
|
//echarts节点
|
|
|
|
|
const myMachineryChart = ref(null);
|
|
|
|
|
const myOrderChart = ref(null);
|
|
|
|
|
|
|
|
|
|
type EChartsOption = echarts.EChartsOption;
|
|
|
|
|
const constructionUserData = ref<ConstructionUserVO>(null);
|
|
|
|
|
const machineryOption = ref<MachineryrVO[]>([]); //机械
|
|
|
|
|
const orderOption = ref<MaterialsVO[]>([]); //材料
|
|
|
|
|
const stopMachineryScroll = ref(null);
|
|
|
|
|
const stopOrderScroll = ref(null);
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const machineryDataAxis = computed(() => machineryOption.value.map((item) => item.statusName)); //x轴数据
|
|
|
|
|
const machineryData = computed(() => machineryOption.value.map((item) => item.statusNumber)); //柱状图数据
|
|
|
|
|
const orderDataAxis = computed(() => orderOption.value.map((item) => item.equipmentMaterialsName)); //材料x轴数据
|
|
|
|
|
const orderPutData = computed(() => orderOption.value.map((item) => item.inventoryNumber)); //柱状图领用量数据
|
|
|
|
|
const orderOutData = computed(() => orderOption.value.map((item) => item.outboundNumber)); //柱状图出库量数据
|
2025-05-21 11:24:53 +08:00
|
|
|
|
const orderRankingData = computed(() => orderOption.value.map((item) => item.value)); //柱状图库存数据
|
|
|
|
|
// 从 store 中获取项目列表和当前选中的项目
|
|
|
|
|
const currentProject = computed(() => userStore.selectedProject);
|
|
|
|
|
|
|
|
|
|
//获取施工人员信息
|
|
|
|
|
const getConstructionUserData = async () => {
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const res = await getConstructionUserList({ projectId: currentProject.value.goId });
|
|
|
|
|
if (res.code !== 0) return;
|
2025-05-21 11:24:53 +08:00
|
|
|
|
constructionUserData.value = res.data;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//查询大屏机械列表
|
|
|
|
|
const getMachineryData = async () => {
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const res = await getMachineryrList({ projectId: currentProject.value.goId });
|
|
|
|
|
if (res.code !== 0) return;
|
|
|
|
|
const merged = Object.values(
|
|
|
|
|
res.data.list.reduce(
|
|
|
|
|
(acc, item) => {
|
|
|
|
|
if (!acc[item.statusName]) {
|
|
|
|
|
acc[item.statusName] = { ...item };
|
|
|
|
|
} else {
|
|
|
|
|
acc[item.statusName].statusNumber += item.statusNumber;
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{} as Record<string, { statusName: string; statusNumber: number }>
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
machineryOption.value = merged as any;
|
2025-05-21 11:24:53 +08:00
|
|
|
|
initMachinerycharts();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//查询大屏材料信息
|
|
|
|
|
const getOrderData = async () => {
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const res = await getMaterialsList({ projectId: currentProject.value.goId });
|
|
|
|
|
if (res.code !== 0) return;
|
|
|
|
|
orderOption.value = res.data.list;
|
2025-05-21 11:24:53 +08:00
|
|
|
|
initOrderChart();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const initMachinerycharts = () => {
|
|
|
|
|
let chartDom = document.getElementById('machineryMain');
|
|
|
|
|
myMachineryChart.value = markRaw(echarts.init(chartDom));
|
|
|
|
|
let option: EChartsOption;
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const { max, interval, splitNumber } = calcYAxisOptions(machineryData.value);
|
2025-05-21 11:24:53 +08:00
|
|
|
|
option = {
|
|
|
|
|
title: {
|
|
|
|
|
subtext: '单位:台数'
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
// 让图表占满容器
|
|
|
|
|
top: '45vh',
|
|
|
|
|
bottom: '50vh'
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
data: machineryDataAxis.value,
|
|
|
|
|
axisLabel: {
|
|
|
|
|
// inside: true,
|
|
|
|
|
color: 'rgba(202, 218, 226, 1)',
|
|
|
|
|
|
2025-07-30 16:25:45 +08:00
|
|
|
|
fontSize: 13,
|
|
|
|
|
interval: 0,
|
|
|
|
|
formatter: function (value: string) {
|
|
|
|
|
// 每5个字符换行(你可以根据需要改成4或6)
|
|
|
|
|
const maxLineLength = 5;
|
|
|
|
|
let result = '';
|
|
|
|
|
for (let i = 0; i < value.length; i += maxLineLength) {
|
|
|
|
|
result += value.slice(i, i + maxLineLength) + '\n';
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2025-05-21 11:24:53 +08:00
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
z: 10
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
2025-07-30 16:25:45 +08:00
|
|
|
|
max,
|
|
|
|
|
interval,
|
|
|
|
|
splitNumber,
|
2025-05-21 11:24:53 +08:00
|
|
|
|
axisLine: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
color: '#999',
|
|
|
|
|
fontSize: 12
|
|
|
|
|
},
|
|
|
|
|
splitLine: {
|
|
|
|
|
show: true,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: 'rgba(108, 128, 151, 0.3)',
|
|
|
|
|
width: 1,
|
|
|
|
|
type: 'dashed'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
dataZoom: [
|
|
|
|
|
{
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'slider',
|
|
|
|
|
xAxisIndex: 0,
|
|
|
|
|
// 滚动条背景颜色
|
|
|
|
|
backgroundColor: 'rgba(8, 14, 15, .3)',
|
|
|
|
|
// 选中区域的背景颜色
|
|
|
|
|
fillerColor: {
|
|
|
|
|
type: 'linear',
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
x2: 0,
|
|
|
|
|
y2: 1,
|
|
|
|
|
colorStops: [
|
|
|
|
|
{
|
|
|
|
|
offset: 0,
|
|
|
|
|
color: 'rgba(67, 226, 203, 1)' // 0% 处的颜色
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
offset: 1,
|
|
|
|
|
color: 'rgba(21, 181, 230, 1)' // 100% 处的颜色
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
global: false // 缺省为 false
|
|
|
|
|
},
|
|
|
|
|
showDataShadow: false,
|
|
|
|
|
// 手柄大小
|
|
|
|
|
showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
|
|
|
|
|
moveHandleSize: 0, //移动手柄的大小
|
|
|
|
|
// 滚动条高度
|
|
|
|
|
height: 12,
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
borderColor: 'rgba(8, 14, 15, .3)',
|
|
|
|
|
// 滚动条与图表的距离
|
|
|
|
|
bottom: 5,
|
|
|
|
|
handleSize: 5,
|
|
|
|
|
// dataZoom-slider组件离容器下侧的距离
|
|
|
|
|
// bottom: 0,
|
|
|
|
|
// 两侧缩放手柄的 icon 形状
|
|
|
|
|
handleIcon:
|
|
|
|
|
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 画一个圆形
|
|
|
|
|
handleStyle: {
|
|
|
|
|
borderWidth: 5,
|
|
|
|
|
borderCap: 'round',
|
|
|
|
|
borderRadius: 20, // 设置滑块的圆角大小
|
|
|
|
|
color: 'rgba(27,90,169,1)', // 设置滑块的颜色
|
|
|
|
|
shadowBlur: 3, // 设置滑块阴影的模糊大小
|
|
|
|
|
shadowColor: 'rgba(0, 0, 0, 0.6)', // 设置滑块阴影的颜色
|
|
|
|
|
shadowOffsetX: 1, // 设置滑块阴影的水平偏移
|
|
|
|
|
shadowOffsetY: 2 // 设置滑块阴影的垂直偏移
|
|
|
|
|
},
|
|
|
|
|
start: 0,
|
|
|
|
|
// 计算初始结束百分比
|
2025-07-30 16:25:45 +08:00
|
|
|
|
end: (3 / machineryData.value.length) * 100
|
2025-05-21 11:24:53 +08:00
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
type: 'bar',
|
|
|
|
|
showBackground: true,
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
|
{ offset: 0, color: 'rgba(25, 181, 251, 1)' },
|
|
|
|
|
{ offset: 1, color: 'rgba(67, 158, 255, 0)' }
|
|
|
|
|
])
|
|
|
|
|
},
|
|
|
|
|
barWidth: '13vh',
|
|
|
|
|
data: machineryData.value
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
option && myMachineryChart.value.setOption(option);
|
|
|
|
|
stopMachineryScroll.value = enableEchartsAutoScroll(myMachineryChart.value, machineryDataAxis.value.length, 6, 2000);
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-30 16:25:45 +08:00
|
|
|
|
const calcYAxisOptions = (data: number[]) => {
|
|
|
|
|
const maxValue = Math.max(...data);
|
|
|
|
|
const paddedMax = Math.ceil(maxValue * 1.2); // 给柱子顶部留空间
|
|
|
|
|
|
|
|
|
|
// 自动控制 Y 轴分几段:比如让每段差不多 2~5 个单位
|
|
|
|
|
let interval = Math.ceil(paddedMax / 5);
|
|
|
|
|
let splitNumber = Math.ceil(paddedMax / interval);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
max: paddedMax,
|
|
|
|
|
interval,
|
|
|
|
|
splitNumber
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-21 11:24:53 +08:00
|
|
|
|
const initOrderChart = () => {
|
|
|
|
|
let chartDom = document.getElementById('orderMain');
|
|
|
|
|
|
|
|
|
|
myOrderChart.value = markRaw(echarts.init(chartDom));
|
|
|
|
|
let option: EChartsOption;
|
|
|
|
|
|
|
|
|
|
option = {
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
// Use axis to trigger tooltip
|
|
|
|
|
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
left: 'right', //位置
|
|
|
|
|
icon: 'roundRect', //形状 类型包括 circle,rect,line,roundRect,triangle,diamond,pin,arrow,none
|
|
|
|
|
itemWidth: 15, // 设置宽度
|
|
|
|
|
itemHeight: 4, // 设置高度
|
|
|
|
|
itemGap: 27, // 设置间距
|
|
|
|
|
top: 10, // 设置圆角
|
|
|
|
|
data: ['入库量', '领用量'],
|
|
|
|
|
textStyle: {
|
|
|
|
|
//文字样式
|
|
|
|
|
color: '#B4CEFF',
|
|
|
|
|
fontSize: '12'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
left: '5%', //距离dom间距
|
|
|
|
|
right: '4%',
|
|
|
|
|
top: '20%',
|
|
|
|
|
bottom: '1%',
|
|
|
|
|
height: '80%'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: orderDataAxis.value,
|
|
|
|
|
offset: 0,
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
inverse: true,
|
|
|
|
|
axisLabel: {
|
|
|
|
|
formatter: function (value) {
|
|
|
|
|
let bgType = '';
|
|
|
|
|
let index = orderDataAxis.value.indexOf(value);
|
|
|
|
|
switch (index) {
|
|
|
|
|
case 0:
|
|
|
|
|
bgType = 'a';
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
bgType = 'b';
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
bgType = 'c';
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return `No.${index + 1} {value|${value}}`;
|
|
|
|
|
}
|
|
|
|
|
return `{${bgType}|No.${index + 1}} {value|${value}}`;
|
|
|
|
|
},
|
|
|
|
|
align: 'left',
|
|
|
|
|
verticalAlign: 'bottom',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
// 横坐标 分割线等取消显示
|
|
|
|
|
padding: [0, 10, 10, 6],
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
color: 'rgba(230, 247, 255, 1)',
|
|
|
|
|
rich: {
|
|
|
|
|
a: {
|
|
|
|
|
color: 'rgba(230, 247, 255, 1)',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
align: 'center',
|
|
|
|
|
width: 31,
|
|
|
|
|
height: 23,
|
|
|
|
|
backgroundColor: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
|
|
|
{ offset: 0, color: 'rgba(255, 208, 59, 1)' },
|
|
|
|
|
{ offset: 1, color: 'rgba(255, 208, 59, 0)' }
|
|
|
|
|
])
|
|
|
|
|
},
|
|
|
|
|
b: {
|
|
|
|
|
color: 'rgba(230, 247, 255, 1)',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
align: 'left',
|
|
|
|
|
width: 31,
|
|
|
|
|
height: 23,
|
|
|
|
|
backgroundColor: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
|
|
|
{ offset: 0, color: 'rgba(31, 189, 237, 1)' },
|
|
|
|
|
{ offset: 1, color: 'rgba(31, 189, 237, 0)' }
|
|
|
|
|
])
|
|
|
|
|
},
|
|
|
|
|
c: {
|
|
|
|
|
color: 'rgba(230, 247, 255, 1)',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
align: 'left',
|
|
|
|
|
width: 31,
|
|
|
|
|
height: 23,
|
|
|
|
|
backgroundColor: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
|
|
|
{ offset: 0, color: 'rgba(67, 226, 203, 1)' },
|
|
|
|
|
{ offset: 1, color: 'rgba(67, 226, 203, 0)' }
|
|
|
|
|
])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
dataZoom: [
|
|
|
|
|
{
|
|
|
|
|
// 设置滚动条的隐藏或显示
|
|
|
|
|
show: true,
|
|
|
|
|
// 设置类型
|
|
|
|
|
type: 'slider',
|
|
|
|
|
// 设置背景颜色
|
|
|
|
|
backgroundColor: 'rgba(8, 14, 15, .3)',
|
|
|
|
|
|
|
|
|
|
// 设置选中范围的填充颜色
|
|
|
|
|
fillerColor: {
|
|
|
|
|
type: 'linear',
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
x2: 0,
|
|
|
|
|
y2: 1,
|
|
|
|
|
colorStops: [
|
|
|
|
|
{
|
|
|
|
|
offset: 0,
|
|
|
|
|
color: 'rgba(67, 226, 203, .5)' // 0% 处的颜色
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
offset: 1,
|
|
|
|
|
color: 'rgba(21, 181, 230, .5)' // 100% 处的颜色
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
global: false // 缺省为 false
|
|
|
|
|
},
|
|
|
|
|
borderColor: 'rgba(8, 14, 15, .3)',
|
|
|
|
|
borderCap: 'round',
|
|
|
|
|
// 是否显示detail,即拖拽时候显示详细数值信息
|
|
|
|
|
showDetail: false,
|
|
|
|
|
// handleSize: 0,
|
|
|
|
|
moveHandleSize: 0, //移动手柄的大小
|
|
|
|
|
borderRadius: 20, //滚动条圆角
|
|
|
|
|
// 数据窗口范围的起始数值
|
|
|
|
|
startValue: 0,
|
|
|
|
|
// 数据窗口范围的结束数值(一页显示多少条数据)
|
|
|
|
|
endValue: 4,
|
|
|
|
|
handleSize: 5,
|
|
|
|
|
// dataZoom-slider组件离容器下侧的距离
|
|
|
|
|
// bottom: 0,
|
|
|
|
|
// 两侧缩放手柄的 icon 形状
|
|
|
|
|
handleIcon:
|
|
|
|
|
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 画一个圆形
|
|
|
|
|
handleStyle: {
|
|
|
|
|
borderWidth: 5,
|
|
|
|
|
borderCap: 'round',
|
|
|
|
|
borderRadius: 20, // 设置滑块的圆角大小
|
|
|
|
|
color: 'rgba(27,90,169,1)', // 设置滑块的颜色
|
|
|
|
|
shadowBlur: 3, // 设置滑块阴影的模糊大小
|
|
|
|
|
shadowColor: 'rgba(0, 0, 0, 0.6)', // 设置滑块阴影的颜色
|
|
|
|
|
shadowOffsetX: 1, // 设置滑块阴影的水平偏移
|
|
|
|
|
shadowOffsetY: 2 // 设置滑块阴影的垂直偏移
|
|
|
|
|
},
|
|
|
|
|
// 控制哪个轴,如果是number表示控制一个轴,
|
|
|
|
|
// 如果是Array表示控制多个轴。此处控制第二根轴
|
|
|
|
|
yAxisIndex: [0, 1],
|
|
|
|
|
// empty:当前数据窗口外的数据,被设置为空。
|
|
|
|
|
// 即不会影响其他轴的数据范围
|
|
|
|
|
filterMode: 'empty',
|
|
|
|
|
// 滚动条高度
|
|
|
|
|
width: 12,
|
|
|
|
|
// 滚动条显示位置
|
|
|
|
|
height: '70%',
|
|
|
|
|
// 距离右边
|
|
|
|
|
right: 5,
|
|
|
|
|
showDataShadow: false, //是否显示数据阴影 默认auto
|
|
|
|
|
// 组件离容器上侧的距离
|
|
|
|
|
// 如果top的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐
|
|
|
|
|
top: 'middle'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 没有下面这块的话,只能拖动滚动条,
|
|
|
|
|
// 鼠标滚轮在区域内不能控制外部滚动条
|
|
|
|
|
type: 'inside',
|
|
|
|
|
// 控制哪个轴,如果是number表示控制一个轴,
|
|
|
|
|
// 如果是Array表示控制多个轴。此处控制第二根轴
|
|
|
|
|
yAxisIndex: [0, 1],
|
|
|
|
|
width: 20,
|
|
|
|
|
// 滚轮是否触发缩放
|
|
|
|
|
zoomOnMouseWheel: false,
|
|
|
|
|
// 鼠标移动能否触发平移
|
|
|
|
|
moveOnMouseMove: true,
|
|
|
|
|
// 鼠标滚轮能否触发平移
|
|
|
|
|
moveOnMouseWheel: true
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '入库量',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
stack: 'total',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: 'rgba(67, 226, 203, 1)'
|
|
|
|
|
},
|
|
|
|
|
emphasis: {
|
|
|
|
|
focus: 'series'
|
|
|
|
|
},
|
|
|
|
|
data: orderPutData.value,
|
|
|
|
|
barWidth: 3
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '领用量',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
stack: 'total',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: 'rgba(31, 189, 237, 1)'
|
|
|
|
|
},
|
|
|
|
|
emphasis: {
|
|
|
|
|
focus: 'series'
|
|
|
|
|
},
|
|
|
|
|
data: orderOutData.value,
|
|
|
|
|
showBackground: true,
|
|
|
|
|
barWidth: 3,
|
|
|
|
|
backgroundStyle: {
|
|
|
|
|
color: 'rgba(217, 231, 255, 0.1)'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
option && myOrderChart.value.setOption(option);
|
|
|
|
|
stopOrderScroll.value = enableEchartsAutoScroll(myOrderChart.value, orderDataAxis.value.length, 5, 2000);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 防抖函数
|
|
|
|
|
const debounce = <T,>(func: (this: T, ...args: any[]) => void, delay: number) => {
|
|
|
|
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
|
return function (this: T, ...args: any[]) {
|
|
|
|
|
const context = this;
|
|
|
|
|
if (timer) clearTimeout(timer);
|
|
|
|
|
timer = setTimeout(() => {
|
|
|
|
|
func.apply(context, args);
|
|
|
|
|
}, delay);
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 窗口大小变化时触发的函数
|
|
|
|
|
const handleResize = () => {
|
|
|
|
|
myMachineryChart.value && myMachineryChart.value.dispose();
|
|
|
|
|
myOrderChart.value && myOrderChart.value.dispose();
|
|
|
|
|
initMachinerycharts();
|
|
|
|
|
initOrderChart();
|
|
|
|
|
};
|
|
|
|
|
const debouncedHandleResize = debounce(handleResize, 300);
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getOrderData();
|
|
|
|
|
getConstructionUserData();
|
|
|
|
|
getMachineryData();
|
|
|
|
|
window.addEventListener('resize', debouncedHandleResize); //监听窗口变化重新生成echarts
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
window.removeEventListener('resize', debouncedHandleResize);
|
|
|
|
|
stopMachineryScroll.value();
|
|
|
|
|
stopOrderScroll.value();
|
2025-06-18 19:56:54 +08:00
|
|
|
|
myMachineryChart.value && myMachineryChart.value.dispose();
|
2025-05-21 11:24:53 +08:00
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
@import '../css/gis.scss';
|
|
|
|
|
|
|
|
|
|
#machineryMain {
|
|
|
|
|
width: vw(421);
|
|
|
|
|
height: vh(222);
|
|
|
|
|
margin-left: vw(14);
|
|
|
|
|
margin-bottom: vh(30);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#orderMain {
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding-right: vw(14);
|
|
|
|
|
height: vh(335);
|
|
|
|
|
}
|
|
|
|
|
.title {
|
|
|
|
|
> div > img {
|
|
|
|
|
width: vw(14);
|
|
|
|
|
height: vh(35);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.subTitle {
|
|
|
|
|
img {
|
|
|
|
|
width: vw(18.8);
|
|
|
|
|
height: vh(20);
|
|
|
|
|
margin-right: vw(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
text-shadow: 0 0 vw(8) rgba(2, 3, 7, 0.35);
|
|
|
|
|
font-size: vw(16);
|
|
|
|
|
letter-spacing: 0;
|
|
|
|
|
color: rgba(255, 255, 255, 1);
|
|
|
|
|
font-family: 'DOUYUFont';
|
|
|
|
|
padding-top: vh(5);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hint {
|
|
|
|
|
font-size: vw(14);
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
color: rgba(204, 204, 204, 0.5);
|
|
|
|
|
margin-right: vw(20);
|
|
|
|
|
font-family: 'Roboto';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mark {
|
|
|
|
|
width: vw(2);
|
|
|
|
|
height: vh(14);
|
|
|
|
|
background: rgba(67, 226, 203);
|
|
|
|
|
margin-right: vw(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ligner {
|
|
|
|
|
height: vh(1);
|
|
|
|
|
background: linear-gradient(to right, transparent 0%, #43e2cb 90%);
|
|
|
|
|
margin-left: vw(14);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.situation {
|
|
|
|
|
width: vw(449);
|
|
|
|
|
height: vh(927);
|
|
|
|
|
background: rgb(1, 26, 33, 0.4);
|
|
|
|
|
backdrop-filter: blur(vw(8));
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: vh(122);
|
|
|
|
|
left: vw(21);
|
|
|
|
|
z-index: 2;
|
|
|
|
|
.main {
|
|
|
|
|
padding-top: vh(30);
|
|
|
|
|
|
|
|
|
|
.cardList {
|
|
|
|
|
padding: 0 vw(20);
|
|
|
|
|
margin-top: vh(20);
|
|
|
|
|
margin-bottom: vh(30);
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
.card {
|
|
|
|
|
border: vw(1) dashed rgba(67, 226, 203, 0.3);
|
|
|
|
|
width: vw(112);
|
|
|
|
|
height: vh(155);
|
|
|
|
|
padding-top: vh(15);
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: rgba(255, 255, 255, 1);
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
width: vw(44);
|
|
|
|
|
margin-bottom: vh(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> p {
|
|
|
|
|
font-size: vw(14);
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
margin-bottom: vh(10);
|
|
|
|
|
font-family: '思源黑体';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.peopleNum {
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
font-size: vw(14);
|
|
|
|
|
|
|
|
|
|
text-shadow: 0 vw(1.24) vw(6.21) rgba(0, 190, 247, 1);
|
|
|
|
|
color: rgba(230, 247, 255, 1);
|
|
|
|
|
font-family: 'Roboto';
|
|
|
|
|
span {
|
|
|
|
|
font-size: vw(24);
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
padding: vw(2);
|
|
|
|
|
background: linear-gradient(to bottom right, #43e2cb 0%, transparent 50%);
|
|
|
|
|
-webkit-mask:
|
|
|
|
|
linear-gradient(#fff 0 0) content-box,
|
|
|
|
|
linear-gradient(#fff 0 0);
|
|
|
|
|
mask-composite: exclude;
|
|
|
|
|
opacity: 0.4;
|
|
|
|
|
z-index: -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.topleft {
|
|
|
|
|
width: vw(7);
|
|
|
|
|
height: vw(7);
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: vh(1);
|
|
|
|
|
left: vw(1);
|
|
|
|
|
background-image: url('@/assets/images/topleft.png');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottomright {
|
|
|
|
|
width: vw(7);
|
|
|
|
|
height: vw(7);
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
background-image: url('@/assets/images/bottomright.png');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|