运营驾驶舱修改部分

This commit is contained in:
2026-03-27 11:12:13 +08:00
parent b85ceb2542
commit 05fe91618c
13 changed files with 672 additions and 44 deletions

View File

@@ -10,9 +10,9 @@ VUE_APP_TITLE = 洛玻集团驾驶舱
# VUE_APP_BASE_API = 'http://172.16.33.83:7070'
# 杨姗姗
# VUE_APP_BASE_API = 'http://172.16.20.218:7070'
VUE_APP_BASE_API = 'http://172.16.20.218:7070'
# 小田
VUE_APP_BASE_API = 'http://172.16.19.232:7070'
# VUE_APP_BASE_API = 'http://172.16.19.232:7070'
# 测试
# VUE_APP_BASE_API = 'http://192.168.0.35:8080'

View File

@@ -1,5 +1,5 @@
<template>
<el-form ref="form" :rules="rules" label-width="110px" :model="form">
<el-form ref="form" :rules="rules" label-width="120px" :model="form">
<el-row>
<el-col :span="24">
<el-form-item label="重点工作" prop="name">
@@ -15,11 +15,12 @@
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="所属年份" prop="daySpan">
<el-form-item label="所属年份" prop="daySpan1">
<el-date-picker
v-model="value3"
type="year"
placeholder="选择年">
placeholder="选择年"
style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>

View File

@@ -37,7 +37,7 @@ export default {
isEdit: false, //是否是编辑
rules: {
name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
code: [{ required: true, message: '请输入产品编码', trigger: 'blur' }],
code: [{ required: true, message: '请输入产品规格', trigger: 'blur' }],
daySpan: [{ required: true, message: '请选择工艺', trigger: 'change' }],
}
}

View File

@@ -39,7 +39,7 @@ export default {
return {
// 图表样式配置项,可以抽离出来方便管理
chartConfig: {
manageCost: {
'管理费用': {
name: '管理费用',
lineColor: 'rgba(11, 88, 255, .5)',
itemColor: 'rgba(11, 88, 255, .5)',
@@ -49,7 +49,7 @@ export default {
{ offset: 1, color: 'rgba(18, 255, 245, 0)' },
]
},
saleCost: {
'销售费用': {
name: '销售费用',
lineColor: 'rgba(54, 181, 138, .5)',
itemColor: 'rgba(54, 181, 138, .5)',
@@ -59,7 +59,7 @@ export default {
{ offset: 1, color: 'rgba(18, 255, 245, 0)' },
]
},
financeCost: {
'财务费用': {
name: '财务费用',
lineColor: 'rgba(255, 132, 0, .5)',
itemColor: 'rgba(255, 132, 0, .5)',
@@ -78,7 +78,7 @@ export default {
// 从 cost.line 中获取任意一个有数据的键的 keys 作为 X 轴
const lineData = this.line || {};
const firstKey = Object.keys(lineData)[0];
return firstKey ? Object.keys(lineData[firstKey]) : [];
return firstKey ? Object.keys(lineData[firstKey].real) : [];
},
// 动态生成 series 数据
chartSeries() {
@@ -94,7 +94,7 @@ export default {
return Object.keys(this.chartConfig).map(key => {
const config = this.chartConfig[key];
// 确保数据顺序和 X 轴一致
const dataValues = xAxisKeys.map(date => lineData[key] ? lineData[key][date] : 0);
const dataValues = xAxisKeys.map(date => lineData[key] ? lineData[key].real[date] : 0);
return {
name: config.name,

View File

@@ -1,11 +1,11 @@
<template>
<div style="flex: 1">
<Container name="销售重点指标" icon="cockpitItemIcon" size="topBasic" topSize="basic">
<Container name="销售重点指标" icon="cockpitItemIcon" size="topBasic" topSize="basic" :isShowTab='true' @tabChange='tabChange'>
<!-- 1. 移除 .kpi-content 的固定高度改为自适应 -->
<div class="kpi-content" style="padding: 14px 16px; display: flex;flex-direction: column; width: 100%;">
<!-- 2. .top 保持 flex无需固定高度自动跟随子元素拉伸 -->
<div class="top" style="display: flex; width: 100%;">
<top-item :sale="sale" :dateData="dateData" />
<top-item :sale="saleData" :dateData="dateData" />
</div>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
@@ -39,16 +39,39 @@ export default {
},
data() {
return {
chart: null
chart: null,
saleData:{},
currentTap:'month'
}
},
watch: {
sale: {
handler(newVal) {
if(this.currentTap === 'month') {
this.saleData = this.sale.mon
}else{
this.saleData = this.sale.total
}
},
deep: true
}
},
mounted() {
// 初始化图表(若需展示图表,需在模板中添加对应 DOM
// this.$nextTick(() => this.updateChart())
this.saleData = this.sale.month
},
methods: {
tabChange(val) {
if(val === 'month') {
this.currentTap = 'month'
this.saleData = this.sale.mon
}else{
this.currentTap = 'total'
this.saleData = this.sale.total
}
console.log(this.saleData);
}
}
}
</script>

View File

@@ -78,7 +78,7 @@ export default {
label: { backgroundColor: '#6a7985' }
}
},
grid: { top: 35, bottom: 20, right: 25, left: 70 },
grid: { top: 35, bottom: 3, right: 15, left: 10, containLabel: true},
xAxis: [
{
type: 'category',

View File

@@ -8,7 +8,7 @@
<div class="content-wrapper">
<div class="left">
<div class="number">{{ item.targetValue }}</div>
<div class="title">上月</div>
<div class="title">{{currentTap==='month'?'上月':'上年'}}</div>
</div>
<div class="line"></div>
<div class="right">
@@ -16,7 +16,7 @@
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
{{ item.currentValue }}
</div>
<div class="title">本月</div>
<div class="title">{{currentTap==='month'?'本月':'本年'}}</div>
</div>
</div>
<div class="line"></div>
@@ -46,6 +46,10 @@ export default {
type: Object,
default: () => ({})
},
currentTap: {
type: String,
default: 'month'
}
},
data() {
return {

View File

@@ -1,12 +1,12 @@
<template>
<div style="flex: 1">
<!-- 传入点击切换的状态到Container组件 -->
<Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch">
<Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch" @tabChange='tabChange'>
<div class="bottom-left-content" style="display: flex;gap: 9px;padding: 14px 16px;flex-direction: column;">
<!-- 根据activeTab状态切换显示采购/存货内容 -->
<template v-if="activeTab === 'purchase'">
<!-- 采购重点指标对应的内容 -->
<coreBottomLeftItem :dateData="dateData" :finance="finance"></coreBottomLeftItem>
<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>
@@ -14,7 +14,7 @@
</template>
<template v-else-if="activeTab === 'inventory'">
<!-- 存货重点指标对应的内容 -->
<costItem :dateData="dateData" :cost="cost"></costItem>
<costItem :dateData="dateData" :cost="costData" :currentTap='currentTap'></costItem>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<CostsBottomBar :line="cost.line" :dateData="dateData">
@@ -52,13 +52,16 @@ export default {
dateData: {
type: Object,
default: () => ({})
},
}
},
data() {
return {
activeTab: 'purchase', // 激活的标签purchase=采购inventory=存货
showChart: true, // 控制图表是否显示
chart: null // 图表实例
chart: null, // 图表实例
financeData:{},
costData:{},
currentTap: 'month'
}
},
watch: {
@@ -71,8 +74,29 @@ export default {
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())
@@ -85,6 +109,17 @@ export default {
}
},
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'

View File

@@ -16,7 +16,17 @@
<span class="title-text">{{ nameTwo }}</span>
</div>
<span class="change-text" :class="{ 'change-text-right': isLeftTransparent }">点击切换</span>
<!-- <span class="change-text" :class="{ 'change-text-right': isLeftTransparent }">点击切换</span> -->
<div class="tab-group">
<!-- 月度Tab点击切换状态动态绑定样式 -->
<div class="tab-item" :class="{ active: activeTab === 'month' }" @click="handleTabClick('month')">
月度
</div>
<!-- 累计Tab点击切换状态动态绑定样式 -->
<div class="tab-item" :class="{ active: activeTab === 'total' }" @click="handleTabClick('total')">
累计
</div>
</div>
</div>
<div class="container-body">
@@ -40,10 +50,18 @@ export default {
return {
// 初始状态左侧不透明1右侧透明0.3
isLeftTransparent: true, // 左侧透明度状态true=1false=0.3
isRightTransparent: false // 右侧透明度状态true=1false=0.3
isRightTransparent: false, // 右侧透明度状态true=1false=0.3
activeTab: 'month', // 默认激活的Tab为月度
};
},
methods: {
handleTabClick(tabType) {
this.activeTab = tabType;
// 向父组件派发Tab切换事件传递当前选中的Tab类型
this.$emit('tabChange', tabType);
// 可选:同时传递更详细的信息(如标签名)
// this.$emit('tabChange', { type: tabType, name: tabType === 'month' ? '月度' : '累计' });
},
// 点击左侧标题:左侧保持不透明,右侧变透明,并派发采购标签事件
handleLeftClick() {
this.isLeftTransparent = true; // 左侧不透明
@@ -151,7 +169,7 @@ export default {
background: linear-gradient(90deg, #FFFFFF 0%, rgba(253, 255, 255, 0) 100%);
position: absolute;
top: 0;
right: 0;
left: 240px;
z-index: 10;
overflow: hidden;
cursor: pointer;
@@ -258,4 +276,41 @@ export default {
// text-align: left;
// font-style: normal;
}
.tab-group {
display: inline-flex;
position: absolute;
right: 5%;
top:20px;
z-index: 9999;
align-items: center;
border-radius: 24px;
overflow: hidden;
gap: 8px; // Tab之间的间距
}
// Tab基础样式统一
.tab-item {
padding: 0 24px;
width: 79px;
height: 24px;
line-height: 24px;
font-size: 12px;
cursor: pointer;
text-align: center;
border-radius: 12px;
transition: all 0.2s ease; // 样式切换动画
}
// 未激活的Tab样式原first-child样式
.tab-item:not(.active) {
background: #ECF4FE;
color: #0B58FF;
}
// 激活的Tab样式原last-child样式
.tab-item.active {
background: #3071FF;
color: #F9FCFF;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,134 @@
<template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 214px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
components: {},
data() {
return {
myChart: null // 存储图表实例,避免重复创建
};
},
props: {
lineData: {
type: Object,
default: () => ({}),
},
xData: {
type: Array,
default: () => []
}
},
mounted() {
this.$nextTick(() => {
this.updateChart();
});
},
// 新增:监听 chartData 变化
watch: {
// 深度监听数据变化,仅更新图表配置(不销毁实例)
lineData: {
handler() {
console.log(this.lineData,'lineData');
this.updateChart();
},
deep: true,
immediate: true // 初始化时立即执行
}
},
methods: {
updateChart() {
const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
console.error('图表容器未找到!');
return;
}
if (this.myChart) {
this.myChart.dispose();
}
this.myChart = echarts.init(chartDom);
console.log('linedaata',this.lineData)
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
},
grid: {
top: 30,
bottom: 30,
right: 20,
left: 60,
},
xAxis: [
{
type: 'category',
boundaryGap: true,
axisTick: { show: false },
axisLine: {
show: true,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
},
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
interval: 0,
padding: [5, 0, 0, 0]
},
data:this.xData
}
],
yAxis: [
// 左侧Y轴营业收入、成本单位万元
{
type: 'value',
name: 'kcal/kg',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'right'
},
splitNumber: 4,
axisTick: { show: false },
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
formatter: '{value}'
},
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4
},
],
series: []
};
option && this.myChart.setOption(option);
// 窗口缩放适配和销毁逻辑保持不变
window.addEventListener('resize', () => {
this.myChart && this.myChart.resize();
});
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => {
this.myChart && this.myChart.resize();
});
this.myChart && this.myChart.dispose();
});
}
},
};
</script>

View File

@@ -0,0 +1,316 @@
<template>
<div class="cockpitContainer" :class="['cockpitContainer__' + size]">
<div class="container-top">
<!-- 左侧标题点击切换到采购标签并更新透明度 -->
<div class="content-top-left title-wrapper" @click="handleLeftClick"
:style="{ opacity: isLeftTransparent ? 1 : 0.3 }">
<svg-icon class="title-icon" style="font-size: 32px; margin-left: 16px" :icon-class="icon" />
<span class="title-text">{{ name }}</span>
<!-- <span v-if="!isLeftTransparent" class="change-text">点击切换</span> -->
</div>
<!-- 右侧标题点击切换到存货标签并更新透明度 -->
<div class="content-top-right title-wrapper" v-if="nameTwo" @click="handleRightClick"
:style="{ opacity: isRightTransparent ? 1 : 0.3 }">
<svg-icon class="title-icon" style="font-size: 32px; margin-left: 16px" :icon-class="iconTwo || icon" />
<span class="title-text">{{ nameTwo }}</span>
</div>
<!-- <span class="change-text" :class="{ 'change-text-right': isLeftTransparent }">点击切换</span> -->
<div class="tab-group">
<!-- 月度Tab点击切换状态动态绑定样式 -->
<div class="tab-item" :class="{ active: activeTab === 'month' }" @click="handleTabClick('month')">
月度
</div>
<!-- 累计Tab点击切换状态动态绑定样式 -->
<div class="tab-item" :class="{ active: activeTab === 'total' }" @click="handleTabClick('total')">
累计
</div>
</div>
</div>
<div class="container-body">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'Container',
components: {},
props: {
name: { type: String, required: true },
nameTwo: { type: String, required: false },
size: { type: String, default: 'default' },
icon: { type: String, default: '' },
iconTwo: { type: String, default: '' }
},
data() {
return {
// 初始状态左侧不透明1右侧透明0.3
isLeftTransparent: true, // 左侧透明度状态true=1false=0.3
isRightTransparent: false, // 右侧透明度状态true=1false=0.3
activeTab: 'month', // 默认激活的Tab为月度
};
},
methods: {
handleTabClick(tabType) {
this.activeTab = tabType;
// 向父组件派发Tab切换事件传递当前选中的Tab类型
this.$emit('tabChange', tabType);
// 可选:同时传递更详细的信息(如标签名)
// this.$emit('tabChange', { type: tabType, name: tabType === 'month' ? '月度' : '累计' });
},
// 点击左侧标题:左侧保持不透明,右侧变透明,并派发采购标签事件
handleLeftClick() {
this.isLeftTransparent = true; // 左侧不透明
this.isRightTransparent = false; // 右侧透明
this.$emit('switchTab', 'product'); // 通知父组件切换到采购内容
},
// 点击右侧标题:右侧保持不透明,左侧变透明,并派发存货标签事件
handleRightClick() {
this.isLeftTransparent = false; // 左侧透明
this.isRightTransparent = true; // 右侧不透明
this.$emit('switchTab', 'heat'); // 通知父组件切换到存货内容
}
}
};
</script>
<style scoped lang="scss">
// 样式保持不变,确保透明度过渡生效
.cockpitContainer {
display: inline-block;
padding: 6px;
display: flex;
flex-direction: column;
position: relative;
.container-top {
position: relative;
height: 60px;
width: 100%;
}
.content-top-left {
width: 566px;
height: 60px;
background: linear-gradient(90deg, #FFFFFF 0%, rgba(253, 255, 255, 0) 100%);
position: relative;
overflow: hidden;
cursor: pointer;
z-index: 1;
transition: opacity 0.3s ease; // 透明度过渡动画
}
.title-wrapper {
display: flex;
align-items: center;
// margin-left: 10px;
/* 垂直居中关键属性 */
height: 100%;
/* 继承父容器高度,确保垂直居中范围 */
}
.title-icon {
font-size: 30px;
margin-right: 12px;
margin-top: 4px;
margin-left: 10px;
/* 图标和文字之间的间距 */
flex-shrink: 0;
/* 防止图标被压缩 */
}
.title-text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24px;
color: #000000;
letter-spacing: 3px;
text-align: left;
font-style: normal;
// 移除固定行高,避免影响垂直对齐
// line-height: 60px;
}
/* 左侧标题 - 左上角折现边框 */
.content-top-left::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid;
border-image: linear-gradient(277deg, rgba(255, 255, 255, 0), rgba(92, 140, 255, 1)) 1 1;
clip-path: polygon(20px 0, 100% 0, 100% 100%, 0 100%, 0 20px);
z-index: 3;
}
/* 左侧标题 - 左上角折现细节 */
.content-top-left::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
background: #E1f0fd;
border-top: 1px solid rgba(92, 140, 255, 1);
border-left: 1px solid rgba(92, 140, 255, 1);
transform: rotate(135deg) translate(-50%, -50%);
transform-origin: top left;
z-index: 3;
}
.content-top-right {
width: 368px;
height: 60px;
background: linear-gradient(90deg, #FFFFFF 0%, rgba(253, 255, 255, 0) 100%);
position: absolute;
top: 0;
left: 240px;
z-index: 10;
overflow: hidden;
cursor: pointer;
transition: opacity 0.3s ease; // 透明度过渡动画
}
/* 右侧标题 - 左上角折现边框 */
.content-top-right::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid;
border-image: linear-gradient(277deg, rgba(255, 255, 255, 0), rgba(92, 140, 255, 1)) 1 1;
clip-path: polygon(20px 0, 100% 0, 100% 100%, 0 100%, 0 20px);
z-index: 12;
}
/* 右侧标题 - 左上角折现细节 */
.content-top-right::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
background: #E1f0fd;
border-top: 1px solid rgba(92, 140, 255, 1);
border-left: 1px solid rgba(92, 140, 255, 1);
transform: rotate(135deg) translate(-50%, -50%);
transform-origin: top left;
z-index: 12;
}
.title-text {
margin-left: 6px;
height: 32px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24px;
color: #000000;
// line-height: 60px;
letter-spacing: 3px;
text-align: left;
font-style: normal;
display: inline-block;
position: relative;
z-index: 1;
}
&__topBasic {
background: url(../../../assets/img/top-basic.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
&__bottomBasic {
background: url(../../../assets/img/bottom-basic.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
}
.container-body {
flex: 1;
}
.test-body {
padding: 20px;
color: #666;
}
.change-text{
position: absolute;
top: 26px;
left: 300px;
z-index: 999;
// width: 48px;
// height: 17px;
// margin-left: 80px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #0B58FF;
line-height: 17px;
text-align: left;
font-style: normal;
}
.change-text-right {
// position: absolute;
// top: 26px;
left: auto; // 清除左侧定位
right: 30px;
// z-index: 999;
// // width: 48px;
// // height: 17px;
// // margin-left: 80px;
// font-family: PingFangSC, PingFang SC;
// font-weight: 400;
// font-size: 12px;
// color: #0B58FF;
// line-height: 17px;
// text-align: left;
// font-style: normal;
}
.tab-group {
display: inline-flex;
position: absolute;
right: 0px;
top:20px;
z-index: 9999;
align-items: center;
border-radius: 24px;
overflow: hidden;
gap: 8px; // Tab之间的间距
}
// Tab基础样式统一
.tab-item {
padding: 0 24px;
width: 79px;
height: 24px;
line-height: 24px;
font-size: 12px;
cursor: pointer;
text-align: center;
border-radius: 12px;
transition: all 0.2s ease; // 样式切换动画
}
// 未激活的Tab样式原first-child样式
.tab-item:not(.active) {
background: #ECF4FE;
color: #0B58FF;
}
// 激活的Tab样式原last-child样式
.tab-item.active {
background: #3071FF;
color: #F9FCFF;
font-weight: bold;
}
</style>

View File

@@ -1,33 +1,49 @@
<template>
<div style="flex: 1">
<Container name="生产重点指标" icon="cockpitItemIcon" size="topBasic" topSize="basic">
<Container name="生产重点指标" nameTwo="热耗" icon="cockpitItemIcon" size="topBasic" topSize="basic" @switchTab="handleTabSwitch" @tabChange='tabChange'>
<!-- 1. 移除 .kpi-content 的固定高度改为自适应 -->
<div class="kpi-content" style="padding: 14px 16px; display: flex;flex-direction: column; width: 100%;">
<!-- 2. .top 保持 flex无需固定高度自动跟随子元素拉伸 -->
<template v-if="activeTab === 'product'">
<div class="top" style="display: flex; width: 100%;">
<top-item :rawItemList='productData' :dateData="dateData" />
</div>
<div class="bottom" style="display: flex;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<!-- <top-item /> -->
<coreBottomBar :lineData="productData.line" :dateData="dateData" />
<coreBottomBar :lineData="product.line" :dateData="dateData" />
</div>
</template>
<template v-else-if="activeTab === 'heat'">
<div class="bottom" style="background-color: rgba(249, 252, 255, 1);">
<div class="bottom" style="margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<div style='text-align: center;margin: 5px;font-size: 18px;font-weight: 400;color: #000;'>1200t/d</div>
<heatBar :lineData="heatData['1200t']" :xData="['桐城','洛阳','江苏','秦皇岛']" :dateData="dateData" />
</div>
<div style='text-align: center;margin: 5px;font-size: 18px;font-weight: 400;color: #000;'>650t/d</div>
<heatBar :lineData="heatData['650t']" :xData="['宜兴','自贡','漳州']" :dateData="dateData" />
</div>
</template>
</div>
</Container>
</div>
</template>
<script>
import Container from './container.vue'
import Container from './keyProductContainer.vue'
// import * as echarts from 'echarts'
import topItem from './top-product-item.vue'
import coreBottomBar from './productBottomBar.vue'
import heatBar from './heatBarChart.vue'
export default {
name: 'ProductionStatus',
components: { Container, topItem, coreBottomBar },
components: { Container, topItem, coreBottomBar, heatBar },
// mixins: [resize],
props: {
productData: {
product: {
type: Object,
default: () => {} // 默认空数组,避免报错
},
heat: {
type: Object,
default: () => {} // 默认空数组,避免报错
},
@@ -35,13 +51,45 @@ export default {
type: Object,
default: () => { } // 默认空数组,避免报错
},
heat: {
type: Object,
default: () => { }
}
},
data() {
return {
chart: null
chart: null,
activeTab: 'product',
currentTap: 'month',
productData:{},
heatData:{}
}
},
watch: {
// 切换标签时更新图表
activeTab(newVal) {
// this.$nextTick(() => this.updateChart())
},
product: {
handler() {
if(this.currentTap === 'month') {
this.productData = this.product.mon
}else{
this.productData = this.product.total
}
},
deep: true
},
heat: {
handler() {
if(this.currentTap === 'month') {
this.heatData = this.heat.mon
}else{
this.heatData = this.heat.total
}
},
deep: true
},
},
mounted() {
// 初始化图表(若需展示图表,需在模板中添加对应 DOM
@@ -49,6 +97,22 @@ export default {
},
methods: {
// 处理标题点击切换标签
handleTabSwitch(tabType) {
this.activeTab = tabType // tabType由Container组件传递'purchase'或'inventory'
this.showChart = true // 切换时默认显示图表(可根据需求调整)
},
tabChange(val) {
if(val === 'month') {
this.currentTap = 'month'
this.productData = this.product.mon
this.heatData = this.heat.mon
}else{
this.currentTap = 'total'
this.productData = this.product.total
this.heatData = this.heat.total
}
},
}
}
</script>

View File

@@ -14,7 +14,7 @@
">
<coreSalesKPIs :sale="sale" :dateData="dateData" />
<financeCosts :finance="finance" :dateData="dateData" :cost="cost" />
<keyProductionIndicators :productData="productData" :dateData="dateData" />
<keyProductionIndicators :product="productData" :heat="heat" :dateData="dateData" />
</div>
</div>
<div class="top" style="display: flex;gap: 16px;margin-top: 6px;">
@@ -152,6 +152,7 @@ export default {
}).then((res) => {
console.log(res)
this.productData = res.data.product
this.heat = res.data.heat
this.purchase = res.data.purchase
this.inventory = res.data.inventory
this.importantWork = res.data.importantWork
@@ -160,11 +161,6 @@ export default {
this.sale = res.data.sale
this.orderOutput = res.data.orderOutput
this.baseOrder = res.data.baseOrder
// this.saleData = res.data.SaleData
// this.premiumProduct = res.data.premiumProduct
// this.salesTrendMap = res.data.salesTrendMap
// this.grossMarginTrendMap = res.data.grossMarginTrendMap
// this.salesProportion = res.data.salesProportion ? res.data.salesProportion : {}
})
},
handleTimeChange(obj) {