311 lines
7.8 KiB
Vue
311 lines
7.8 KiB
Vue
<template>
|
||
<div style="flex: 1">
|
||
<Container name="累计数据对比" icon="cockpitItemIcon" size="operatingLarge" topSize="large">
|
||
<div class="kpi-content" style="padding: 14px 16px; display: flex; width: 100%; gap: 16px">
|
||
<div class="left" style="
|
||
height: 380px;
|
||
display: flex;
|
||
width: 348px;
|
||
background-color: rgba(249, 252, 255, 1);
|
||
flex-direction: column;
|
||
">
|
||
<div style="
|
||
font-weight: 400;
|
||
font-size: 18px;
|
||
color: #000000;
|
||
line-height: 18px;
|
||
letter-spacing: 1px;
|
||
font-style: normal;
|
||
padding: 16px 0 0 16px;
|
||
">
|
||
集团情况
|
||
</div>
|
||
<operatingTopBar :chartData="chartData?.topBarData || {}" />
|
||
</div>
|
||
<div class="right" style="
|
||
height: 380px;
|
||
display: flex;
|
||
width: 1220px;
|
||
background-color: rgba(249, 252, 255, 1);
|
||
">
|
||
<operatingBar :dateData="dateData" :chartData="chartData?.barData || {}" />
|
||
</div>
|
||
</div>
|
||
</Container>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import Container from "../components/container.vue";
|
||
import operatingBar from "./operatingBar.vue";
|
||
import operatingTopBar from "./operatingTopBar.vue";
|
||
|
||
// 序号→地名映射表(levelId=序号)
|
||
const baseIndexToNameMap = {
|
||
7: "宜兴",
|
||
8: "漳州",
|
||
3: "自贡",
|
||
2: "桐城",
|
||
9: "洛阳",
|
||
5: "合肥",
|
||
10: "秦皇岛",
|
||
6: "宿迁"
|
||
};
|
||
|
||
export default {
|
||
name: "ProductionStatus",
|
||
components: { Container, operatingBar, operatingTopBar },
|
||
props: {
|
||
totalData: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
dateData: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
chartData: {
|
||
topBarData: { // levelId=1的整合数据
|
||
locations: [], // 固定为["凯盛新能"]
|
||
diff: [], // 差值数组
|
||
targets: [], // 预算值数组
|
||
reals: [], // 实际值数组
|
||
rate: [], // 完成率数组
|
||
flags: [] // 完成状态数组(0/1)
|
||
},
|
||
barData: { // levelId≠1的整合数据
|
||
locations: [], // levelId对应的baseIndexToNameMap中的地名
|
||
diff: [], // 对应差值数组
|
||
targets: [], // 预算值数组
|
||
reals: [], // 实际值数组
|
||
rate: [], // 完成率数组
|
||
flags: [] // 完成状态数组(0/1)
|
||
// baseIndexes: []// 对应levelId(序号)数组
|
||
}
|
||
},
|
||
};
|
||
},
|
||
watch: {
|
||
totalData: {
|
||
handler() {
|
||
this.processChartData();
|
||
},
|
||
immediate: true,
|
||
deep: true,
|
||
},
|
||
},
|
||
methods: {
|
||
/**
|
||
* 核心方法:按levelId匹配地名生成locations
|
||
*/
|
||
processChartData() {
|
||
// 初始化空数据结构
|
||
const initTopBarData = {
|
||
locations: [], diff: [], targets: [], reals: [], rate: [], flags: []
|
||
};
|
||
const initBarData = { locations: [], diff: [], targets: [], reals: [], rate: [], flags: [] };
|
||
|
||
if (!Array.isArray(this.totalData) || this.totalData.length === 0) {
|
||
this.chartData = { topBarData: initTopBarData, barData: initBarData };
|
||
return;
|
||
}
|
||
|
||
// 1. 处理levelId=1的整合数据(逻辑不变)
|
||
const level1Data = this.totalData.filter(item => item.levelId === 1);
|
||
const topBarData = { ...initTopBarData };
|
||
level1Data.forEach(item => {
|
||
if (!item.name) return;
|
||
topBarData.locations = ["凯盛新能"]; // levelId=1固定为凯盛新能
|
||
topBarData.diff.push(item.diffValue || 0);
|
||
topBarData.targets.push(item.targetValue || 0);
|
||
topBarData.reals.push(item.value || 0);
|
||
topBarData.rate.push(item.proportion || 0);
|
||
topBarData.flags.push(item.completed ? 1 : 0);
|
||
});
|
||
|
||
// 2. 处理levelId≠1的整合数据(核心:levelId匹配地名)
|
||
const barData = { ...initBarData };
|
||
// 筛选有效数据:levelId≠1 且 levelId在baseIndexToNameMap中
|
||
const validOtherData = this.totalData.filter(item => {
|
||
return item.levelId !== 1 && baseIndexToNameMap.hasOwnProperty(item.levelId);
|
||
});
|
||
|
||
// 遍历有效数据,填充locations(levelId→地名)
|
||
validOtherData.forEach(item => {
|
||
// 根据levelId(序号)从映射表获取对应地名
|
||
const baseName = baseIndexToNameMap[item.levelId];
|
||
if (baseName) { // 确保地名和原始名称有效
|
||
// barData.names.push(item.name); // 保留monData中的原始名称
|
||
barData.locations.push(baseName); // locations=levelId对应的地名(如levelId=7→宜兴)
|
||
barData.diff.push(item.diffValue || 0);
|
||
barData.targets.push(item.targetValue || 0);
|
||
barData.reals.push(item.value || 0);
|
||
barData.rate.push(item.proportion || 0);
|
||
barData.flags.push(item.completed ? 1 : 0);
|
||
// barData.baseIndexes.push(Number(item.levelId) || 0); // 序号转数字
|
||
}
|
||
});
|
||
|
||
// 3. 更新chartData
|
||
this.chartData = { topBarData, barData };
|
||
console.log('levelId=1数据:', this.chartData.topBarData);
|
||
console.log('levelId≠1数据(locations=levelId对应地名):', this.chartData.barData);
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 原有样式保持不变 */
|
||
.scroll-container {
|
||
max-height: 210px;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
padding: 10px 0;
|
||
|
||
&::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
scrollbar-width: none;
|
||
-ms-overflow-style: none;
|
||
}
|
||
|
||
.proBarInfo {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: 8px 27px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.proBarInfoEqInfo {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.slot {
|
||
width: 21px;
|
||
height: 23px;
|
||
background: rgba(0, 106, 205, 0.22);
|
||
backdrop-filter: blur(1.5px);
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #68b5ff;
|
||
line-height: 23px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.eq-name {
|
||
margin-left: 8px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #ffffff;
|
||
line-height: 18px;
|
||
letter-spacing: 1px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.eqStatus {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #ffffff;
|
||
line-height: 18px;
|
||
text-align: right;
|
||
font-style: normal;
|
||
}
|
||
|
||
.splitLine {
|
||
width: 1px;
|
||
height: 14px;
|
||
border: 1px solid #adadad;
|
||
margin: 0 8px;
|
||
}
|
||
|
||
.yield {
|
||
height: 18px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #00ffff;
|
||
line-height: 18px;
|
||
text-align: right;
|
||
font-style: normal;
|
||
}
|
||
|
||
.proBarInfoEqInfoLeft {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.proBarInfoEqInfoRight {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.proBarWrapper {
|
||
position: relative;
|
||
height: 10px;
|
||
margin-top: 6px;
|
||
border-radius: 5px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.proBarLine {
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(65deg, rgba(82, 82, 82, 0) 0%, #acacac 100%);
|
||
opacity: 0.2;
|
||
}
|
||
|
||
.proBarLineTop {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
height: 100%;
|
||
background: linear-gradient(65deg,
|
||
rgba(53, 223, 247, 0) 0%,
|
||
rgba(54, 220, 246, 0.92) 92%,
|
||
#36f6e5 100%,
|
||
#37acf5 100%);
|
||
border-radius: 5px;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.chartImgBottom {
|
||
position: absolute;
|
||
bottom: 45px;
|
||
left: 58px;
|
||
}
|
||
|
||
.line {
|
||
display: inline-block;
|
||
position: absolute;
|
||
left: 57px;
|
||
bottom: 42px;
|
||
width: 1px;
|
||
height: 20px;
|
||
background-color: #00e8ff;
|
||
}
|
||
</style>
|
||
|
||
<style>
|
||
.production-status-chart-tooltip {
|
||
background: #0a2b4f77 !important;
|
||
border: none !important;
|
||
backdrop-filter: blur(12px);
|
||
}
|
||
|
||
.production-status-chart-tooltip * {
|
||
color: #fff !important;
|
||
}
|
||
</style>
|