Files
yudao-dev/src/views/home/components/financeCosts.vue
2026-04-14 13:54:05 +08:00

402 lines
10 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组件 -->
<Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch" @tabChange='tabChange'>
<div class="bottom-left-content" style="display: flex;gap: 0px;padding: 14px 16px;flex-direction: column;">
<!-- 根据activeTab状态切换显示采购/存货内容 -->
<template v-if="activeTab === 'purchase'">
<!-- 财务重点指标应的内容 -->
<coreBottomLeftItem :dateData="dateData" :finance="financeData"></coreBottomLeftItem>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<coreBottomBar :dateData="dateData" :line="finance.line"></coreBottomBar>
</div>
</template>
<template v-else-if="activeTab === 'inventory'">
<!-- 费用重点指标对应的内容 -->
<costItem :dateData="dateData" :cost="costData" :currentTap='currentTap'></costItem>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 4px;background-color: rgba(249, 252, 255, 1);">
<CostsBottomBar :line="cost.line" :dateData="dateData">
</CostsBottomBar>
</div>
</template>
</div>
</Container>
</div>
</template>
<script>
import Container from './financeCostsContainer.vue'
import * as echarts from 'echarts'
import coreBottomLeftItem from './purchase-Item.vue'
import coreBottomBar from './financeCostsBottomBar.vue'
import costItem from './cost-Item.vue'
import CostsBottomBar from './CostsBottomBar.vue'
export default {
name: 'ProductionStatus',
components: { Container, coreBottomLeftItem, coreBottomBar, costItem, CostsBottomBar },
props: {
finance: {
type: Object,
default: () => {}
},
cost: {
type: Object,
default: () => ({})
},
dateData: {
type: Object,
default: () => ({})
}
},
data() {
return {
activeTab: 'purchase', // 激活的标签purchase=采购inventory=存货
showChart: true, // 控制图表是否显示
chart: null, // 图表实例
financeData:{},
costData:{},
currentTap: 'month'
}
},
watch: {
// 切换标签时更新图表
activeTab(newVal) {
this.$nextTick(() => this.updateChart())
},
productionOverviewVo: {
handler() {
this.updateChart()
},
deep: true
},
finance: {
handler() {
if(this.currentTap === 'month') {
this.financeData = this.finance.mon
}else{
this.financeData = this.finance.total
}
},
deep: true
},
cost: {
handler() {
if(this.currentTap === 'month') {
this.costData = this.cost.mon
}else{
this.costData = this.cost.total
}
},
deep: true
}
},
mounted() {
// 初始化图表
this.$nextTick(() => this.updateChart())
},
beforeDestroy() {
// 销毁图表,避免内存泄漏
if (this.chart) {
this.chart.dispose()
this.chart = null
}
},
methods: {
tabChange(val) {
if(val === 'month') {
this.currentTap = 'month'
this.financeData = this.finance.mon
this.costData = this.cost.mon
}else{
this.currentTap = 'total'
this.financeData = this.finance.total
this.costData = this.cost.total
}
},
// 处理标题点击切换标签
handleTabSwitch(tabType) {
this.activeTab = tabType // tabType由Container组件传递'purchase'或'inventory'
this.showChart = true // 切换时默认显示图表(可根据需求调整)
},
// 更新图表内容
updateChart() {
const chartDom = document.getElementById('productionStatusChart')
if (!chartDom) return
// 销毁已有图表实例
if (this.chart) this.chart.dispose()
this.chart = echarts.init(chartDom)
// 根据当前激活的标签,设置对应图表数据(示例:可根据实际需求修改)
const data = this.activeTab === 'purchase'
? [
this.productionOverviewVo.purchaseInput || 0,
this.productionOverviewVo.purchaseOutput || 0,
this.productionOverviewVo.purchaseNg || 0,
0, 0, 0, 0 // 补充默认值,避免图表报错
]
: [
this.productionOverviewVo.inventoryInput || 0,
this.productionOverviewVo.inventoryOutput || 0,
this.productionOverviewVo.inventoryNg || 0,
0, 0, 0, 0
]
const option = {
type: 'bar',
grid: { left: 51, right: 40, top: 50, bottom: 45 },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
className: 'production-status-chart-tooltip'
},
xAxis: {
type: 'category',
offset: 8,
data: this.activeTab === 'purchase'
? ['采购投入', '采购产出', '采购待判', '低价值', '报废', '在制', '实验片']
: ['存货投入', '存货产出', '存货待判', '低价值', '报废', '在制', '实验片'],
axisTick: { show: false },
axisLine: { show: true, onZero: false, lineStyle: { color: '#00E8FF' } },
axisLabel: {
color: 'rgba(255,255,255,0.7)',
fontSize: 12,
interval: 0,
width: 38,
overflow: 'break'
}
},
yAxis: {
type: 'value',
name: '单位/片',
nameTextStyle: { color: 'rgba(255,255,255,0.7)', fontSize: 14, align: 'left' },
min: 0,
max: (value) => Math.ceil(value.max),
axisTick: { show: false },
axisLabel: { color: 'rgba(255,255,255,0.7)', fontSize: 12 },
splitLine: { lineStyle: { color: 'RGBA(24, 88, 100, 0.6)', type: 'dashed' } },
axisLine: { show: true, lineStyle: { color: '#00E8FF' } }
},
series: [
{
type: 'pictorialBar',
label: { show: true, position: 'top', distance: -3, color: '#89CDFF', fontSize: 11 },
symbolSize: [20, 8],
symbolOffset: [0, 5],
z: 20,
itemStyle: {
borderColor: '#3588C7',
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'RGBA(22, 89, 98, 1)' },
{ offset: 1, color: '#3588C7' }
])
},
data: data
},
{
type: 'bar',
barWidth: 20,
itemStyle: {
borderWidth: 1,
borderColor: '#3588C7',
opacity: 0.8,
color: {
x: 0, y: 0, x2: 0, y2: 1,
type: 'linear',
global: false,
colorStops: [
{ offset: 0, color: 'rgba(73,178,255,0)' },
{ offset: 0.5, color: 'rgba(0, 232, 255, .5)' },
{ offset: 1, color: 'rgba(0, 232, 255, 1)' }
]
}
},
tooltip: { show: false },
data: data
},
{
type: 'pictorialBar',
symbolSize: [20, 8],
symbolOffset: [0, -4],
z: 12,
symbolPosition: 'end',
itemStyle: {
borderColor: 'rgba(0, 232, 255, 1)',
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'RGBA(22, 89, 98, 1)' },
{ offset: 1, color: '#3588C7' }
])
},
tooltip: { show: false },
data: data
}
]
}
this.chart.setOption(option)
// 监听窗口 resize自适应图表
window.addEventListener('resize', this.chart.resize)
}
}
}
</script>
<style lang='scss' scoped>
/* 原有样式保留,新增内容容器样式 */
.bottom-left-content {
width: 100%;
height: 100%;
overflow: hidden;
}
/* 其他原有样式... */
.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>