This commit is contained in:
‘937886381’
2025-11-12 16:56:14 +08:00
commit 1ea62af1d6
1135 changed files with 109385 additions and 0 deletions

View File

@@ -0,0 +1,263 @@
<template>
<div style="">
<Container name="利润影主要响因素" icon="cockpitItemIcon" size="profitMiddleBasic" topSize="KFAPTopTitle">
<div class="kpi-content" style="padding: 14px 16px; display: flex;width: 100%;">
<div class="left" style="width: 382px;">
<top-item :itemList="targetItemList" />
</div>
<div class="bottom"
style="height: 227px; margin-left: 16px; display: flex; width: 100%;background-color: rgba(249, 252, 255, 1);">
<KFAPMiddleBar :chartData="{
allPlaceNames, incomeValueData, profitProportionData, costValueData, costCompletedData
}" />
</div>
</div>
</Container>
</div>
</template>
<script>
import Container from './container.vue'
import topItem from './profit-item-middle.vue'
import KFAPMiddleBar from './KFAPMiddleBar.vue'
export default {
name: 'ProductionStatus',
components: { Container, topItem, KFAPMiddleBar },
props: {
middleChartData: {
type: Array,
default: () => []
},
middleItemData: {
type: Array,
default: () => []
},
},
data() {
return {
parentItemList: [
{ name: "营业收入", targetValue: 0, value: 0, proportion: 0, route: 'operatingRevenue' },
{ name: "成本", targetValue: 0, value: 0, proportion: 0, route: 'cost/cost' },
]
}
},
computed: {
allPlaceNames() {
if (!Array.isArray(this.middleChartData)) return [];
return this.middleChartData.map(item => this.cleanPlaceName(item.name)).filter(Boolean)
},
PlaceNames() {
if (!Array.isArray(this.middleChartData)) return [];
return this.middleChartData.map(item => item.name).filter(Boolean);
},
profitProportionData() {
if (!Array.isArray(this.middleChartData)) return [];
return this.PlaceNames.map(place => {
const target = this.middleChartData.find(item => item.name === place);
return target?.profitProportion || 0;
});
},
incomeValueData() {
if (!Array.isArray(this.middleChartData)) return [];
return this.PlaceNames.map(place => {
const target = this.middleChartData.find(item => item.name === place);
return target?.income || 0;
});
},
costValueData() {
if (!Array.isArray(this.middleChartData)) return [];
return this.PlaceNames.map(place => {
const target = this.middleChartData.find(item => item.name === place);
return target?.cost || 0;
});
},
costCompletedData() {
if (!Array.isArray(this.middleChartData)) return [];
return this.PlaceNames.map(place => {
const target = this.middleChartData.find(item => item.name === place);
return target?.costCompleted || 0;
});
},
targetItemList() {
// 基于 parentItemList 的名称,匹配 productAndSaleData 中对应名称的数据
return this.parentItemList.map(parentItem => {
// 按名称精准匹配name 完全一致才关联)
const productItem = this.middleItemData.find(
item => item.name === parentItem.name
) || {};
// 优先使用匹配到的 productItem 数据,缺失则用 parentItem 的默认值0
return {
name: parentItem.name, // 保留原名称(销量、产量等)
targetValue: productItem.targetValue ?? parentItem.targetValue ?? 0,
value: productItem.value ?? parentItem.value ?? 0,
proportion: productItem.proportion ?? parentItem.proportion ?? 0,
completed: productItem.completed ?? parentItem.completed ?? 1,
route: parentItem.route // 路由沿用 parentItem 的配置
};
});
}
},
methods: {
cleanPlaceName(place) {
return place?.replace('分公司', '') || ''; // 匹配“分公司”并替换为空兼容null/undefined
},
// // 唯一的地名提取方法(定义在 methods 中,确保是函数)
// extractPlace(item) {
// if (!item?.name) return ''; // 处理空值,避免报错
// const match = item.name.match(/(.+?)(基地|利润总额|营业收入|成本)/);
// return match ? match[1] : item.name;
// }
}
}
</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>