341 lines
9.0 KiB
Vue
341 lines
9.0 KiB
Vue
<template>
|
||
<div style="flex: 1">
|
||
<Container name="累计数据对比" icon="cockpitItemIcon" size="opLargeBg" topSize="large">
|
||
<!-- 1. 移除 .kpi-content 的固定高度,改为自适应 -->
|
||
<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" />
|
||
</div>
|
||
<div class="right" style="
|
||
height: 380px;
|
||
display: flex;
|
||
width: 1220px;
|
||
background-color: rgba(249, 252, 255, 1);
|
||
">
|
||
<!-- <top-item /> -->
|
||
<operatingBar :dateData="dateData" @sort-change="sortChange" :chartData="chartData" />
|
||
</div>
|
||
</div>
|
||
</Container>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import Container from "../components/container.vue";
|
||
import operatingBar from "./operatingBar.vue";
|
||
import operatingTopBar from "./operatingTopBar.vue";
|
||
|
||
export default {
|
||
name: "ProductionStatus",
|
||
components: { Container, operatingBar, operatingTopBar },
|
||
props: {
|
||
salesTrendMap: {
|
||
type: Object,
|
||
default: () => ({}),
|
||
},
|
||
ytdData: {
|
||
type: Object,
|
||
default: () => ({}),
|
||
},
|
||
dateData: {
|
||
type: Object,
|
||
default: () => ({}),
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
chartData: null, // 初始化 chartData 为 null
|
||
groupData: {}, // 集团数据
|
||
factoryData: [] // 工厂数据
|
||
};
|
||
},
|
||
watch: {
|
||
ytdData: {
|
||
handler() {
|
||
this.processChartData();
|
||
},
|
||
immediate: true,
|
||
deep: true,
|
||
},
|
||
},
|
||
methods: {
|
||
sortChange(value) {
|
||
this.$emit('sort-change', value);
|
||
},
|
||
/**
|
||
* 判断rate对应的flag值(<1为0,>1为1)
|
||
* @param {number} rate 处理后的rate值(已*100)
|
||
* @returns {0|1} flag值
|
||
*/
|
||
getRateFlag(rate, real, target) {
|
||
if (isNaN(rate) || rate === null || rate === undefined) return 0;
|
||
|
||
// 1. 完成率 >= 100 => 达标
|
||
if (rate >= 100) return 1;
|
||
|
||
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
|
||
if (rate === 0 && target === 0) return 1;
|
||
|
||
// 其他情况 => 未达标
|
||
return 0;
|
||
},
|
||
|
||
/**
|
||
* 核心处理函数:在所有数据都准备好后,才组装 chartData
|
||
*/
|
||
processChartData() {
|
||
// 1. 处理集团数据 - 提取各字段到对应数组
|
||
this.groupData = this.ytdData.group || { rate: 0, diff: 0, real: 0, target: 0 };
|
||
|
||
// 集团各维度数据数组(单条数据,对应凯盛新能)
|
||
const groupTarget = [this.groupData.target]; // 预算值数组
|
||
const groupDiff = [this.groupData.diff]; // 差值数组
|
||
const groupReal = [this.groupData.real]; // 实际值数组
|
||
const groupRate = [this.groupData.rate]; // 完成率数组
|
||
// 新增:集团rate对应的flag
|
||
const groupFlag = [this.getRateFlag(groupRate[0], groupReal[0], groupTarget[0])];
|
||
|
||
console.log('集团数据数组:', {
|
||
groupTarget,
|
||
groupDiff,
|
||
groupReal,
|
||
groupRate,
|
||
groupFlag,
|
||
rawGroupData: this.groupData
|
||
});
|
||
|
||
// 2. 处理工厂数据 - 提取每个工厂的对应字段到数组
|
||
this.factoryData = this.ytdData.factory || [];
|
||
// 提取工厂名称数组
|
||
const factoryNames = this.factoryData.map(item => item.title || '');
|
||
// 提取工厂各维度数据数组
|
||
const factoryBudget = this.factoryData.map(item => item.budget || 0);
|
||
const factoryReal = this.factoryData.map(item => item.real || 0);
|
||
const factoryRate = this.factoryData.map(item => item.rate || 0);
|
||
const factoryDiff = this.factoryData.map(item => item.diff || 0);
|
||
// 新增:每个工厂rate对应的flag数组
|
||
const factoryFlags = this.factoryData.map(item => this.getRateFlag(item.rate, item.real, item.budget));
|
||
|
||
// 3. 组装最终的chartData(供子组件使用)
|
||
this.chartData = {
|
||
// 集团数据(对应凯盛新能)
|
||
group: {
|
||
locations: ['凯盛新能'], // 集团名称
|
||
targets: groupTarget, // 集团预算值数组
|
||
diff: groupDiff, // 集团差值数组
|
||
reals: groupReal, // 集团实际值数组
|
||
rate: groupRate, // 集团完成率数组
|
||
flags: groupFlag // 新增:集团rate对应的flag
|
||
},
|
||
// 工厂数据
|
||
factory: {
|
||
locations: factoryNames, // 工厂名称数组
|
||
targets: factoryBudget, // 工厂预算数组
|
||
reals: factoryReal, // 工厂实际值数组
|
||
rates: factoryRate, // 工厂完成率数组
|
||
diff: factoryDiff, // 工厂差值数组
|
||
flags: factoryFlags // 新增:工厂rate对应的flags数组
|
||
},
|
||
// 原始数据备份(方便后续使用)
|
||
rawData: {
|
||
group: this.groupData,
|
||
factory: this.factoryData
|
||
}
|
||
};
|
||
|
||
console.log('最终处理后的图表数据:', this.chartData);
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 3. 核心:滚动容器样式(固定高度+溢出滚动+隐藏滚动条) */
|
||
.scroll-container {
|
||
/* 1. 固定容器高度:根据页面布局调整(示例300px,超出则滚动) */
|
||
max-height: 210px;
|
||
/* 2. 溢出滚动:内容超出高度时显示滚动功能 */
|
||
overflow-y: auto;
|
||
/* 3. 隐藏横向滚动条(防止设备名过长导致横向滚动) */
|
||
overflow-x: hidden;
|
||
/* 4. 内边距:与标题栏和容器边缘对齐 */
|
||
padding: 10px 0;
|
||
|
||
/* 5. 隐藏滚动条(兼容主流浏览器) */
|
||
/* Chrome/Safari */
|
||
&::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
/* Firefox */
|
||
scrollbar-width: none;
|
||
/* IE/Edge */
|
||
-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>
|
||
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
||
.production-status-chart-tooltip {
|
||
background: #0a2b4f77 !important;
|
||
border: none !important;
|
||
backdrop-filter: blur(12px);
|
||
}
|
||
|
||
.production-status-chart-tooltip * {
|
||
color: #fff !important;
|
||
}
|
||
</style>
|