Files
yudao-dev/src/views/home/productionCostAnalysisComponents/relatedIndicatorsAnalysis.vue
2026-04-24 08:51:39 +08:00

239 lines
7.1 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="flex: 1">
<Container :isShowTab="true" :name="title" icon="cockpitItemIcon" size="opLargeBg" topSize="large"
@tabChange="handleChange">
<div class="kpi-content" style="padding: 14px 16px; display: flex; width: 100%;">
<div class="topItem-container" style="display: flex; gap: 8px">
<div
v-for="item in sortedIndicators"
:key="item.key"
class="dashboard"
@click="item.route && handleDashboardClick(item.name,item.route)"
>
<div class="title">
{{ item.name }}·{{ item.unit }}
</div>
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
<span>完成率:<span style='color: #0B58FF;'>{{item.data.proportion}}%</span></span>
<span style='display: inline-block;margin-left: 10px;'>差值:<span :style="{color:item.data.completed>0?'#30B590':'#FF9423'}" >{{item.data.diffValue}}</span></span>
</div>
<operatingSingleBar :detailData="item.data"></operatingSingleBar>
</div>
</div>
</div>
</Container>
</div>
</template>
<script>
import Container from '../components/container.vue'
import operatingSingleBar from './operatingSingleBar.vue'
export default {
name: 'ProductionStatus', // 保持组件名一致如需区分可重命名为CostProductionStatus
components: { Container, operatingSingleBar },
props: {
// 参考第二个组件,改为接收 成本相关数据(支持月度/累计,与第二个组件格式统一)
relatedData: {
type: Object,
default: () => ({
relatedMon: [], // 成本月度数据(数组格式,存储各成本项)
relatedTotal: [] // 成本累计数据(数组格式,存储各成本项)
})
},
dateData: {
type: Object,
default: () => ({})
},
factory: {
type: [String, Number],
default: ''
},
title: {
type: String,
default: ''
},
month: {
type: String,
default: ''
},
},
data() {
return {
chart: null,
// 核心:当前激活的成本数据集(默认月度数据,与第二个组件逻辑一致)
activeData: this.relatedData.relatedMon || [],
currentTab: 'month'
}
},
computed: {
indicatorDefs() {
return [
{ key: 'rawMaterialCost', name: '原料成本',label:'原料成本', unit: '元/㎡', route: 'fuelCostAnalysis/fuelCostAnalysis'},
{ key: 'fuelCost', name: '燃料成本',label:'原片燃料成本', unit: '元/㎡', route: 'combustible/combustible'},
{ key: 'electricityCost', name: '电成本',label:'原片电成本', unit: '元/㎡', route: 'osElectricityCostAnalysis'},
{ key: 'laborCost', name: '人工成本',label:'人工成本', unit: '元/㎡', route: 'originalSheetLabor'},
{ key: 'manufacturingCost', name: '制造费用',label:'制造费用', unit: '元/㎡', route: 'mfgOverheadCostAnalysis/mfgOverheadCostAnalysis'},
]
},
indicators() {
const fallback = { targetValue: 0, value: 0, completed: 0, diffValue: 0 }
const list = (Array.isArray(this.activeData) ? this.activeData : [])
return this.indicatorDefs.map(def => {
const data = list.find(item => item && item.name === def.label) || fallback
return {
...def,
data,
sortValue: Number((data && data.value) ?? 0)
}
})
},
sortedIndicators() {
const unitOrder = ['元/㎡']
const unitRank = (u) => {
const idx = unitOrder.indexOf(u)
return idx === -1 ? 999 : idx
}
return this.indicators.slice().sort((a, b) => {
const ur = unitRank(a.unit) - unitRank(b.unit)
if (ur !== 0) return ur
const vr = (b.sortValue ?? -Infinity) - (a.sortValue ?? -Infinity)
if (vr !== 0) return vr
return String(a.key).localeCompare(String(b.key))
})
}
},
watch: {
// 监听父组件传递的itemData变化同步更新激活数据集与第二个组件逻辑一致
relatedData: {
handler(newVal) {
if (this.currentTab === 'month') {
this.activeData = newVal.relatedMon || [];
}else{
this.activeData = newVal.relatedTotal || [];
}
},
immediate: true,
deep: true
}
},
mounted() {
console.log('成本组件挂载时的激活数据:', this.activeData);
},
methods: {
handleChange(value) {
console.log('Tab 切换值:', value);
this.currentTab = value;
// 根据 Tab 值更新当前激活的数据集
if (value === 'month') {
// 切换为月度数据
this.activeData = this.relatedData.relatedMon || [];
} else {
// 切换为累计数据(非 month 均视为累计,可根据实际需求调整判断条件)
this.activeData = this.relatedData.relatedTotal || [];
}
console.log('当前激活数据集:', this.activeData);
},
// 成本项点击事件:保留跳转功能,优化参数传递
handleDashboardClick(material,path) {
// 2. 优化路由跳转month放入query中修复原代码参数错误
this.$router.push({
path: path,
query: {
name: material,
month: this.month,
factory: this.$route.query.factory ? this.$route.query.factory : this.factory,
dateData: this.dateData
}
});
// 3. 向父组件传递事件(携带当前成本项的详细数据)
// this.$emit('dashboard-click', {
// material,
// month: this.month,
// data: this.activeData.find(item => item.name === material) || {}
// });
},
}
}
</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;
}
.dashboard {
width: 310px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 10px;
flex-shrink: 0; // 固定宽度,不被挤压(与第二个组件一致)
.title {
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 18px;
color: #000000;
line-height: 18px;
letter-spacing: 2px;
}
.number {
display: flex;
align-items: center;
gap: 30px;
height: 32px;
font-family: YouSheBiaoTiHei;
font-size: 32px;
color: #0B58FF;
line-height: 32px;
letter-spacing: 2px;
text-align: left;
}
.mom {
width: 97px;
height: 18px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 18px;
color: #000000;
line-height: 18px;
letter-spacing: 1px;
text-align: left;
z-index: 1000;
}
// .line {
// width: 280px; // 适配310px宽度避免图表溢出
// height: 150px; // 与第二个组件图表高度一致
// }
}
/* 隐藏横向滚动条,与第二个组件样式统一 */
.topItem-container::-webkit-scrollbar {
display: none;
}
.topItem-container {
scrollbar-width: none;
-ms-overflow-style: none;
}
</style>