Files
yudao-dev/src/views/home/components/KFAP.vue
‘937886381’ 694beb5851 修改
2025-11-24 14:10:46 +08:00

266 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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, profitListData, 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);
},
profitListData() {
if (!Array.isArray(this.middleChartData)) return [];
return this.PlaceNames.map(place => {
const target = this.middleChartData.find(item => item.name === place);
console.log('target?.profit', target?.profit);
return target?.profit || 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>