463 lines
11 KiB
Vue
463 lines
11 KiB
Vue
|
|
<template>
|
|||
|
|
<Card title="各装置实际进度">
|
|||
|
|
<div class="device-list">
|
|||
|
|
<div class="select-right">
|
|||
|
|
<el-cascader
|
|||
|
|
size="small"
|
|||
|
|
v-model="dataInfo.checkedNodeData.id"
|
|||
|
|
:options="dataInfo.listData"
|
|||
|
|
:props="{ value: 'id', label: 'deviceUnitName' }"
|
|||
|
|
@change="handleChange"
|
|||
|
|
:show-all-levels="false"
|
|||
|
|
/>
|
|||
|
|
<el-select v-model="dataInfo.deviceYearInfo.id" size="small" @change="selectChange">
|
|||
|
|
<el-option v-for="(item, index) in dataInfo.deviceYearList" :key="index" :label="item.year" :value="item.id" />
|
|||
|
|
</el-select>
|
|||
|
|
</div>
|
|||
|
|
<div class="centerBottom">
|
|||
|
|
<div
|
|||
|
|
v-if="dataInfo.listData.length > 0"
|
|||
|
|
id="stateTotal"
|
|||
|
|
class="chart"
|
|||
|
|
ref="lineCharts"
|
|||
|
|
></div>
|
|||
|
|
<div v-else>
|
|||
|
|
<div class="not-data">
|
|||
|
|
<img src="@/assets/images/noData.png" />
|
|||
|
|
<p>暂无数据</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</Card>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup lang="ts">
|
|||
|
|
import Card from "@/components/card.vue";
|
|||
|
|
import { ref, onMounted, reactive, nextTick } from "vue";
|
|||
|
|
import * as echarts from "echarts";
|
|||
|
|
import symbolIcon from "@/assets/images/lineSymbol.png";
|
|||
|
|
import { getDeviceScheduleListApi, getDeviceYearListApi, getProgressPlanEquipmentTreeApi } from "@/api/modules/schedulePlan";
|
|||
|
|
import { GlobalStore } from "@/stores";
|
|||
|
|
const store = GlobalStore();
|
|||
|
|
function selectChange(e: any) {
|
|||
|
|
const find = dataInfo.deviceYearList.find((item: any) => item.id == dataInfo.deviceYearInfo.id);
|
|||
|
|
if (find) {
|
|||
|
|
dataInfo.deviceYearInfo = JSON.parse(JSON.stringify(find));
|
|||
|
|
getDeviceScheduleList();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const dataInfo = reactive({
|
|||
|
|
deviceScheduleList: [] as any[],
|
|||
|
|
deviceYearInfo: {} as any,
|
|||
|
|
deviceYearList: [] as any[],
|
|||
|
|
listData: [] as any[],
|
|||
|
|
checkedNodeData: {} as any
|
|||
|
|
});
|
|||
|
|
const lineCharts = ref(null);
|
|||
|
|
|
|||
|
|
const lineChartsFn = (el: any) => {
|
|||
|
|
console.log(el);
|
|||
|
|
let ageChart = echarts.init(el);
|
|||
|
|
const maxCount = dataInfo.deviceScheduleList.reduce((prev, item) => {
|
|||
|
|
const currentActual = Math.ceil(Number(item.currentActual));
|
|||
|
|
const currentPlan = Math.ceil(Number(item.currentPlan));
|
|||
|
|
const max = currentActual > currentPlan ? currentActual : currentPlan;
|
|||
|
|
prev = max > prev ? max : prev;
|
|||
|
|
return prev;
|
|||
|
|
}, 0); // 最大显示数量
|
|||
|
|
|
|||
|
|
console.log(maxCount);
|
|||
|
|
let option = {
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: "axis"
|
|||
|
|
},
|
|||
|
|
// toolbox: {
|
|||
|
|
// feature: {
|
|||
|
|
// dataView: { show: true, readOnly: false },
|
|||
|
|
// magicType: { show: true, type: ['line', 'bar'] },
|
|||
|
|
// restore: { show: true },
|
|||
|
|
// saveAsImage: { show: true }
|
|||
|
|
// }
|
|||
|
|
// },
|
|||
|
|
legend: {
|
|||
|
|
align: "left", //图例位置
|
|||
|
|
itemGap: 15, //图例之间的间隔
|
|||
|
|
orient: "vertical",
|
|||
|
|
x: "right", //可设定图例在左、右、居中
|
|||
|
|
y: "center", //可设定图例在上、下、居中
|
|||
|
|
padding: [0, 20, 0, 0], //可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
icon: "roundRect",
|
|||
|
|
name: "当期计划"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
icon: "roundRect",
|
|||
|
|
name: "当期实际"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
icon: "circle",
|
|||
|
|
name: "累计计划"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
icon: "circle",
|
|||
|
|
name: "累计实际"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
itemWidth: 10,
|
|||
|
|
itemHeight: 10,
|
|||
|
|
textStyle: {
|
|||
|
|
color: "#ffffff" //字体颜色
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
left: "5%",
|
|||
|
|
right: "12%",
|
|||
|
|
bottom: "10%",
|
|||
|
|
containLabel: true
|
|||
|
|
},
|
|||
|
|
// toolbox: {
|
|||
|
|
// feature: {
|
|||
|
|
// saveAsImage: {}
|
|||
|
|
// }
|
|||
|
|
// },
|
|||
|
|
xAxis: {
|
|||
|
|
// name: "月份", //X轴标题
|
|||
|
|
type: "category",
|
|||
|
|
// boundaryGap: false,
|
|||
|
|
data: dataInfo.deviceScheduleList.map(item => item.year + "-" + item.month),
|
|||
|
|
axisPointer: {
|
|||
|
|
type: "shadow"
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: "#193c81"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
show: true,
|
|||
|
|
interval: 0,
|
|||
|
|
textStyle: {
|
|||
|
|
color: "#ffffff"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
yAxis: [
|
|||
|
|
{
|
|||
|
|
name: "累计", //Y轴标题
|
|||
|
|
type: "value",
|
|||
|
|
axisTick: {
|
|||
|
|
// 轴刻度
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
// 轴线
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: "#193c81"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
// color: 'rgba(255,255,255,1)',
|
|||
|
|
color: "#fff"
|
|||
|
|
},
|
|||
|
|
nameTextStyle: {
|
|||
|
|
padding: [0, 0, 0, -30], // 四个数字分别为上右下左与原位置距离
|
|||
|
|
color: "#fff"
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
type: "dashed",
|
|||
|
|
color: "#193c81"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
show: true,
|
|||
|
|
textStyle: {
|
|||
|
|
color: "#ffffff"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "当期", //Y轴标题
|
|||
|
|
min: 0,
|
|||
|
|
max: maxCount,
|
|||
|
|
// interval: 2,
|
|||
|
|
type: "value",
|
|||
|
|
axisTick: {
|
|||
|
|
// 轴刻度
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
// 轴线
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: "#193c81"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
color: "#ffffff"
|
|||
|
|
},
|
|||
|
|
nameTextStyle: {
|
|||
|
|
padding: [0, 0, 0, 0], // 四个数字分别为上右下左与原位置距离
|
|||
|
|
color: "#fff"
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: false,
|
|||
|
|
lineStyle: {
|
|||
|
|
type: "dashed",
|
|||
|
|
color: "#193c81"
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
show: true,
|
|||
|
|
textStyle: {
|
|||
|
|
color: "#ffffff"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: "当期计划",
|
|||
|
|
type: "bar",
|
|||
|
|
yAxisIndex: 1,
|
|||
|
|
data: dataInfo.deviceScheduleList.map(item => item.currentPlan),
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
color: "rgba(210,210,250,1)"
|
|||
|
|
},
|
|||
|
|
barWidth: 10 // 设置柱子粗细
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "当期实际",
|
|||
|
|
type: "bar",
|
|||
|
|
yAxisIndex: 1,
|
|||
|
|
// stack: 'Total',
|
|||
|
|
data: dataInfo.deviceScheduleList.map(item => item.currentActual),
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
color: "rgba(251,242,183,1)"
|
|||
|
|
},
|
|||
|
|
barWidth: 10 // 设置柱子粗细
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "累计计划",
|
|||
|
|
type: "line",
|
|||
|
|
// stack: 'Total',
|
|||
|
|
data: dataInfo.deviceScheduleList.map(item => item.cumulativePlan),
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
color: "rgba(97,106,220,1)"
|
|||
|
|
},
|
|||
|
|
symbol: "circle", //将小圆点改成实心 不写symbol默认空心
|
|||
|
|
symbolSize: 5 //小圆点的大小
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "累计实际",
|
|||
|
|
type: "line",
|
|||
|
|
// stack: 'Total',
|
|||
|
|
data: dataInfo.deviceScheduleList.map(item => item.cumulativeActual),
|
|||
|
|
itemStyle: {
|
|||
|
|
//颜色 默认灰色
|
|||
|
|
color: "rgba(246,210,16,1)"
|
|||
|
|
},
|
|||
|
|
symbol: "circle", //将小圆点改成实心 不写symbol默认空心
|
|||
|
|
symbolSize: 5 //小圆点的大小
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
dataZoom: [
|
|||
|
|
{
|
|||
|
|
type: "slider", //隐藏或显示(true)组件
|
|||
|
|
show: dataInfo.deviceScheduleList.length > 12 ? true : false,
|
|||
|
|
// backgroundColor: "rgb(19, 63, 100)", // 组件的背景颜色。
|
|||
|
|
// fillerColor: "rgb(16, 171, 198)", // 选中范围的填充颜色。
|
|||
|
|
// borderColor: "rgb(19, 63, 100)", // 边框颜色
|
|||
|
|
showDetail: false, //是否显示detail,即拖拽时候显示详细数值信息
|
|||
|
|
startValue: 0,
|
|||
|
|
endValue: 11,
|
|||
|
|
filterMode: "empty",
|
|||
|
|
width: "50%", //滚动条高度
|
|||
|
|
height: 6, //滚动条显示位置
|
|||
|
|
left: "center",
|
|||
|
|
zoomLoxk: true, // 是否锁定选择区域(或叫做数据窗口)的大小
|
|||
|
|
handleSize: 0, //控制手柄的尺寸
|
|||
|
|
bottom: 0 // dataZoom-slider组件离容器下侧的距离
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
//没有下面这块的话,只能拖动滚动条,鼠标滚轮在区域内不能控制外部滚动条
|
|||
|
|
type: "inside",
|
|||
|
|
zoomOnMouseWheel: false, //滚轮是否触发缩放
|
|||
|
|
moveOnMouseMove: true, //鼠标滚轮触发滚动
|
|||
|
|
moveOnMouseWheel: true
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
} as any;
|
|||
|
|
ageChart.setOption(option);
|
|||
|
|
window.addEventListener("resize", () => {
|
|||
|
|
ageChart.resize();
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
const getDeviceScheduleList = () => {
|
|||
|
|
let data = {
|
|||
|
|
projectSn: store.sn,
|
|||
|
|
pageNo: 1,
|
|||
|
|
pageSize: -1,
|
|||
|
|
deviceUnitId: dataInfo.checkedNodeData.id,
|
|||
|
|
year: dataInfo.deviceYearInfo.year == "全部" ? "" : dataInfo.deviceYearInfo.year
|
|||
|
|
// isFilterQualityRegionEnterprise: 1
|
|||
|
|
};
|
|||
|
|
getDeviceScheduleListApi(data).then((res: any) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
dataInfo.deviceScheduleList = res.result.records;
|
|||
|
|
nextTick(() => {
|
|||
|
|
lineChartsFn(lineCharts.value);
|
|||
|
|
});
|
|||
|
|
console.log("查询装置主进度计划详情信息", dataInfo.deviceScheduleList);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
//查询装置主进度计划年份信息
|
|||
|
|
const getDeviceYearList = () => {
|
|||
|
|
let data = {
|
|||
|
|
projectSn: store.sn,
|
|||
|
|
pageNo: 1,
|
|||
|
|
pageSize: -1,
|
|||
|
|
deviceUnitId: dataInfo.checkedNodeData.id
|
|||
|
|
// isFilterQualityRegionEnterprise: 1
|
|||
|
|
};
|
|||
|
|
getDeviceYearListApi(data).then((res: any) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
dataInfo.deviceYearList = [
|
|||
|
|
{
|
|||
|
|
id: "",
|
|||
|
|
year: "全部"
|
|||
|
|
},
|
|||
|
|
...res.result.records
|
|||
|
|
];
|
|||
|
|
dataInfo.deviceYearInfo = JSON.parse(JSON.stringify(dataInfo.deviceYearList[0]));
|
|||
|
|
console.log("查询装置主进度计划年份信息", dataInfo.deviceYearList);
|
|||
|
|
getDeviceScheduleList();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
//获取左侧---列表信息
|
|||
|
|
const getDangerTypeRecordList = () => {
|
|||
|
|
console.log(22);
|
|||
|
|
let data = {
|
|||
|
|
projectSn: store.sn,
|
|||
|
|
hasAll: 1
|
|||
|
|
};
|
|||
|
|
getProgressPlanEquipmentTreeApi(data).then((res: any) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
if (res.result.length > 0) {
|
|||
|
|
dataInfo.listData = [
|
|||
|
|
// {
|
|||
|
|
// id: '',
|
|||
|
|
// children: [],
|
|||
|
|
// deviceUnitName: '全部'
|
|||
|
|
// },
|
|||
|
|
...res.result
|
|||
|
|
];
|
|||
|
|
dataInfo.checkedNodeData.id = dataInfo.listData[0].id;
|
|||
|
|
getDeviceYearList();
|
|||
|
|
console.log("获取左侧---列表信息", dataInfo.listData);
|
|||
|
|
} else {
|
|||
|
|
dataInfo.listData = [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleChange = (e: any) => {
|
|||
|
|
// console.log('handleChange', e);
|
|||
|
|
// // const find = dataInfo.listData.find((item: any) => item.id == dataInfo.checkedNodeData.id[dataInfo.checkedNodeData.id.length - 1]);
|
|||
|
|
// const find = nodeTree(dataInfo.listData, e[e.length - 1]);
|
|||
|
|
// const resultList = find.filter((item:any) => item.length > 0)
|
|||
|
|
// console.log('handleChange', find);
|
|||
|
|
// if(resultList && resultList[0]) {
|
|||
|
|
// dataInfo.checkedNodeData = resultList[0][0].deviceUnitName == "全部装置" ? dataInfo.listData[0] : resultList[0][0];
|
|||
|
|
// getDeviceYearList();
|
|||
|
|
// }
|
|||
|
|
dataInfo.checkedNodeData.id = e[e.length - 1];
|
|||
|
|
getDeviceYearList();
|
|||
|
|
|
|||
|
|
console.log("handleChange", dataInfo.checkedNodeData, dataInfo.listData, e);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const nodeTree = (node: any, id: any) => {
|
|||
|
|
return node
|
|||
|
|
.map((item: any) => {
|
|||
|
|
if (item.id == id)
|
|||
|
|
return {
|
|||
|
|
...item
|
|||
|
|
};
|
|||
|
|
if (item.children && item.children.length > 0) {
|
|||
|
|
return nodeTree(item.children, id).filter((item: any) => item !== undefined);
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.filter((item: any) => item !== undefined);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
onMounted(async () => {
|
|||
|
|
// await getChartTotal();
|
|||
|
|
// draw();
|
|||
|
|
getDangerTypeRecordList();
|
|||
|
|
// console.log("Mount_type", dialogIndex.value);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="scss">
|
|||
|
|
.device-list {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
position: relative;
|
|||
|
|
.select-right {
|
|||
|
|
position: absolute;
|
|||
|
|
right: 3%;
|
|||
|
|
width: 15%;
|
|||
|
|
top: -18%;
|
|||
|
|
z-index: 9;
|
|||
|
|
display: flex;
|
|||
|
|
> div:not(:first-child) {
|
|||
|
|
margin-left: 20px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.centerBottom {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
position: relative;
|
|||
|
|
.chart {
|
|||
|
|
width: 920px;
|
|||
|
|
height: 228px;
|
|||
|
|
}
|
|||
|
|
.not-data {
|
|||
|
|
width: 20%;
|
|||
|
|
position: absolute;
|
|||
|
|
top: 50%;
|
|||
|
|
left: 50%;
|
|||
|
|
transform: translate(-50%, -50%);
|
|||
|
|
img {
|
|||
|
|
width: 40%;
|
|||
|
|
margin: 5% 30%;
|
|||
|
|
}
|
|||
|
|
p {
|
|||
|
|
color: #fff;
|
|||
|
|
font-size: calc(100vw * 14 / 1920);
|
|||
|
|
margin: 0;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|