制造成本分析接口+单位修改
This commit is contained in:
@@ -130,6 +130,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
margin: 7px 0;
|
||||||
|
|
||||||
.barTop {
|
.barTop {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 214px;"></div>
|
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 216px;"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export default {
|
|||||||
getUnitPriceAnalysisGroupData({
|
getUnitPriceAnalysisGroupData({
|
||||||
startTime: this.dateData.startTime,
|
startTime: this.dateData.startTime,
|
||||||
endTime: this.dateData.endTime,
|
endTime: this.dateData.endTime,
|
||||||
paramName: '增效额'
|
paramName: '总增效额'
|
||||||
// timeDim: this.dateData.mode
|
// timeDim: this.dateData.mode
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ export default {
|
|||||||
endTime: this.dateData.endTime,
|
endTime: this.dateData.endTime,
|
||||||
// index: this.index,
|
// index: this.index,
|
||||||
// sort: 1,
|
// sort: 1,
|
||||||
paramName: '增效额',
|
paramName: '总增效额',
|
||||||
paramList: ['大宗增效额', '石料增效额', '材料增效额', '动力增效额', '技术服务增效额'],
|
paramList: ['大宗增效额', '石料增效额', '材料增效额', '动力增效额', '技术服务增效额'],
|
||||||
baseId: this.factory,
|
baseId: this.factory,
|
||||||
// baseId: Number(this.factory),
|
// baseId: Number(this.factory),
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
activeButton: 0,
|
activeButton: 0,
|
||||||
isDropdownShow: false,
|
isDropdownShow: false,
|
||||||
selectedProfit: '增效额', // 关键修改:默认赋值为「净价」,初始化即展示该类目数据
|
selectedProfit: '总增效额', // 关键修改:默认赋值为「净价」,初始化即展示该类目数据
|
||||||
profitOptions: ['增效额', '动力增效额', '大宗增效额', '技术服务增效额', '材料增效额', '石料增效额']
|
profitOptions: ['总增效额', '动力增效额', '大宗增效额', '技术服务增效额', '材料增效额', '石料增效额']
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ import changeBase from "../components/changeBase.vue";
|
|||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysis.vue";
|
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysis.vue";
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuel.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuelYL.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
@@ -94,11 +94,16 @@ export default {
|
|||||||
trendName: '采购单价',
|
trendName: '采购单价',
|
||||||
meterialName:'',
|
meterialName:'',
|
||||||
materialOptions: [
|
materialOptions: [
|
||||||
{value:'硅砂',label:'硅砂'},
|
{value:'氢氧化铝',label:'氢氧化铝'},
|
||||||
{value:'海砂',label:'海砂'},
|
{value:'碎玻璃',label:'碎玻璃'},
|
||||||
{value:'纯碱',label:'纯碱'},
|
{value:'助熔剂',label:'助熔剂'},
|
||||||
{value:'白云石',label:'白云石'},
|
{value:'白云石',label:'白云石'},
|
||||||
{value:'石灰石',label:'石灰石'}
|
{value:'石灰石',label:'石灰石'},
|
||||||
|
{value:'硅砂',label:'硅砂'},
|
||||||
|
{value:'纯碱',label:'纯碱'},
|
||||||
|
{value:'焦锑酸钠',label:'焦锑酸钠'},
|
||||||
|
{value:'芒硝',label:'芒硝'},
|
||||||
|
{value:'硝酸钠',label:'硝酸钠'}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -169,7 +174,7 @@ export default {
|
|||||||
this.beilv = _this.clientWidth / 1920;
|
this.beilv = _this.clientWidth / 1920;
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
this.meterialName = this.$route.query.name ? this.$route.query.name : '硅砂'
|
this.meterialName = this.$route.query.name ? this.$route.query.name : '氢氧化铝'
|
||||||
if(this.$route.query.factory){
|
if(this.$route.query.factory){
|
||||||
this.factory =Number(this.$route.query.factory)
|
this.factory =Number(this.$route.query.factory)
|
||||||
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
|
}else if(this.$store.getters.levelList.length > 0 && this.$store.getters.levelList[0].id !== 1) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import changeBase from "../components/changeBase.vue";
|
|||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
|
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcessingLabor.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcessingLabor2.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getSingleMaterialCostAnalysis } from '@/api/cockpit'
|
import { getSingleMaterialCostAnalysis } from '@/api/cockpit'
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
|
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
|
||||||
<relateSingleFuelCostAnalysis :dateData="dateData" :relatedData="relatedData" :title="'相关指标分析'" />
|
<relateSingleFuelCostAnalysis fuelName='电' :dateData="dateData" :relatedData="relatedData" :title="'相关指标分析'" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,18 +47,10 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<dataTrend @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
<dataTrend fuelName='电' @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="centerImg" style="
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1; /* 确保在 backp 之上、内容之下 */
|
|
||||||
"></div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -68,21 +60,11 @@ import screenfull from "screenfull";
|
|||||||
import changeBase from "../components/changeBase.vue";
|
import changeBase from "../components/changeBase.vue";
|
||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
|
||||||
// import monthlyRelatedMetrics from "../procurementGainAnalysisComponents/monthlyRelatedMetrics.vue";
|
|
||||||
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisDian.vue";
|
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisDian.vue";
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuel.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuelDian.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getCostAnalysisData } from '@/api/cockpit'
|
import { getCostAnalysisData } from '@/api/cockpit'
|
||||||
// import PSDO from "./components/PSDO.vue";
|
|
||||||
// import psiLineChart from "./components/psiLineChart.vue";
|
|
||||||
|
|
||||||
// import coreBottomLeft from "./components/coreBottomLeft.vue";
|
|
||||||
// import orderProgress from "./components/orderProgress.vue";
|
|
||||||
// import keyWork from "./components/keyWork.vue";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
// import html2canvas from 'html2canvas'
|
|
||||||
// import JsPDF from 'jspdf'
|
|
||||||
export default {
|
export default {
|
||||||
name: "DayReport",
|
name: "DayReport",
|
||||||
components: {
|
components: {
|
||||||
@@ -93,7 +75,6 @@ export default {
|
|||||||
totalOverview,
|
totalOverview,
|
||||||
relateSingleFuelCostAnalysis,
|
relateSingleFuelCostAnalysis,
|
||||||
dataTrend
|
dataTrend
|
||||||
// psiLineChart
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -34,13 +34,9 @@
|
|||||||
<div class="left-three" style="
|
<div class="left-three" style="
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
grid-template-columns: 804px 804px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<monthlyRelatedMetrics :dateData="dateData" :factory="factory" :relatedData="monthRelatedData"
|
<relateFuCostAnalysis :relatedData="relatedData" :title="'相关指标分析'" />
|
||||||
:title="'月度概览'" />
|
|
||||||
<yearRelatedMetrics :dateData="dateData" :factory="factory" :relatedData="totalRelatedData" :title="'累计概览'" />
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom" style="display: flex; gap: 16px;margin-top: 6px;">
|
<div class="bottom" style="display: flex; gap: 16px;margin-top: 6px;">
|
||||||
@@ -53,14 +49,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="centerImg" style="
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1; /* 确保在 backp 之上、内容之下 */
|
|
||||||
"></div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -70,21 +58,11 @@ import screenfull from "screenfull";
|
|||||||
import changeBase from "../components/changeBase.vue";
|
import changeBase from "../components/changeBase.vue";
|
||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
import relateFuCostAnalysis from "../productionCostAnalysisComponents/relateFuCostAnalysis.vue";
|
||||||
import monthlyRelatedMetrics from "../productionCostAnalysisComponents/monthlyThreeRelatedMetrics.vue";
|
|
||||||
import yearRelatedMetrics from "../productionCostAnalysisComponents/yearThreeRelatedMetrics.vue";
|
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcAuxMat.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcAuxMat.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getCostAnalysisData } from '@/api/cockpit'
|
import { getCostAnalysisData } from '@/api/cockpit'
|
||||||
// import PSDO from "./components/PSDO.vue";
|
|
||||||
// import psiLineChart from "./components/psiLineChart.vue";
|
|
||||||
|
|
||||||
// import coreBottomLeft from "./components/coreBottomLeft.vue";
|
|
||||||
// import orderProgress from "./components/orderProgress.vue";
|
|
||||||
// import keyWork from "./components/keyWork.vue";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
// import html2canvas from 'html2canvas'
|
|
||||||
// import JsPDF from 'jspdf'
|
|
||||||
export default {
|
export default {
|
||||||
name: "DayReport",
|
name: "DayReport",
|
||||||
components: {
|
components: {
|
||||||
@@ -93,8 +71,7 @@ export default {
|
|||||||
monthlyOverview,
|
monthlyOverview,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
totalOverview,
|
totalOverview,
|
||||||
monthlyRelatedMetrics,
|
relateFuCostAnalysis,
|
||||||
yearRelatedMetrics,
|
|
||||||
dataTrend
|
dataTrend
|
||||||
// psiLineChart
|
// psiLineChart
|
||||||
},
|
},
|
||||||
@@ -107,11 +84,10 @@ export default {
|
|||||||
factory: null,
|
factory: null,
|
||||||
value: 100,
|
value: 100,
|
||||||
dateData: {},
|
dateData: {},
|
||||||
trendName: '加工燃料成本',
|
trendName: '加工辅料',
|
||||||
monData: {},
|
monData: {},
|
||||||
totalData: {},
|
totalData: {},
|
||||||
monthRelatedData: [],
|
relatedData:{},
|
||||||
totalRelatedData: [],
|
|
||||||
trend: [],
|
trend: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -224,20 +200,17 @@ export default {
|
|||||||
return item.name === "加工辅料成本";
|
return item.name === "加工辅料成本";
|
||||||
});
|
});
|
||||||
console.log('this.monData', this.monData);
|
console.log('this.monData', this.monData);
|
||||||
|
|
||||||
this.totalData = res.data.totalMonthData.find(item => {
|
this.totalData = res.data.totalMonthData.find(item => {
|
||||||
return item.name === "加工辅料成本";
|
return item.name === "加工辅料成本";
|
||||||
});
|
});
|
||||||
// this.relatedMon = res.data.relatedMon
|
this.relatedData = {
|
||||||
this.monthRelatedData = res.data.currentMonthData.filter(item => {
|
relatedMon: res.data.currentMonthData.filter(item => {
|
||||||
|
return item.name !== "加工辅料成本";
|
||||||
|
}),
|
||||||
|
relatedTotal: res.data.totalMonthData.filter(item => {
|
||||||
return item.name !== "加工辅料成本";
|
return item.name !== "加工辅料成本";
|
||||||
})
|
})
|
||||||
this.totalRelatedData = res.data.totalMonthData.filter(item => {
|
}
|
||||||
return item.name !== "加工辅料成本";
|
|
||||||
}) // 兜底累
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
this.trend = res.data.dataTrend
|
this.trend = res.data.dataTrend
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview
|
|||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
||||||
// import monthlyRelatedMetrics from "../procurementGainAnalysisComponents/monthlyRelatedMetrics.vue";
|
// import monthlyRelatedMetrics from "../procurementGainAnalysisComponents/monthlyRelatedMetrics.vue";
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcessingLabor.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendProcessingLabor2.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getSingleMaterialCostAnalysis } from '@/api/cockpit'
|
import { getSingleMaterialCostAnalysis } from '@/api/cockpit'
|
||||||
// import PSDO from "./components/PSDO.vue";
|
// import PSDO from "./components/PSDO.vue";
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<dataTrend @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
<dataTrend :fuelName='fuelName' @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
|
|
||||||
<relateSingleFuelCostAnalysis :relatedData="relatedData" :title="'相关指标分析'" />
|
<relateSingleFuelCostAnalysis :relatedData="relatedData" :title="'相关指标分析'" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -53,14 +52,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="centerImg" style="
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1; /* 确保在 backp 之上、内容之下 */
|
|
||||||
"></div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -70,21 +61,11 @@ import screenfull from "screenfull";
|
|||||||
import changeBase from "../components/changeBase.vue";
|
import changeBase from "../components/changeBase.vue";
|
||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
|
||||||
// import monthlyRelatedMetrics from "../procurementGainAnalysisComponents/monthlyRelatedMetrics.vue";
|
|
||||||
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisFu.vue";
|
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisFu.vue";
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuel.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuelF.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
||||||
// import PSDO from "./components/PSDO.vue";
|
|
||||||
// import psiLineChart from "./components/psiLineChart.vue";
|
|
||||||
|
|
||||||
// import coreBottomLeft from "./components/coreBottomLeft.vue";
|
|
||||||
// import orderProgress from "./components/orderProgress.vue";
|
|
||||||
// import keyWork from "./components/keyWork.vue";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
// import html2canvas from 'html2canvas'
|
|
||||||
// import JsPDF from 'jspdf'
|
|
||||||
export default {
|
export default {
|
||||||
name: "DayReport",
|
name: "DayReport",
|
||||||
components: {
|
components: {
|
||||||
@@ -95,7 +76,6 @@ export default {
|
|||||||
totalOverview,
|
totalOverview,
|
||||||
relateSingleFuelCostAnalysis,
|
relateSingleFuelCostAnalysis,
|
||||||
dataTrend
|
dataTrend
|
||||||
// psiLineChart
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -115,7 +95,9 @@ export default {
|
|||||||
auxMatOptions: [
|
auxMatOptions: [
|
||||||
{value:'镀膜液',label:'镀膜液'},
|
{value:'镀膜液',label:'镀膜液'},
|
||||||
{value:'油墨',label:'油墨'},
|
{value:'油墨',label:'油墨'},
|
||||||
{value:'釉料',label:'釉料'}
|
{value:'釉料',label:'釉料'},
|
||||||
|
{value:'无水乙醇',label:'无水乙醇'},
|
||||||
|
{value:'异丙醇',label:'异丙醇'}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
|
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
|
||||||
<relateSingleFuelCostAnalysis :relatedData="relatedData" :title="'相关指标分析'" />
|
<relateSingleFuelCostAnalysis :fuelName='fuelName' :relatedData="relatedData" :title="'相关指标分析'" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,18 +49,10 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
grid-template-columns: 1624px;
|
grid-template-columns: 1624px;
|
||||||
">
|
">
|
||||||
<dataTrend @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
<dataTrend :fuelName='fuelName' @getData="changeItem" :trendData="trend" :title="'数据趋势'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="centerImg" style="
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1; /* 确保在 backp 之上、内容之下 */
|
|
||||||
"></div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -70,21 +62,11 @@ import screenfull from "screenfull";
|
|||||||
import changeBase from "../components/changeBase.vue";
|
import changeBase from "../components/changeBase.vue";
|
||||||
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
import monthlyOverview from "../productionCostAnalysisComponents/monthlyOverview.vue";
|
||||||
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
import totalOverview from "../productionCostAnalysisComponents/totalOverview.vue";
|
||||||
// import totalOverview from "../operatingComponents/totalOverview.vue";
|
|
||||||
// import monthlyRelatedMetrics from "../procurementGainAnalysisComponents/monthlyRelatedMetrics.vue";
|
|
||||||
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisDian.vue";
|
import relateSingleFuelCostAnalysis from "../productionCostAnalysisComponents/relateSingleFuelCostAnalysisDian.vue";
|
||||||
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuel.vue";
|
import dataTrend from "../productionCostAnalysisComponents/dataTrendSingleFuelDian.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
import { getSingleMaterialAnalysis } from '@/api/cockpit'
|
||||||
// import PSDO from "./components/PSDO.vue";
|
|
||||||
// import psiLineChart from "./components/psiLineChart.vue";
|
|
||||||
|
|
||||||
// import coreBottomLeft from "./components/coreBottomLeft.vue";
|
|
||||||
// import orderProgress from "./components/orderProgress.vue";
|
|
||||||
// import keyWork from "./components/keyWork.vue";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
// import html2canvas from 'html2canvas'
|
|
||||||
// import JsPDF from 'jspdf'
|
|
||||||
export default {
|
export default {
|
||||||
name: "DayReport",
|
name: "DayReport",
|
||||||
components: {
|
components: {
|
||||||
@@ -95,7 +77,6 @@ export default {
|
|||||||
totalOverview,
|
totalOverview,
|
||||||
relateSingleFuelCostAnalysis,
|
relateSingleFuelCostAnalysis,
|
||||||
dataTrend
|
dataTrend
|
||||||
// psiLineChart
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<div class="dropdown-options" v-if="isDropdownShow">
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
@click.stop="selectProfit(item)">
|
@click.stop="selectProfit(item)">
|
||||||
{{ item }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,19 +60,18 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isDropdownShow: false,
|
isDropdownShow: false,
|
||||||
selectedProfit: '天然气', // 选中的名称,初始为null
|
selectedProfit: '原片燃料成本', // 选中的名称,初始为null
|
||||||
profitOptions: [
|
profitOptions: [
|
||||||
'天然气',
|
{name:'原片燃料成本',unit:'元/㎡'},
|
||||||
'LNG液化天然气',
|
{name:'天然气',unit:'元/㎡'},
|
||||||
'重油',
|
{name:'LNG液化天然气',unit:'元/㎡'},
|
||||||
'水',
|
{name:'重油',unit:'元/㎡'},
|
||||||
]
|
{name:'水',unit:'元/m³'}
|
||||||
|
],
|
||||||
|
unit:'元/㎡'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// profitOptions() {
|
|
||||||
// return this.categoryData.map(item => item.name) || [];
|
|
||||||
// },
|
|
||||||
currentDataSource() {
|
currentDataSource() {
|
||||||
return this.chartData
|
return this.chartData
|
||||||
},
|
},
|
||||||
@@ -88,6 +87,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:this.unit,
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
@@ -246,9 +246,10 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectProfit(item) {
|
selectProfit(item) {
|
||||||
this.selectedProfit = item;
|
this.selectedProfit = item.name;
|
||||||
|
this.unit = item.unit;
|
||||||
this.isDropdownShow = false;
|
this.isDropdownShow = false;
|
||||||
this.$emit('handleGetItemData', item)
|
this.$emit('handleGetItemData', item.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<div class="dropdown-options" v-if="isDropdownShow">
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
@click.stop="selectProfit(item)">
|
@click.stop="selectProfit(item)">
|
||||||
{{ item }}
|
{{ item.nname }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,18 +62,15 @@ export default {
|
|||||||
isDropdownShow: false,
|
isDropdownShow: false,
|
||||||
selectedProfit: '原片制造费用成本', // 选中的名称,初始为null
|
selectedProfit: '原片制造费用成本', // 选中的名称,初始为null
|
||||||
profitOptions: [
|
profitOptions: [
|
||||||
'原片制造费用成本',
|
{name:'原片制造费用成本',nname:'原片制造费用'},
|
||||||
'包材',
|
{name:'包材',nname:'包材'},
|
||||||
'备件、机物料',
|
{name:'备件、机物料',nname:'备件、机物料'},
|
||||||
'折旧',
|
{name:'折旧',nname:'折旧'},
|
||||||
'其他',
|
{name:'其他',nname:'其他'},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// profitOptions() {
|
|
||||||
// return this.categoryData.map(item => item.name) || [];
|
|
||||||
// },
|
|
||||||
currentDataSource() {
|
currentDataSource() {
|
||||||
return this.chartData
|
return this.chartData
|
||||||
},
|
},
|
||||||
@@ -89,6 +86,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
@@ -247,9 +245,9 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectProfit(item) {
|
selectProfit(item) {
|
||||||
this.selectedProfit = item;
|
this.selectedProfit = item.nname;
|
||||||
this.isDropdownShow = false;
|
this.isDropdownShow = false;
|
||||||
this.$emit('handleGetItemData', item)
|
this.$emit('handleGetItemData', item.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,21 +63,18 @@ export default {
|
|||||||
selectedProfit: '原片原料', // 选中的名称,初始为null
|
selectedProfit: '原片原料', // 选中的名称,初始为null
|
||||||
profitOptions: [
|
profitOptions: [
|
||||||
'原片原料',
|
'原片原料',
|
||||||
'硅砂',
|
'氢氧化铝',
|
||||||
'纯碱',
|
'碎玻璃',
|
||||||
|
'复合澄清剂',
|
||||||
|
'助熔剂',
|
||||||
'白云石',
|
'白云石',
|
||||||
'石灰石',
|
'石灰石',
|
||||||
'复合澄清剂',
|
'硅砂',
|
||||||
'氢氧化铝',
|
'纯碱'
|
||||||
'助溶剂',
|
|
||||||
'碎玻璃'
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// profitOptions() {
|
|
||||||
// return this.categoryData.map(item => item.name) || [];
|
|
||||||
// },
|
|
||||||
currentDataSource() {
|
currentDataSource() {
|
||||||
return this.chartData
|
return this.chartData
|
||||||
},
|
},
|
||||||
@@ -93,6 +90,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ export default {
|
|||||||
'镀膜液',
|
'镀膜液',
|
||||||
'油墨',
|
'油墨',
|
||||||
'釉料',
|
'釉料',
|
||||||
|
'无水乙醇',
|
||||||
|
'异丙醇'
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -88,6 +90,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:'元/㎡',
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<div class="dropdown-options" v-if="isDropdownShow">
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
@click.stop="selectProfit(item)">
|
@click.stop="selectProfit(item)">
|
||||||
{{ item }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,24 +56,45 @@ import * as echarts from 'echarts';
|
|||||||
export default {
|
export default {
|
||||||
name: "Container",
|
name: "Container",
|
||||||
components: { operatingLineBar },
|
components: { operatingLineBar },
|
||||||
props: ["chartData"],
|
props: ["chartData","fuelName"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isDropdownShow: false,
|
isDropdownShow: false,
|
||||||
selectedProfit: '采购单价', // 选中的名称,初始为null
|
selectedProfit: '采购单价',
|
||||||
profitOptions: [
|
unit:'元/m³'
|
||||||
'采购单价',
|
|
||||||
'产量',
|
|
||||||
'单耗',
|
|
||||||
'消耗量',
|
|
||||||
'热耗',
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
fuelName: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.profitOptions.forEach(item => {
|
||||||
|
if (item.name === this.selectedProfit) {
|
||||||
|
this.unit = item.unit
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// profitOptions() {
|
profitOptions() {
|
||||||
// return this.categoryData.map(item => item.name) || [];
|
if (this.fuelName === '重油') {
|
||||||
// },
|
return [
|
||||||
|
{ name: '采购单价', unit: '元/吨'},
|
||||||
|
{ name: '产量', unit: '㎡'},
|
||||||
|
{ name: '单耗', unit: '千克/㎡'},
|
||||||
|
{ name: '消耗量', unit: '吨'},
|
||||||
|
{ name: '热耗', unit: '千卡/千克'}
|
||||||
|
]
|
||||||
|
}else{
|
||||||
|
return [
|
||||||
|
{ name: '采购单价', unit: '元/m³'},
|
||||||
|
{ name: '产量', unit: '㎡'},
|
||||||
|
{ name: '单耗', unit: 'm³/㎡'},
|
||||||
|
{ name: '消耗量', unit: 'm³'},
|
||||||
|
{ name: '热耗', unit: '千卡/千克'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
currentDataSource() {
|
currentDataSource() {
|
||||||
return this.chartData
|
return this.chartData
|
||||||
},
|
},
|
||||||
@@ -89,6 +110,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit: this.unit,
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
@@ -247,9 +269,10 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectProfit(item) {
|
selectProfit(item) {
|
||||||
this.selectedProfit = item;
|
this.selectedProfit = item.name;
|
||||||
|
this.unit = item.unit;
|
||||||
this.isDropdownShow = false;
|
this.isDropdownShow = false;
|
||||||
this.$emit('handleGetItemData', item)
|
this.$emit('handleGetItemData', item.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<div class="dropdown-options" v-if="isDropdownShow">
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
@click.stop="selectProfit(item)">
|
@click.stop="selectProfit(item)">
|
||||||
{{ item }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,19 +61,17 @@ export default {
|
|||||||
return {
|
return {
|
||||||
isDropdownShow: false,
|
isDropdownShow: false,
|
||||||
selectedProfit: '采购单价', // 选中的名称,初始为null
|
selectedProfit: '采购单价', // 选中的名称,初始为null
|
||||||
|
unit:'元/吨',
|
||||||
profitOptions: [
|
profitOptions: [
|
||||||
'采购单价',
|
{name:'采购单价',unit:'元/吨'},
|
||||||
'产量',
|
{name:'产量',unit:'㎡'},
|
||||||
'单耗',
|
{name:'单耗',unit:'千克/㎡'},
|
||||||
'消耗量',
|
{name:'消耗量',unit:'吨'},
|
||||||
'日均消耗量'
|
{name:'日均消耗量',unit:'吨'}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// profitOptions() {
|
|
||||||
// return this.categoryData.map(item => item.name) || [];
|
|
||||||
// },
|
|
||||||
currentDataSource() {
|
currentDataSource() {
|
||||||
return this.chartData
|
return this.chartData
|
||||||
},
|
},
|
||||||
@@ -89,6 +87,7 @@ export default {
|
|||||||
|
|
||||||
const salesData = {
|
const salesData = {
|
||||||
allPlaceNames: this.locations,
|
allPlaceNames: this.locations,
|
||||||
|
unit:this.unit,
|
||||||
series: [
|
series: [
|
||||||
// 1. 完成率(折线图)
|
// 1. 完成率(折线图)
|
||||||
{
|
{
|
||||||
@@ -247,10 +246,10 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectProfit(item) {
|
selectProfit(item) {
|
||||||
console.log('aaaaaa',item)
|
this.selectedProfit = item.name;
|
||||||
this.selectedProfit = item;
|
this.unit = item.unit;
|
||||||
this.isDropdownShow = false;
|
this.isDropdownShow = false;
|
||||||
this.$emit('handleGetItemData', item)
|
this.$emit('handleGetItemData', item.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,497 @@
|
|||||||
|
<template>
|
||||||
|
<div class="coreBar">
|
||||||
|
<!-- 新增行容器:包裹“各基地情况”和barTop -->
|
||||||
|
<div class="header-row">
|
||||||
|
<div class="barTop">
|
||||||
|
<!-- 关键:新增右侧容器,包裹图例和按钮组,实现整体靠右 -->
|
||||||
|
<div class="right-container">
|
||||||
|
<div class="legend">
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon line yield"></span>
|
||||||
|
完成率
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square target"></span>
|
||||||
|
目标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square achieved"></span>
|
||||||
|
实际·达标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square unachieved"></span>
|
||||||
|
实际·未达标
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="button-group">
|
||||||
|
<div class="item-button category-btn">
|
||||||
|
<span class="item-text">类目选择</span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-container">
|
||||||
|
<div class="item-button profit-btn active" @click.stop="isDropdownShow = !isDropdownShow">
|
||||||
|
<span class="item-text profit-text">{{ selectedProfit || '请选择' }}</span>
|
||||||
|
<span class="dropdown-arrow" :class="{ 'rotate': isDropdownShow }"></span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
|
@click.stop="selectProfit(item)">
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lineBottom" style="height: 100%; width: 100%">
|
||||||
|
<operatingLineBar :chartData="chartD" style="height: 99%; width: 100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import operatingLineBar from './operatingLineBarSale.vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Container",
|
||||||
|
components: { operatingLineBar },
|
||||||
|
props: ["chartData","fuelName"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isDropdownShow: false,
|
||||||
|
selectedProfit: '采购单价', // 选中的名称,初始为null
|
||||||
|
unit:'元/度'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
fuelName: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.profitOptions.forEach(item => {
|
||||||
|
if (item.name === this.selectedProfit) {
|
||||||
|
this.unit = item.unit
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
profitOptions() {
|
||||||
|
if (this.fuelName==='电') {
|
||||||
|
return [
|
||||||
|
{name:'采购单价',unit:'元/度'},
|
||||||
|
{name:'产量',unit:'㎡'},
|
||||||
|
{name:'单耗',unit:'度/㎡'},
|
||||||
|
{name:'消耗量',unit:'度'}
|
||||||
|
]
|
||||||
|
}else{
|
||||||
|
return [
|
||||||
|
{name:'采购单价',unit:'元/m³'},
|
||||||
|
{name:'产量',unit:'㎡'},
|
||||||
|
{name:'单耗',unit:'m³/㎡'},
|
||||||
|
{name:'消耗量',unit:'m³'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
currentDataSource() {
|
||||||
|
return this.chartData
|
||||||
|
},
|
||||||
|
locations() {
|
||||||
|
return this.chartData.time
|
||||||
|
},
|
||||||
|
// 根据按钮切换生成对应的 chartData
|
||||||
|
chartD() {
|
||||||
|
// 销量场景数据
|
||||||
|
const data = this.currentDataSource;
|
||||||
|
console.log(this.currentDataSource, 'currentDataSource');
|
||||||
|
console.log('this.currentDataSource', data);
|
||||||
|
|
||||||
|
const salesData = {
|
||||||
|
allPlaceNames: this.locations,
|
||||||
|
unit:this.unit,
|
||||||
|
series: [
|
||||||
|
// 1. 完成率(折线图)
|
||||||
|
{
|
||||||
|
name: '完成率',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1, // 绑定右侧Y轴(需在子组件启用配置)
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, .5)',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderColor: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
radius: 4
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.2,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(40, 138, 255, .9)' },
|
||||||
|
{ offset: 1, color: 'rgba(40, 138, 255, 0)' }
|
||||||
|
])
|
||||||
|
},
|
||||||
|
data: data.proportion || [], // 完成率(%)
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 6
|
||||||
|
},
|
||||||
|
// 2. 目标(柱状图)
|
||||||
|
{
|
||||||
|
name: '预算',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0, // 左侧Y轴(万元)
|
||||||
|
barWidth: 14,
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(75, 157, 255, 1)' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.targetValue || [] // 目标销量(万元)
|
||||||
|
},
|
||||||
|
// 3. 实际(柱状图,含达标状态)
|
||||||
|
{
|
||||||
|
name: '实际',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
offset: [0, 0],
|
||||||
|
// 固定label尺寸:68px×20px
|
||||||
|
width: 68,
|
||||||
|
height: 20,
|
||||||
|
// 关键:去掉换行,让文字在一行显示,适配小尺寸
|
||||||
|
formatter: (params) => {
|
||||||
|
const diff = data.diffValue || [];
|
||||||
|
const flags = data.completed || [];
|
||||||
|
const currentDiff = diff[params.dataIndex] || 0;
|
||||||
|
const currentFlag = flags[params.dataIndex] || 0;
|
||||||
|
|
||||||
|
const prefix = currentFlag === 1 ? '+' : '-';
|
||||||
|
|
||||||
|
// 根据标志位选择不同的样式类
|
||||||
|
if (currentFlag === 1) {
|
||||||
|
// 达标 - 使用 rate-achieved 样式
|
||||||
|
return `{achieved|${currentDiff}}{text|差值}`;
|
||||||
|
} else {
|
||||||
|
// 未达标 - 使用 rate-unachieved 样式
|
||||||
|
return `{unachieved|${currentDiff}}{text|差值}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(205, 215, 224, 0.6)' },
|
||||||
|
{ offset: 0.2, color: '#ffffff' },
|
||||||
|
{ offset: 1, color: '#ffffff' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
shadowColor: 'rgba(191,203,215,0.5)',
|
||||||
|
shadowBlur: 2,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowOffsetY: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: '#BFCBD577',
|
||||||
|
borderWidth: 0,
|
||||||
|
lineHeight: 20,
|
||||||
|
rich: {
|
||||||
|
text: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 10, 5, 0],
|
||||||
|
align: 'center',
|
||||||
|
color: '#464646',
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
achieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#76DABE', // 与达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
// 未达标样式
|
||||||
|
unachieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#F9A44A', // 与未达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: (params) => {
|
||||||
|
// 达标状态:1=达标(绿色),0=未达标(橙色)
|
||||||
|
const safeFlag = data.completed || [];
|
||||||
|
const currentFlag = safeFlag[params.dataIndex] || 0;
|
||||||
|
return currentFlag === 1
|
||||||
|
? {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(174, 239, 224, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(118, 218, 190, 1)' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(253, 209, 129, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(249, 164, 74, 1)' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.value || [] // 实际销量(万元)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return salesData;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectProfit(item) {
|
||||||
|
this.selectedProfit = item.name;
|
||||||
|
this.unit = item.unit;
|
||||||
|
this.isDropdownShow = false;
|
||||||
|
this.$emit('handleGetItemData', item.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.coreBar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
// 新增:头部行容器,实现一行排列
|
||||||
|
.header-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end; // 左右两端对齐
|
||||||
|
align-items: center; // 垂直居中
|
||||||
|
// width: 100%;
|
||||||
|
margin-bottom: 8px; // 与下方图表区保留间距(可根据需求调整)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 各基地情况标题样式
|
||||||
|
.base-title {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #000000;
|
||||||
|
line-height: 18px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-style: normal;
|
||||||
|
padding: 0 0 0 16px; // 保留原有内边距
|
||||||
|
white-space: nowrap; // 防止文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.barTop {
|
||||||
|
// 移除原有flex和justify-content,由header-row控制
|
||||||
|
width: auto; // 自适应宽度
|
||||||
|
// 保留原有align-items,确保内部元素垂直居中
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
// 1. 右侧容器:包裹图例和按钮组,整体靠右
|
||||||
|
.right-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center; // 图例和按钮组垂直居中
|
||||||
|
gap: 24px; // 图例与按钮组的间距,避免贴紧
|
||||||
|
margin-right: 46px; // 右侧整体留边,与原按钮组边距一致
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 图例:在右侧容器内横向排列
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px; // 图例项之间间距,避免重叠
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
white-space: nowrap; // 防止图例文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.line {
|
||||||
|
width: 12px;
|
||||||
|
height: 2px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: -2px;
|
||||||
|
left: 3px;
|
||||||
|
width: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 6px;
|
||||||
|
background-color: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.square {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图例颜色
|
||||||
|
.yield {
|
||||||
|
background: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
background: #2889FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.achieved {
|
||||||
|
background: rgba(40, 203, 151, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unachieved {
|
||||||
|
background: rgba(255, 132, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 按钮组:在右侧容器内,保留原有样式
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
gap: 2px;
|
||||||
|
align-items: center;
|
||||||
|
height: 24px;
|
||||||
|
background: #ecf4fe;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.dropdown-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 999; // 提高z-index,确保菜单不被遮挡
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-button {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 24px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn {
|
||||||
|
width: 75px;
|
||||||
|
border-top-left-radius: 12px;
|
||||||
|
border-bottom-left-radius: 12px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-btn {
|
||||||
|
width: 123px;
|
||||||
|
border-top-right-radius: 12px;
|
||||||
|
border-bottom-right-radius: 12px;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 18px 0 8px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #3071ff;
|
||||||
|
color: rgba(249, 252, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-text {
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 6px solid currentColor;
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
|
||||||
|
&.rotate {
|
||||||
|
transform: rotate(90deg); // 箭头旋转方向可根据需求调整,比如改为rotate(-90deg)更符合向上展开的视觉
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-options {
|
||||||
|
position: absolute;
|
||||||
|
// 关键修改1:调整top值,让菜单显示在选择框上方,calc(-100% - 2px)表示向上偏移自身100%再加2px间距
|
||||||
|
bottom: 100%;
|
||||||
|
right: 0;
|
||||||
|
// 移除多余的margin-top,避免额外间距
|
||||||
|
// margin-top: 2px;
|
||||||
|
width: 123px;
|
||||||
|
background: #ffffff;
|
||||||
|
// 关键修改2:调整border-radius,让菜单顶部圆角匹配选择框的右上角,底部圆角为0(更美观)
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.dropdown-option {
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #3071ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,475 @@
|
|||||||
|
<template>
|
||||||
|
<div class="coreBar">
|
||||||
|
<!-- 新增行容器:包裹“各基地情况”和barTop -->
|
||||||
|
<div class="header-row">
|
||||||
|
<div class="barTop">
|
||||||
|
<!-- 关键:新增右侧容器,包裹图例和按钮组,实现整体靠右 -->
|
||||||
|
<div class="right-container">
|
||||||
|
<div class="legend">
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon line yield"></span>
|
||||||
|
完成率
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square target"></span>
|
||||||
|
目标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square achieved"></span>
|
||||||
|
实际·达标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square unachieved"></span>
|
||||||
|
实际·未达标
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="button-group">
|
||||||
|
<div class="item-button category-btn">
|
||||||
|
<span class="item-text">类目选择</span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-container">
|
||||||
|
<div class="item-button profit-btn active" @click.stop="isDropdownShow = !isDropdownShow">
|
||||||
|
<span class="item-text profit-text">{{ selectedProfit || '请选择' }}</span>
|
||||||
|
<span class="dropdown-arrow" :class="{ 'rotate': isDropdownShow }"></span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
|
@click.stop="selectProfit(item)">
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lineBottom" style="height: 100%; width: 100%">
|
||||||
|
<operatingLineBar :chartData="chartD" style="height: 99%; width: 100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import operatingLineBar from './operatingLineBarSale.vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Container",
|
||||||
|
components: { operatingLineBar },
|
||||||
|
props: ["chartData"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isDropdownShow: false,
|
||||||
|
selectedProfit: '采购单价', // 选中的名称,初始为null
|
||||||
|
unit:'元/千克',
|
||||||
|
profitOptions: [
|
||||||
|
{name:'采购单价',unit:'元/千克'},
|
||||||
|
{name:'产量',unit:'㎡'},
|
||||||
|
{name:'单耗',unit:'千克/㎡'},
|
||||||
|
{name:'消耗量',unit:'千克'}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentDataSource() {
|
||||||
|
return this.chartData
|
||||||
|
},
|
||||||
|
locations() {
|
||||||
|
return this.chartData.time
|
||||||
|
},
|
||||||
|
// 根据按钮切换生成对应的 chartData
|
||||||
|
chartD() {
|
||||||
|
// 销量场景数据
|
||||||
|
const data = this.currentDataSource;
|
||||||
|
console.log(this.currentDataSource, 'currentDataSource');
|
||||||
|
console.log('this.currentDataSource', data);
|
||||||
|
|
||||||
|
const salesData = {
|
||||||
|
allPlaceNames: this.locations,
|
||||||
|
unit:this.unit,
|
||||||
|
series: [
|
||||||
|
// 1. 完成率(折线图)
|
||||||
|
{
|
||||||
|
name: '完成率',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1, // 绑定右侧Y轴(需在子组件启用配置)
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, .5)',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderColor: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
radius: 4
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.2,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(40, 138, 255, .9)' },
|
||||||
|
{ offset: 1, color: 'rgba(40, 138, 255, 0)' }
|
||||||
|
])
|
||||||
|
},
|
||||||
|
data: data.proportion || [], // 完成率(%)
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 6
|
||||||
|
},
|
||||||
|
// 2. 目标(柱状图)
|
||||||
|
{
|
||||||
|
name: '预算',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0, // 左侧Y轴(万元)
|
||||||
|
barWidth: 14,
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(75, 157, 255, 1)' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.targetValue || [] // 目标销量(万元)
|
||||||
|
},
|
||||||
|
// 3. 实际(柱状图,含达标状态)
|
||||||
|
{
|
||||||
|
name: '实际',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
offset: [0, 0],
|
||||||
|
// 固定label尺寸:68px×20px
|
||||||
|
width: 68,
|
||||||
|
height: 20,
|
||||||
|
// 关键:去掉换行,让文字在一行显示,适配小尺寸
|
||||||
|
formatter: (params) => {
|
||||||
|
const diff = data.diffValue || [];
|
||||||
|
const flags = data.completed || [];
|
||||||
|
const currentDiff = diff[params.dataIndex] || 0;
|
||||||
|
const currentFlag = flags[params.dataIndex] || 0;
|
||||||
|
|
||||||
|
const prefix = currentFlag === 1 ? '+' : '-';
|
||||||
|
|
||||||
|
// 根据标志位选择不同的样式类
|
||||||
|
if (currentFlag === 1) {
|
||||||
|
// 达标 - 使用 rate-achieved 样式
|
||||||
|
return `{achieved|${currentDiff}}{text|差值}`;
|
||||||
|
} else {
|
||||||
|
// 未达标 - 使用 rate-unachieved 样式
|
||||||
|
return `{unachieved|${currentDiff}}{text|差值}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(205, 215, 224, 0.6)' },
|
||||||
|
{ offset: 0.2, color: '#ffffff' },
|
||||||
|
{ offset: 1, color: '#ffffff' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
shadowColor: 'rgba(191,203,215,0.5)',
|
||||||
|
shadowBlur: 2,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowOffsetY: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: '#BFCBD577',
|
||||||
|
borderWidth: 0,
|
||||||
|
lineHeight: 20,
|
||||||
|
rich: {
|
||||||
|
text: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 10, 5, 0],
|
||||||
|
align: 'center',
|
||||||
|
color: '#464646',
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
achieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#76DABE', // 与达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
// 未达标样式
|
||||||
|
unachieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#F9A44A', // 与未达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: (params) => {
|
||||||
|
// 达标状态:1=达标(绿色),0=未达标(橙色)
|
||||||
|
const safeFlag = data.completed || [];
|
||||||
|
const currentFlag = safeFlag[params.dataIndex] || 0;
|
||||||
|
return currentFlag === 1
|
||||||
|
? {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(174, 239, 224, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(118, 218, 190, 1)' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(253, 209, 129, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(249, 164, 74, 1)' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.value || [] // 实际销量(万元)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return salesData;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectProfit(item) {
|
||||||
|
this.selectedProfit = item.name;
|
||||||
|
this.unit = item.unit;
|
||||||
|
this.isDropdownShow = false;
|
||||||
|
this.$emit('handleGetItemData', item.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.coreBar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
// 新增:头部行容器,实现一行排列
|
||||||
|
.header-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end; // 左右两端对齐
|
||||||
|
align-items: center; // 垂直居中
|
||||||
|
// width: 100%;
|
||||||
|
margin-bottom: 8px; // 与下方图表区保留间距(可根据需求调整)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 各基地情况标题样式
|
||||||
|
.base-title {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #000000;
|
||||||
|
line-height: 18px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-style: normal;
|
||||||
|
padding: 0 0 0 16px; // 保留原有内边距
|
||||||
|
white-space: nowrap; // 防止文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.barTop {
|
||||||
|
// 移除原有flex和justify-content,由header-row控制
|
||||||
|
width: auto; // 自适应宽度
|
||||||
|
// 保留原有align-items,确保内部元素垂直居中
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
// 1. 右侧容器:包裹图例和按钮组,整体靠右
|
||||||
|
.right-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center; // 图例和按钮组垂直居中
|
||||||
|
gap: 24px; // 图例与按钮组的间距,避免贴紧
|
||||||
|
margin-right: 46px; // 右侧整体留边,与原按钮组边距一致
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 图例:在右侧容器内横向排列
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px; // 图例项之间间距,避免重叠
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
white-space: nowrap; // 防止图例文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.line {
|
||||||
|
width: 12px;
|
||||||
|
height: 2px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: -2px;
|
||||||
|
left: 3px;
|
||||||
|
width: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 6px;
|
||||||
|
background-color: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.square {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图例颜色
|
||||||
|
.yield {
|
||||||
|
background: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
background: #2889FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.achieved {
|
||||||
|
background: rgba(40, 203, 151, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unachieved {
|
||||||
|
background: rgba(255, 132, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 按钮组:在右侧容器内,保留原有样式
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
gap: 2px;
|
||||||
|
align-items: center;
|
||||||
|
height: 24px;
|
||||||
|
background: #ecf4fe;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.dropdown-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 999; // 提高z-index,确保菜单不被遮挡
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-button {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 24px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn {
|
||||||
|
width: 75px;
|
||||||
|
border-top-left-radius: 12px;
|
||||||
|
border-bottom-left-radius: 12px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-btn {
|
||||||
|
width: 123px;
|
||||||
|
border-top-right-radius: 12px;
|
||||||
|
border-bottom-right-radius: 12px;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 18px 0 8px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #3071ff;
|
||||||
|
color: rgba(249, 252, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-text {
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 6px solid currentColor;
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
|
||||||
|
&.rotate {
|
||||||
|
transform: rotate(90deg); // 箭头旋转方向可根据需求调整,比如改为rotate(-90deg)更符合向上展开的视觉
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-options {
|
||||||
|
position: absolute;
|
||||||
|
// 关键修改1:调整top值,让菜单显示在选择框上方,calc(-100% - 2px)表示向上偏移自身100%再加2px间距
|
||||||
|
bottom: 100%;
|
||||||
|
right: 0;
|
||||||
|
// 移除多余的margin-top,避免额外间距
|
||||||
|
// margin-top: 2px;
|
||||||
|
width: 123px;
|
||||||
|
background: #ffffff;
|
||||||
|
// 关键修改2:调整border-radius,让菜单顶部圆角匹配选择框的右上角,底部圆角为0(更美观)
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.dropdown-option {
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #3071ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
<template>
|
||||||
|
<div class="coreBar">
|
||||||
|
<!-- 新增行容器:包裹“各基地情况”和barTop -->
|
||||||
|
<div class="header-row">
|
||||||
|
<div class="barTop">
|
||||||
|
<!-- 关键:新增右侧容器,包裹图例和按钮组,实现整体靠右 -->
|
||||||
|
<div class="right-container">
|
||||||
|
<div class="legend">
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon line yield"></span>
|
||||||
|
完成率
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square target"></span>
|
||||||
|
目标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square achieved"></span>
|
||||||
|
实际·达标
|
||||||
|
</span>
|
||||||
|
<span class="legend-item">
|
||||||
|
<span class="legend-icon square unachieved"></span>
|
||||||
|
实际·未达标
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="button-group">
|
||||||
|
<div class="item-button category-btn">
|
||||||
|
<span class="item-text">类目选择</span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-container">
|
||||||
|
<div class="item-button profit-btn active" @click.stop="isDropdownShow = !isDropdownShow">
|
||||||
|
<span class="item-text profit-text">{{ selectedProfit || '请选择' }}</span>
|
||||||
|
<span class="dropdown-arrow" :class="{ 'rotate': isDropdownShow }"></span>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-options" v-if="isDropdownShow">
|
||||||
|
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||||
|
@click.stop="selectProfit(item)">
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lineBottom" style="height: 100%; width: 100%">
|
||||||
|
<operatingLineBar :chartData="chartD" style="height: 99%; width: 100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import operatingLineBar from './operatingLineBarSale.vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Container",
|
||||||
|
components: { operatingLineBar },
|
||||||
|
props: ["chartData"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isDropdownShow: false,
|
||||||
|
selectedProfit: '采购单价', // 选中的名称,初始为null
|
||||||
|
unit:'元/吨',
|
||||||
|
profitOptions: [
|
||||||
|
{name:'采购单价',unit:'元/吨'},
|
||||||
|
{name:'产量',unit:'㎡'},
|
||||||
|
{name:'单耗',unit:'千克/㎡'},
|
||||||
|
{name:'消耗量',unit:'吨'},
|
||||||
|
{name:'日均消耗量',unit:'吨'}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentDataSource() {
|
||||||
|
return this.chartData
|
||||||
|
},
|
||||||
|
locations() {
|
||||||
|
return this.chartData.time
|
||||||
|
},
|
||||||
|
// 根据按钮切换生成对应的 chartData
|
||||||
|
chartD() {
|
||||||
|
// 销量场景数据
|
||||||
|
const data = this.currentDataSource;
|
||||||
|
console.log(this.currentDataSource, 'currentDataSource');
|
||||||
|
console.log('this.currentDataSource', data);
|
||||||
|
|
||||||
|
const salesData = {
|
||||||
|
allPlaceNames: this.locations,
|
||||||
|
unit:this.unit,
|
||||||
|
series: [
|
||||||
|
// 1. 完成率(折线图)
|
||||||
|
{
|
||||||
|
name: '完成率',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1, // 绑定右侧Y轴(需在子组件启用配置)
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, .5)',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderColor: 'rgba(40, 138, 255, 1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
radius: 4
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.2,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{ offset: 0, color: 'rgba(40, 138, 255, .9)' },
|
||||||
|
{ offset: 1, color: 'rgba(40, 138, 255, 0)' }
|
||||||
|
])
|
||||||
|
},
|
||||||
|
data: data.proportion || [], // 完成率(%)
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 6
|
||||||
|
},
|
||||||
|
// 2. 目标(柱状图)
|
||||||
|
{
|
||||||
|
name: '预算',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0, // 左侧Y轴(万元)
|
||||||
|
barWidth: 14,
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(75, 157, 255, 1)' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.targetValue || [] // 目标销量(万元)
|
||||||
|
},
|
||||||
|
// 3. 实际(柱状图,含达标状态)
|
||||||
|
{
|
||||||
|
name: '实际',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 0,
|
||||||
|
barWidth: 14,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
offset: [0, 0],
|
||||||
|
// 固定label尺寸:68px×20px
|
||||||
|
width: 68,
|
||||||
|
height: 20,
|
||||||
|
// 关键:去掉换行,让文字在一行显示,适配小尺寸
|
||||||
|
formatter: (params) => {
|
||||||
|
const diff = data.diffValue || [];
|
||||||
|
const flags = data.completed || [];
|
||||||
|
const currentDiff = diff[params.dataIndex] || 0;
|
||||||
|
const currentFlag = flags[params.dataIndex] || 0;
|
||||||
|
|
||||||
|
const prefix = currentFlag === 1 ? '+' : '-';
|
||||||
|
|
||||||
|
// 根据标志位选择不同的样式类
|
||||||
|
if (currentFlag === 1) {
|
||||||
|
// 达标 - 使用 rate-achieved 样式
|
||||||
|
return `{achieved|${currentDiff}}{text|差值}`;
|
||||||
|
} else {
|
||||||
|
// 未达标 - 使用 rate-unachieved 样式
|
||||||
|
return `{unachieved|${currentDiff}}{text|差值}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(205, 215, 224, 0.6)' },
|
||||||
|
{ offset: 0.2, color: '#ffffff' },
|
||||||
|
{ offset: 1, color: '#ffffff' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
shadowColor: 'rgba(191,203,215,0.5)',
|
||||||
|
shadowBlur: 2,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowOffsetY: 2,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: '#BFCBD577',
|
||||||
|
borderWidth: 0,
|
||||||
|
lineHeight: 20,
|
||||||
|
rich: {
|
||||||
|
text: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 10, 5, 0],
|
||||||
|
align: 'center',
|
||||||
|
color: '#464646',
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
achieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#76DABE', // 与达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
},
|
||||||
|
// 未达标样式
|
||||||
|
unachieved: {
|
||||||
|
width: 'auto',
|
||||||
|
padding: [5, 0, 5, 10],
|
||||||
|
align: 'center',
|
||||||
|
color: '#F9A44A', // 与未达标的 offset: 1 颜色一致
|
||||||
|
fontSize: 11,
|
||||||
|
lineHeight: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: (params) => {
|
||||||
|
// 达标状态:1=达标(绿色),0=未达标(橙色)
|
||||||
|
const safeFlag = data.completed || [];
|
||||||
|
const currentFlag = safeFlag[params.dataIndex] || 0;
|
||||||
|
return currentFlag === 1
|
||||||
|
? {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(174, 239, 224, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(118, 218, 190, 1)' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0, y: 0, x2: 0, y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(253, 209, 129, 1)' },
|
||||||
|
{ offset: 1, color: 'rgba(249, 164, 74, 1)' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
borderRadius: [4, 4, 0, 0],
|
||||||
|
borderWidth: 0
|
||||||
|
},
|
||||||
|
data: data.value || [] // 实际销量(万元)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return salesData;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectProfit(item) {
|
||||||
|
this.selectedProfit = item.name;
|
||||||
|
this.unit = item.unit;
|
||||||
|
this.isDropdownShow = false;
|
||||||
|
this.$emit('handleGetItemData', item.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.coreBar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
// 新增:头部行容器,实现一行排列
|
||||||
|
.header-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end; // 左右两端对齐
|
||||||
|
align-items: center; // 垂直居中
|
||||||
|
// width: 100%;
|
||||||
|
margin-bottom: 8px; // 与下方图表区保留间距(可根据需求调整)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 各基地情况标题样式
|
||||||
|
.base-title {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #000000;
|
||||||
|
line-height: 18px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-style: normal;
|
||||||
|
padding: 0 0 0 16px; // 保留原有内边距
|
||||||
|
white-space: nowrap; // 防止文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.barTop {
|
||||||
|
// 移除原有flex和justify-content,由header-row控制
|
||||||
|
width: auto; // 自适应宽度
|
||||||
|
// 保留原有align-items,确保内部元素垂直居中
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
// 1. 右侧容器:包裹图例和按钮组,整体靠右
|
||||||
|
.right-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center; // 图例和按钮组垂直居中
|
||||||
|
gap: 24px; // 图例与按钮组的间距,避免贴紧
|
||||||
|
margin-right: 46px; // 右侧整体留边,与原按钮组边距一致
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 图例:在右侧容器内横向排列
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px; // 图例项之间间距,避免重叠
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
white-space: nowrap; // 防止图例文字换行
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.line {
|
||||||
|
width: 12px;
|
||||||
|
height: 2px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
top: -2px;
|
||||||
|
left: 3px;
|
||||||
|
width: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 6px;
|
||||||
|
background-color: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-icon.square {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图例颜色
|
||||||
|
.yield {
|
||||||
|
background: rgba(40, 138, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
background: #2889FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.achieved {
|
||||||
|
background: rgba(40, 203, 151, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unachieved {
|
||||||
|
background: rgba(255, 132, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 按钮组:在右侧容器内,保留原有样式
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
gap: 2px;
|
||||||
|
align-items: center;
|
||||||
|
height: 24px;
|
||||||
|
background: #ecf4fe;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.dropdown-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 999; // 提高z-index,确保菜单不被遮挡
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-button {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 24px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn {
|
||||||
|
width: 75px;
|
||||||
|
border-top-left-radius: 12px;
|
||||||
|
border-bottom-left-radius: 12px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-btn {
|
||||||
|
width: 123px;
|
||||||
|
border-top-right-radius: 12px;
|
||||||
|
border-bottom-right-radius: 12px;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 18px 0 8px;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0b58ff;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #3071ff;
|
||||||
|
color: rgba(249, 252, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profit-text {
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 6px solid currentColor;
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
|
||||||
|
&.rotate {
|
||||||
|
transform: rotate(90deg); // 箭头旋转方向可根据需求调整,比如改为rotate(-90deg)更符合向上展开的视觉
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-options {
|
||||||
|
position: absolute;
|
||||||
|
// 关键修改1:调整top值,让菜单显示在选择框上方,calc(-100% - 2px)表示向上偏移自身100%再加2px间距
|
||||||
|
bottom: 100%;
|
||||||
|
right: 0;
|
||||||
|
// 移除多余的margin-top,避免额外间距
|
||||||
|
// margin-top: 2px;
|
||||||
|
width: 123px;
|
||||||
|
background: #ffffff;
|
||||||
|
// 关键修改2:调整border-radius,让菜单顶部圆角匹配选择框的右上角,底部圆角为0(更美观)
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.dropdown-option {
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #3071ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
background-color: rgba(249, 252, 255, 1);
|
background-color: rgba(249, 252, 255, 1);
|
||||||
">
|
">
|
||||||
<!-- 直接使用计算属性 chartData,无需手动更新 -->
|
<!-- 直接使用计算属性 chartData,无需手动更新 -->
|
||||||
<dataTrendBar @handleGetItemData="getData" :chartData="chartData" />
|
<dataTrendBar :fuelName='fuelName' @handleGetItemData="getData" :chartData="chartData" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
@@ -28,6 +28,10 @@ export default {
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
fuelName: {
|
||||||
|
type: String,
|
||||||
|
default: () => "",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Container from "../components/container.vue";
|
import Container from "../components/container.vue";
|
||||||
import dataTrendBar from "./dataTrendBarSingleFuel.vue";
|
import dataTrendBar from "./dataTrendBarSingleFuelDian.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProductionStatus",
|
name: "ProductionStatus",
|
||||||
@@ -91,7 +91,6 @@ export default {
|
|||||||
return `${year}-${month}`;
|
return `${year}-${month}`;
|
||||||
},
|
},
|
||||||
getData(value) {
|
getData(value) {
|
||||||
console.log('bbbbbbbbbbbbb=================',value)
|
|
||||||
this.$emit('getData', value)
|
this.$emit('getData', value)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,254 @@
|
|||||||
|
<template>
|
||||||
|
<div style="flex: 1">
|
||||||
|
<Container name="数据趋势" icon="cockpitItemIcon" size="opLargeBg" topSize="large">
|
||||||
|
<div class="kpi-content" style="padding: 14px 16px; display: flex; width: 100%; gap: 16px">
|
||||||
|
<div class="right" style="
|
||||||
|
height: 191px;
|
||||||
|
display: flex;
|
||||||
|
width: 1595px;
|
||||||
|
background-color: rgba(249, 252, 255, 1);
|
||||||
|
">
|
||||||
|
<!-- 直接使用计算属性 chartData,无需手动更新 -->
|
||||||
|
<dataTrendBar :fuelName='fuelName' @handleGetItemData="getData" :chartData="chartData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Container from "../components/container.vue";
|
||||||
|
import dataTrendBar from "./dataTrendBarSingleFuelDian.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProductionStatus",
|
||||||
|
components: { Container, dataTrendBar },
|
||||||
|
props: {
|
||||||
|
trendData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
fuelName: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 移除:原 chartData 定义,改为计算属性
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 移除:原 watch 监听配置,计算属性自动响应 trendData 变化
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* chartData 计算属性:自动响应 trendData 变化,格式化并提取各字段数组
|
||||||
|
* @returns {Object} 包含6个独立数组的格式化数据
|
||||||
|
*/
|
||||||
|
chartData() {
|
||||||
|
// 初始化6个独立数组
|
||||||
|
const timeArr = []; // 格式化后的年月数组
|
||||||
|
const valueArr = []; // 实际值数组
|
||||||
|
const diffValueArr = []; // 差异值数组
|
||||||
|
const targetValueArr = []; // 预算值数组
|
||||||
|
const proportionArr = []; // 占比数组
|
||||||
|
const completedArr = []; // 完成率数组
|
||||||
|
|
||||||
|
// 遍历传入的 trendData 数组(响应式依赖,变化时自动重算)
|
||||||
|
this.trendData.forEach((item) => {
|
||||||
|
// 1. 格式化时间并推入时间数组
|
||||||
|
const yearMonth = this.formatTimeToYearMonth(item.time);
|
||||||
|
timeArr.push(yearMonth);
|
||||||
|
|
||||||
|
// 2. 提取其他字段,兜底为0(防止null/undefined影响图表渲染)
|
||||||
|
valueArr.push(item.value ?? 0);
|
||||||
|
diffValueArr.push(item.diffValue ?? 0);
|
||||||
|
targetValueArr.push(item.targetValue ?? 0);
|
||||||
|
proportionArr.push(item.proportion ?? 0);
|
||||||
|
completedArr.push(item.completed ?? 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组装并返回格式化后的数据(结构与原一致)
|
||||||
|
return {
|
||||||
|
time: timeArr,
|
||||||
|
value: valueArr,
|
||||||
|
diffValue: diffValueArr,
|
||||||
|
targetValue: targetValueArr,
|
||||||
|
proportion: proportionArr,
|
||||||
|
completed: completedArr,
|
||||||
|
rawData: this.trendData, // 透传原始数据,方便子组件使用
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 格式化时间戳为年月格式(YYYY-MM)
|
||||||
|
* @param {Number} timestamp 13位毫秒级时间戳
|
||||||
|
* @returns {String} 格式化后的年月字符串(如:2025-10)
|
||||||
|
*/
|
||||||
|
formatTimeToYearMonth(timestamp) {
|
||||||
|
if (!timestamp || isNaN(timestamp)) {
|
||||||
|
return ""; // 容错:非有效时间戳返回空字符串
|
||||||
|
}
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始,补0至2位
|
||||||
|
return `${year}-${month}`;
|
||||||
|
},
|
||||||
|
getData(value) {
|
||||||
|
this.$emit('getData', value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</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>
|
||||||
|
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
||||||
|
.production-status-chart-tooltip {
|
||||||
|
background: #0a2b4f77 !important;
|
||||||
|
border: none !important;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.production-status-chart-tooltip * {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
<template>
|
||||||
|
<div style="flex: 1">
|
||||||
|
<Container name="数据趋势" icon="cockpitItemIcon" size="opLargeBg" topSize="large">
|
||||||
|
<div class="kpi-content" style="padding: 14px 16px; display: flex; width: 100%; gap: 16px">
|
||||||
|
<div class="right" style="
|
||||||
|
height: 191px;
|
||||||
|
display: flex;
|
||||||
|
width: 1595px;
|
||||||
|
background-color: rgba(249, 252, 255, 1);
|
||||||
|
">
|
||||||
|
<!-- 直接使用计算属性 chartData,无需手动更新 -->
|
||||||
|
<dataTrendBar @handleGetItemData="getData" :chartData="chartData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Container from "../components/container.vue";
|
||||||
|
import dataTrendBar from "./dataTrendBarSingleFuelF.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProductionStatus",
|
||||||
|
components: { Container, dataTrendBar },
|
||||||
|
props: {
|
||||||
|
trendData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 移除:原 chartData 定义,改为计算属性
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 移除:原 watch 监听配置,计算属性自动响应 trendData 变化
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* chartData 计算属性:自动响应 trendData 变化,格式化并提取各字段数组
|
||||||
|
* @returns {Object} 包含6个独立数组的格式化数据
|
||||||
|
*/
|
||||||
|
chartData() {
|
||||||
|
// 初始化6个独立数组
|
||||||
|
const timeArr = []; // 格式化后的年月数组
|
||||||
|
const valueArr = []; // 实际值数组
|
||||||
|
const diffValueArr = []; // 差异值数组
|
||||||
|
const targetValueArr = []; // 预算值数组
|
||||||
|
const proportionArr = []; // 占比数组
|
||||||
|
const completedArr = []; // 完成率数组
|
||||||
|
|
||||||
|
// 遍历传入的 trendData 数组(响应式依赖,变化时自动重算)
|
||||||
|
this.trendData.forEach((item) => {
|
||||||
|
// 1. 格式化时间并推入时间数组
|
||||||
|
const yearMonth = this.formatTimeToYearMonth(item.time);
|
||||||
|
timeArr.push(yearMonth);
|
||||||
|
|
||||||
|
// 2. 提取其他字段,兜底为0(防止null/undefined影响图表渲染)
|
||||||
|
valueArr.push(item.value ?? 0);
|
||||||
|
diffValueArr.push(item.diffValue ?? 0);
|
||||||
|
targetValueArr.push(item.targetValue ?? 0);
|
||||||
|
proportionArr.push(item.proportion ?? 0);
|
||||||
|
completedArr.push(item.completed ?? 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组装并返回格式化后的数据(结构与原一致)
|
||||||
|
return {
|
||||||
|
time: timeArr,
|
||||||
|
value: valueArr,
|
||||||
|
diffValue: diffValueArr,
|
||||||
|
targetValue: targetValueArr,
|
||||||
|
proportion: proportionArr,
|
||||||
|
completed: completedArr,
|
||||||
|
rawData: this.trendData, // 透传原始数据,方便子组件使用
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 格式化时间戳为年月格式(YYYY-MM)
|
||||||
|
* @param {Number} timestamp 13位毫秒级时间戳
|
||||||
|
* @returns {String} 格式化后的年月字符串(如:2025-10)
|
||||||
|
*/
|
||||||
|
formatTimeToYearMonth(timestamp) {
|
||||||
|
if (!timestamp || isNaN(timestamp)) {
|
||||||
|
return ""; // 容错:非有效时间戳返回空字符串
|
||||||
|
}
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始,补0至2位
|
||||||
|
return `${year}-${month}`;
|
||||||
|
},
|
||||||
|
getData(value) {
|
||||||
|
this.$emit('getData', value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</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>
|
||||||
|
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
||||||
|
.production-status-chart-tooltip {
|
||||||
|
background: #0a2b4f77 !important;
|
||||||
|
border: none !important;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.production-status-chart-tooltip * {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
<template>
|
||||||
|
<div style="flex: 1">
|
||||||
|
<Container name="数据趋势" icon="cockpitItemIcon" size="opLargeBg" topSize="large">
|
||||||
|
<div class="kpi-content" style="padding: 14px 16px; display: flex; width: 100%; gap: 16px">
|
||||||
|
<div class="right" style="
|
||||||
|
height: 191px;
|
||||||
|
display: flex;
|
||||||
|
width: 1595px;
|
||||||
|
background-color: rgba(249, 252, 255, 1);
|
||||||
|
">
|
||||||
|
<!-- 直接使用计算属性 chartData,无需手动更新 -->
|
||||||
|
<dataTrendBar @handleGetItemData="getData" :chartData="chartData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Container from "../components/container.vue";
|
||||||
|
import dataTrendBar from "./dataTrendBarSingleFuelYL.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProductionStatus",
|
||||||
|
components: { Container, dataTrendBar },
|
||||||
|
props: {
|
||||||
|
trendData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 移除:原 chartData 定义,改为计算属性
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 移除:原 watch 监听配置,计算属性自动响应 trendData 变化
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* chartData 计算属性:自动响应 trendData 变化,格式化并提取各字段数组
|
||||||
|
* @returns {Object} 包含6个独立数组的格式化数据
|
||||||
|
*/
|
||||||
|
chartData() {
|
||||||
|
// 初始化6个独立数组
|
||||||
|
const timeArr = []; // 格式化后的年月数组
|
||||||
|
const valueArr = []; // 实际值数组
|
||||||
|
const diffValueArr = []; // 差异值数组
|
||||||
|
const targetValueArr = []; // 预算值数组
|
||||||
|
const proportionArr = []; // 占比数组
|
||||||
|
const completedArr = []; // 完成率数组
|
||||||
|
|
||||||
|
// 遍历传入的 trendData 数组(响应式依赖,变化时自动重算)
|
||||||
|
this.trendData.forEach((item) => {
|
||||||
|
// 1. 格式化时间并推入时间数组
|
||||||
|
const yearMonth = this.formatTimeToYearMonth(item.time);
|
||||||
|
timeArr.push(yearMonth);
|
||||||
|
|
||||||
|
// 2. 提取其他字段,兜底为0(防止null/undefined影响图表渲染)
|
||||||
|
valueArr.push(item.value ?? 0);
|
||||||
|
diffValueArr.push(item.diffValue ?? 0);
|
||||||
|
targetValueArr.push(item.targetValue ?? 0);
|
||||||
|
proportionArr.push(item.proportion ?? 0);
|
||||||
|
completedArr.push(item.completed ?? 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组装并返回格式化后的数据(结构与原一致)
|
||||||
|
return {
|
||||||
|
time: timeArr,
|
||||||
|
value: valueArr,
|
||||||
|
diffValue: diffValueArr,
|
||||||
|
targetValue: targetValueArr,
|
||||||
|
proportion: proportionArr,
|
||||||
|
completed: completedArr,
|
||||||
|
rawData: this.trendData, // 透传原始数据,方便子组件使用
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 格式化时间戳为年月格式(YYYY-MM)
|
||||||
|
* @param {Number} timestamp 13位毫秒级时间戳
|
||||||
|
* @returns {String} 格式化后的年月字符串(如:2025-10)
|
||||||
|
*/
|
||||||
|
formatTimeToYearMonth(timestamp) {
|
||||||
|
if (!timestamp || isNaN(timestamp)) {
|
||||||
|
return ""; // 容错:非有效时间戳返回空字符串
|
||||||
|
}
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始,补0至2位
|
||||||
|
return `${year}-${month}`;
|
||||||
|
},
|
||||||
|
getData(value) {
|
||||||
|
this.$emit('getData', value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</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>
|
||||||
|
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
||||||
|
.production-status-chart-tooltip {
|
||||||
|
background: #0a2b4f77 !important;
|
||||||
|
border: none !important;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.production-status-chart-tooltip * {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="topItem-container" style="display: flex; gap: 8px;">
|
<div class="topItem-container" style="display: flex; gap: 8px;">
|
||||||
<div class="dashboard left" @click="handleDashboardClick('电')" :detailData="dianData">
|
<div class="dashboard left" @click="handleDashboardClick('电')" :detailData="dianData">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
电·万元
|
电·元/㎡
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{dianData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{dianData.proportion}}%</span></span>
|
||||||
|
|||||||
@@ -1,240 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div style="flex: 1">
|
|
||||||
<Container :name="title" icon="cockpitItemIcon" size="operatingRevenueBg" topSize="middle">
|
|
||||||
<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="handleDashboardClick(item.name)"
|
|
||||||
>
|
|
||||||
<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 './container.vue'
|
|
||||||
import operatingSingleBar from './operatingSingleBar.vue'
|
|
||||||
|
|
||||||
// import * as echarts from 'echarts'
|
|
||||||
// import rawItem from './raw-Item.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ProductionStatus',
|
|
||||||
components: { Container, operatingSingleBar },
|
|
||||||
props: {
|
|
||||||
// 接收父组件传递的 月度+累计 组合数据(原有配置保留,仅优化注释)
|
|
||||||
relatedData: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
dateData: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
factory: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 可选:动态标题(原有配置保留)
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
// 注释无效的activeData,保持数据简洁(样式不变)
|
|
||||||
// activeData: this.relatedData || []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
indicatorDefs() {
|
|
||||||
return [
|
|
||||||
{ key: 'coatingLiquid', name: '镀膜液', unit: '万元'},
|
|
||||||
{ key: 'ink', name: '油墨', unit: '万元'},
|
|
||||||
{ key: 'glaze', name: '釉料', unit: '万元'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
indicators() {
|
|
||||||
const fallback = { targetValue: 0, value: 0, completed: 0, diffValue: 0 }
|
|
||||||
const list = (Array.isArray(this.relatedData) ? this.relatedData : [])
|
|
||||||
|
|
||||||
return this.indicatorDefs.map(def => {
|
|
||||||
const data = list.find(item => item && item.name.includes(def.name)) || 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注释(若需恢复可直接启用,样式不变)
|
|
||||||
// watch: {
|
|
||||||
// relatedData: {
|
|
||||||
// handler(newVal) {
|
|
||||||
// this.activeData = newVal.relatedMon || [];
|
|
||||||
// },
|
|
||||||
// immediate: true,
|
|
||||||
// deep: true
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
mounted() {
|
|
||||||
// 优化打印日志,输出有效数据(样式不变)
|
|
||||||
console.log('组件挂载时的相关数据:', this.relatedData);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleDashboardClick(name) {
|
|
||||||
this.$router.push({
|
|
||||||
path: 'singleProcAuxMatCost',
|
|
||||||
query: {
|
|
||||||
name,
|
|
||||||
factory: this.$route.query.factory ? this.$route.query.factory : this.factory,
|
|
||||||
dateData: this.dateData
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
|
||||||
/* 样式100%保留不变,无任何增删改 */
|
|
||||||
/* 3. 核心:滚动容器样式(固定高度+溢出滚动+隐藏滚动条) */
|
|
||||||
.scroll-container {
|
|
||||||
/* 1. 固定容器高度:根据页面布局调整(示例300px,超出则滚动) */
|
|
||||||
max-height: 210px;
|
|
||||||
/* 2. 溢出滚动:内容超出高度时显示滚动功能 */
|
|
||||||
overflow-y: auto;
|
|
||||||
/* 3. 隐藏横向滚动条(防止设备名过长导致横向滚动) */
|
|
||||||
overflow-x: hidden;
|
|
||||||
/* 4. 内边距:与标题栏和容器边缘对齐 */
|
|
||||||
padding: 10px 0;
|
|
||||||
|
|
||||||
/* 5. 隐藏滚动条(兼容主流浏览器) */
|
|
||||||
/* Chrome/Safari */
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Firefox */
|
|
||||||
scrollbar-width: none;
|
|
||||||
/* IE/Edge */
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard {
|
|
||||||
width: 250px;
|
|
||||||
height: 205px;
|
|
||||||
background: #F9FCFF;
|
|
||||||
padding: 16px 0 0 10px;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
// width: 190px;
|
|
||||||
height: 18px;
|
|
||||||
font-family: PingFangSC, PingFang SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 18px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.number {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
// width: 190px;
|
|
||||||
height: 32px;
|
|
||||||
font-family: YouSheBiaoTiHei;
|
|
||||||
font-size: 32px;
|
|
||||||
color: #0B58FF;
|
|
||||||
line-height: 32px;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mom {
|
|
||||||
width: 120px;
|
|
||||||
height: 18px;
|
|
||||||
font-family: PingFangSC, PingFang SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 18px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// .line {
|
|
||||||
// width: 500px;
|
|
||||||
// height: 205px;
|
|
||||||
// background: #F9FCFF;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .leftTitle {
|
|
||||||
// .item {
|
|
||||||
// width: 67px;
|
|
||||||
// height: 180px;
|
|
||||||
// padding: 37px 23px;
|
|
||||||
// background: #F9FCFF;
|
|
||||||
// font-family: PingFangSC, PingFang SC;
|
|
||||||
// font-weight: 400;
|
|
||||||
// font-size: 18px;
|
|
||||||
// color: #000000;
|
|
||||||
// line-height: 25px;
|
|
||||||
// letter-spacing: 1px;
|
|
||||||
// // text-align: left;
|
|
||||||
// font-style: normal;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- <style>
|
|
||||||
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
|
||||||
.production-status-chart-tooltip {
|
|
||||||
background: #0a2b4f77 !important;
|
|
||||||
border: none !important;
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.production-status-chart-tooltip * {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
</style> -->
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
v-for="item in sortedIndicators"
|
v-for="item in sortedIndicators"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
class="dashboard"
|
class="dashboard"
|
||||||
@click="handleDashboardClick(item.name)"
|
@click="item.route && handleDashboardClick(item.name,item.route)"
|
||||||
>
|
>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.name }}·{{ item.unit }}
|
{{ item.name }}·{{ item.unit }}
|
||||||
@@ -62,9 +62,9 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'mx', name: '芒硝', unit: '元/㎡'},
|
{ key: 'mx', name: '芒硝', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'xsn', name: '硝酸钠', unit: '元/㎡'},
|
{ key: 'xsn', name: '硝酸钠', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'jtsn', name: '焦锑酸钠', unit: '元/㎡'},
|
{ key: 'jtsn', name: '焦锑酸钠', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
@@ -112,16 +112,17 @@ export default {
|
|||||||
console.log('组件挂载时的相关数据:', this.relatedData);
|
console.log('组件挂载时的相关数据:', this.relatedData);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleDashboardClick(name) {
|
handleDashboardClick(material, path) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: 'singleProcMfgOverheadCost',
|
path: path,
|
||||||
query: {
|
query: {
|
||||||
name,
|
name: material,
|
||||||
factory: this.$route.query.factory ? this.$route.query.factory : this.factory,
|
month: this.month,
|
||||||
|
factory: this.$route.query.factory ? this.$route.query.factory :5,
|
||||||
dateData: this.dateData
|
dateData: this.dateData
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export default {
|
|||||||
return; // 实例未初始化则返回
|
return; // 实例未初始化则返回
|
||||||
}
|
}
|
||||||
|
|
||||||
const { allPlaceNames, series } = this.chartData || {};
|
const { allPlaceNames,unit, series } = this.chartData || {};
|
||||||
const xData = allPlaceNames || [];
|
const xData = allPlaceNames || [];
|
||||||
const chartSeries = series || [];
|
const chartSeries = series || [];
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ export default {
|
|||||||
top: 30,
|
top: 30,
|
||||||
bottom: 5,
|
bottom: 5,
|
||||||
right: 20,
|
right: 20,
|
||||||
left: 35,
|
left: 55,
|
||||||
containLabel: true
|
containLabel: true
|
||||||
},
|
},
|
||||||
xAxis: [
|
xAxis: [
|
||||||
@@ -181,7 +181,7 @@ export default {
|
|||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: 'value',
|
||||||
name: '元/m²',
|
name: unit,
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: 'rgba(0, 0, 0, 0.45)',
|
color: 'rgba(0, 0, 0, 0.45)',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|||||||
@@ -67,10 +67,10 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'naturalGas', name: '天然气', unit: '元/吨',route:'singleCombustible'},
|
{ key: 'naturalGas', name: '天然气', unit: '元/㎡',route:'singleCombustible'},
|
||||||
{ key: 'lng', name: 'LNG液化天然气', unit: '元/吨',route:'singleCombustible'},
|
{ key: 'lng', name: 'LNG液化天然气', unit: '元/㎡',route:'singleCombustible'},
|
||||||
{ key: 'heavyOil', name: '重油', unit: '元/吨',route:'singleCombustible'},
|
{ key: 'heavyOil', name: '重油', unit: '元/㎡',route:'singleCombustible'},
|
||||||
{ key: 'water', name: '水', unit: '元/吨',route:'singleCombustible'}
|
{ key: 'water', name: '水', unit: '元/m³',route:'singleCombustible'}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
sortedIndicators() {
|
sortedIndicators() {
|
||||||
const unitOrder = ['元/吨']
|
const unitOrder = ['元/㎡', '元/m³']
|
||||||
const unitRank = (u) => {
|
const unitRank = (u) => {
|
||||||
const idx = unitOrder.indexOf(u)
|
const idx = unitOrder.indexOf(u)
|
||||||
return idx === -1 ? 999 : idx
|
return idx === -1 ? 999 : idx
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'packaging', name: '包材', unit: '元/吨'},
|
{ key: 'packaging', name: '包材', unit: '元/㎡'},
|
||||||
{ key: 'spareParts', name: '备件、机物料', unit: '元/吨'},
|
{ key: 'spareParts', name: '备件、机物料', unit: '元/㎡'},
|
||||||
{ key: 'depreciation', name: '折旧', unit: '元/吨'},
|
{ key: 'depreciation', name: '折旧', unit: '元/㎡'},
|
||||||
{ key: 'other', name: '其他', unit: '元/吨'},
|
{ key: 'other', name: '其他', unit: '元/㎡'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
@@ -96,7 +96,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
sortedIndicators() {
|
sortedIndicators() {
|
||||||
const unitOrder = ['元/吨']
|
const unitOrder = ['元/㎡']
|
||||||
const unitRank = (u) => {
|
const unitRank = (u) => {
|
||||||
const idx = unitOrder.indexOf(u)
|
const idx = unitOrder.indexOf(u)
|
||||||
return idx === -1 ? 999 : idx
|
return idx === -1 ? 999 : idx
|
||||||
|
|||||||
@@ -0,0 +1,230 @@
|
|||||||
|
<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', // 如需区分可重命名为MaterialProductionStatus
|
||||||
|
components: { Container, operatingSingleBar },
|
||||||
|
props: {
|
||||||
|
// 对齐第二个组件:改为Object类型,支持月度/累计物料数据,格式统一
|
||||||
|
relatedData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
relatedMon: [], // 物料月度数据(数组格式,存储各物料项)
|
||||||
|
relatedTotal: [] // 物料累计数据(数组格式,存储各物料项)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dateData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null,
|
||||||
|
// 核心:当前激活的物料数据集(默认月度数据,与第二个组件逻辑一致)
|
||||||
|
activeData: this.relatedData.relatedMon || [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
indicatorDefs() {
|
||||||
|
return [
|
||||||
|
{ key: 'coatingLiquid', name: '镀膜液', unit: '元/㎡',route:'singleProcAuxMatCost'},
|
||||||
|
{ key: 'ink', name: '油墨', unit: '元/㎡',route:'singleProcAuxMatCost'},
|
||||||
|
{ key: 'glaze', name: '釉料', unit: '元/㎡',route:'singleProcAuxMatCost'},
|
||||||
|
{ key: 'wsyc', name: '无水乙醇', unit: '元/㎡',route:'singleProcAuxMatCost'},
|
||||||
|
{ key: 'ybc', name: '异丙醇', unit: '元/㎡',route:'singleProcAuxMatCost'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
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.name+'成本') || 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: {
|
||||||
|
// 对齐第二个组件:监听物料数据变化,同步更新激活数据集
|
||||||
|
relatedData: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.activeData = newVal.relatedMon || [];
|
||||||
|
},
|
||||||
|
immediate: true, // 组件挂载时立即执行
|
||||||
|
deep: true // 深度监听对象内部变化
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('物料组件挂载时的激活数据:', this.activeData);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(value) {
|
||||||
|
console.log('Tab 切换值:', 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 :5,
|
||||||
|
dateData: this.dateData
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 保留原有的可选弹窗方法(如需使用可保留)
|
||||||
|
openMaterialDetail(material) {
|
||||||
|
alert(`查看【${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; // 固定宽度,不被挤压(与第二个组件一致)
|
||||||
|
cursor: pointer; // 鼠标悬浮手型(保留原点击反馈)
|
||||||
|
transition: all 0.2s ease; // 过渡动画(保留原样式)
|
||||||
|
|
||||||
|
// 悬浮样式(保留原交互效果)
|
||||||
|
// &:hover {
|
||||||
|
// background: #F0F8FF;
|
||||||
|
// box-shadow: 0 2px 8px rgba(11, 88, 255, 0.1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 选中状态样式(可选,与第二个组件风格统一)
|
||||||
|
// &.active {
|
||||||
|
// background: #E8F4FF;
|
||||||
|
// border: 1px solid #0B58FF;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.title {
|
||||||
|
height: 18px;
|
||||||
|
font-family: PingFangSC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #000000;
|
||||||
|
line-height: 18px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .line {
|
||||||
|
// width: 280px; // 适配310px宽度,避免图表溢出(与第二个组件一致)
|
||||||
|
// height: 150px; // 图表高度与第二个组件统一
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏横向滚动条,与第二个组件样式完全统一 */
|
||||||
|
.topItem-container::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topItem-container {
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -65,14 +65,13 @@ export default {
|
|||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'silicaSand', name: '硅砂', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
{ key: 'silicaSand', name: '硅砂', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
// { key: 'seaSand', name: '海砂', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
|
||||||
{ key: 'sodaAsh', name: '纯碱', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
{ key: 'sodaAsh', name: '纯碱', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'dolomite', name: '白云石', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
{ key: 'dolomite', name: '白云石', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'limestone', name: '石灰石', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
{ key: 'limestone', name: '石灰石', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'compoundClarifyingAgent', name: '复合澄清剂', unit: '元/㎡', route: 'compositeClarifyingAgentCostAnalysis'},
|
{ key: 'compoundClarifyingAgent', name: '复合澄清剂', unit: '元/㎡', route: 'compositeClarifyingAgentCostAnalysis'},
|
||||||
{ key: 'ATH', name: '氢氧化铝', unit: '元/㎡', route: null},
|
{ key: 'ATH', name: '氢氧化铝', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'cosolvent', name: '助溶剂', unit: '元/㎡', route: null},
|
{ key: 'cosolvent', name: '助熔剂', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
{ key: 'brokenGlass', name: '碎玻璃', unit: '元/㎡', route: null},
|
{ key: 'brokenGlass', name: '碎玻璃', unit: '元/㎡', route: 'SIMFRMCostAnalysis'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: '' // 默认空字符串,保持原有配置
|
default: '' // 默认空字符串,保持原有配置
|
||||||
},
|
},
|
||||||
|
fuelName: { // 接收父组件传递的设备数据数组
|
||||||
|
type: String,
|
||||||
|
default: '' // 默认空字符串,保持原有配置
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -77,13 +81,23 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
if (this.fuelName === '重油') {
|
||||||
{ key: 'unitPrice', name: '采购单价', unit: '元/m³'},
|
return [
|
||||||
{ key: 'product', name: '产量', unit: '吨'},
|
{ key: 'unitPrice', name: '采购单价', unit: '元/吨'},
|
||||||
{ key: 'unitHao', name: '单耗', unit: '吨/m³'},
|
{ key: 'product', name: '产量', unit: '㎡'},
|
||||||
{ key: 'haoNum', name: '消耗量', unit: 'm³'},
|
{ key: 'unitHao', name: '单耗', unit: '千克/㎡'},
|
||||||
{ key: 'heatConsumption', name: '热耗', unit: 'kcal/kg'},
|
{ key: 'haoNum', name: '消耗量', unit: '吨'},
|
||||||
|
{ key: 'heatConsumption', name: '热耗', unit: '千卡/千克'},
|
||||||
]
|
]
|
||||||
|
}else{
|
||||||
|
return [
|
||||||
|
{ key: 'unitPrice', name: '采购单价', unit: '元/m³'},
|
||||||
|
{ key: 'product', name: '产量', unit: '㎡'},
|
||||||
|
{ key: 'unitHao', name: '单耗', unit: 'm³/㎡'},
|
||||||
|
{ key: 'haoNum', name: '消耗量', unit: 'm³'},
|
||||||
|
{ key: 'heatConsumption', name: '热耗', unit: '千卡/千克'},
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
const fallback = { targetValue: 0, value: 0, completed: 0, diffValue: 0 }
|
const fallback = { targetValue: 0, value: 0, completed: 0, diffValue: 0 }
|
||||||
@@ -99,7 +113,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
sortedIndicators() {
|
sortedIndicators() {
|
||||||
const unitOrder = ['元/㎡','吨','吨/m³','m³','kcal/kg']
|
const unitOrder = ['元/m³','㎡','m³/㎡','m³','千卡/千克']
|
||||||
const unitRank = (u) => {
|
const unitRank = (u) => {
|
||||||
const idx = unitOrder.indexOf(u)
|
const idx = unitOrder.indexOf(u)
|
||||||
return idx === -1 ? 999 : idx
|
return idx === -1 ? 999 : idx
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default {
|
|||||||
month: {
|
month: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -66,8 +66,8 @@ export default {
|
|||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'rawMaterialCost', name: '采购单价', unit: '元/吨'},
|
{ key: 'rawMaterialCost', name: '采购单价', unit: '元/吨'},
|
||||||
{ key: 'fuelCost', name: '产量', unit: '吨'},
|
{ key: 'fuelCost', name: '产量', unit: '㎡'},
|
||||||
{ key: 'electricityCost', name: '单耗', unit: '吨'},
|
{ key: 'electricityCost', name: '单耗', unit: '千克/㎡'},
|
||||||
{ key: 'laborCost', name: '消耗量', unit: '吨'},
|
{ key: 'laborCost', name: '消耗量', unit: '吨'},
|
||||||
{ key: 'laborCostDay', name: '日均消耗量', unit: '吨'}
|
{ key: 'laborCostDay', name: '日均消耗量', unit: '吨'}
|
||||||
]
|
]
|
||||||
@@ -86,7 +86,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
sortedIndicators() {
|
sortedIndicators() {
|
||||||
const unitOrder = ['元/吨', '吨']
|
const unitOrder = ['元/吨','㎡','千克/㎡', '吨']
|
||||||
const unitRank = (u) => {
|
const unitRank = (u) => {
|
||||||
const idx = unitOrder.indexOf(u)
|
const idx = unitOrder.indexOf(u)
|
||||||
return idx === -1 ? 999 : idx
|
return idx === -1 ? 999 : idx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="topItem-container" style="display: flex; gap: 8px;">
|
<div class="topItem-container" style="display: flex; gap: 8px;">
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
采购单价·元/度
|
采购单价·{{unitList[0]}}
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{unitPriceData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{unitPriceData.proportion}}%</span></span>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
产量·吨
|
产量.{{unitList[1]}}
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{productData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{productData.proportion}}%</span></span>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
单耗·度/吨
|
单耗·{{unitList[2]}}
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{unitHaoData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{unitHaoData.proportion}}%</span></span>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
消耗量·度
|
消耗量·{{unitList[3]}}
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{haoNumData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{haoNumData.proportion}}%</span></span>
|
||||||
@@ -90,6 +90,10 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
fuelName:{
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -101,6 +105,13 @@ export default {
|
|||||||
},
|
},
|
||||||
// 对齐第二个组件:添加计算属性,精准筛选各物料数据
|
// 对齐第二个组件:添加计算属性,精准筛选各物料数据
|
||||||
computed: {
|
computed: {
|
||||||
|
unitList() {
|
||||||
|
if (this.fuelName === '电') {
|
||||||
|
return ['元/度','㎡','度/㎡','度']
|
||||||
|
}else{
|
||||||
|
return ['元/m³','㎡','m³/㎡','m³']
|
||||||
|
}
|
||||||
|
},
|
||||||
// 1. 硅砂数据:从激活数据集中筛选,兜底值与第二个组件统一
|
// 1. 硅砂数据:从激活数据集中筛选,兜底值与第二个组件统一
|
||||||
unitPriceData() {
|
unitPriceData() {
|
||||||
return this.activeData.find(item => (item.name || '').includes('采购单价')) || {
|
return this.activeData.find(item => (item.name || '').includes('采购单价')) || {
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
indicatorDefs() {
|
indicatorDefs() {
|
||||||
return [
|
return [
|
||||||
{ key: 'unitPrice', name: '采购单价', unit: 'kg/㎡'},
|
{ key: 'unitPrice', name: '采购单价', unit: '元/千克'},
|
||||||
{ key: 'product', name: '产量', unit: '万㎡'},
|
{ key: 'product', name: '产量', unit: '㎡'},
|
||||||
{ key: 'unitHao', name: '单耗', unit: 'kg/m²'},
|
{ key: 'unitHao', name: '单耗', unit: '千克/㎡'},
|
||||||
{ key: 'haoNum', name: '消耗量', unit: 'kg'},
|
{ key: 'haoNum', name: '消耗量', unit: '千克'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
indicators() {
|
indicators() {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="topItem-container" style="display: flex; gap: 8px;">
|
<div class="topItem-container" style="display: flex; gap: 8px;">
|
||||||
<div class="dashboard left" @click="handleDashboardClick('电')" :detailData="dianData">
|
<div class="dashboard left" @click="handleDashboardClick('电')" :detailData="dianData">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
电·万元
|
电·元/㎡
|
||||||
</div>
|
</div>
|
||||||
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
<div style='font-size: 14px;text-align: right;padding-right: 5px;'>
|
||||||
<span>完成率:<span style='color: #0B58FF;'>{{dianData.proportion}}%</span></span>
|
<span>完成率:<span style='color: #0B58FF;'>{{dianData.proportion}}%</span></span>
|
||||||
|
|||||||
@@ -1,240 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div style="flex: 1">
|
|
||||||
<Container :name="title" icon="cockpitItemIcon" size="operatingRevenueBg" topSize="middle">
|
|
||||||
<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="handleDashboardClick(item.name)"
|
|
||||||
>
|
|
||||||
<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 './container.vue'
|
|
||||||
import operatingSingleBar from './operatingSingleBar.vue'
|
|
||||||
|
|
||||||
// import * as echarts from 'echarts'
|
|
||||||
// import rawItem from './raw-Item.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ProductionStatus',
|
|
||||||
components: { Container, operatingSingleBar },
|
|
||||||
props: {
|
|
||||||
// 接收父组件传递的 月度+累计 组合数据(原有配置保留,仅优化注释)
|
|
||||||
relatedData: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
dateData: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
factory: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 可选:动态标题(原有配置保留)
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
// 注释无效的activeData,保持数据简洁(样式不变)
|
|
||||||
// activeData: this.relatedData || []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
indicatorDefs() {
|
|
||||||
return [
|
|
||||||
{ key: 'coatingLiquid', name: '镀膜液', unit: '万元'},
|
|
||||||
{ key: 'ink', name: '油墨', unit: '万元'},
|
|
||||||
{ key: 'glaze', name: '釉料', unit: '万元'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
indicators() {
|
|
||||||
const fallback = { targetValue: 0, value: 0, completed: 0, diffValue: 0 }
|
|
||||||
const list = (Array.isArray(this.relatedData) ? this.relatedData : [])
|
|
||||||
|
|
||||||
return this.indicatorDefs.map(def => {
|
|
||||||
const data = list.find(item => item && item.name.includes(def.name)) || 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注释(若需恢复可直接启用,样式不变)
|
|
||||||
// watch: {
|
|
||||||
// relatedData: {
|
|
||||||
// handler(newVal) {
|
|
||||||
// this.activeData = newVal.relatedMon || [];
|
|
||||||
// },
|
|
||||||
// immediate: true,
|
|
||||||
// deep: true
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
mounted() {
|
|
||||||
// 优化打印日志,输出有效数据(样式不变)
|
|
||||||
console.log('组件挂载时的相关数据:', this.relatedData);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleDashboardClick(name) {
|
|
||||||
this.$router.push({
|
|
||||||
path: 'singleProcAuxMatCost',
|
|
||||||
query: {
|
|
||||||
name,
|
|
||||||
factory: this.$route.query.factory ? this.$route.query.factory : this.factory,
|
|
||||||
dateData: this.dateData
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
|
||||||
/* 样式100%保留不变,无任何增删改 */
|
|
||||||
/* 3. 核心:滚动容器样式(固定高度+溢出滚动+隐藏滚动条) */
|
|
||||||
.scroll-container {
|
|
||||||
/* 1. 固定容器高度:根据页面布局调整(示例300px,超出则滚动) */
|
|
||||||
max-height: 210px;
|
|
||||||
/* 2. 溢出滚动:内容超出高度时显示滚动功能 */
|
|
||||||
overflow-y: auto;
|
|
||||||
/* 3. 隐藏横向滚动条(防止设备名过长导致横向滚动) */
|
|
||||||
overflow-x: hidden;
|
|
||||||
/* 4. 内边距:与标题栏和容器边缘对齐 */
|
|
||||||
padding: 10px 0;
|
|
||||||
|
|
||||||
/* 5. 隐藏滚动条(兼容主流浏览器) */
|
|
||||||
/* Chrome/Safari */
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Firefox */
|
|
||||||
scrollbar-width: none;
|
|
||||||
/* IE/Edge */
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard {
|
|
||||||
width: 250px;
|
|
||||||
height: 205px;
|
|
||||||
background: #F9FCFF;
|
|
||||||
padding: 16px 0 0 10px;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
// width: 190px;
|
|
||||||
height: 18px;
|
|
||||||
font-family: PingFangSC, PingFang SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 18px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.number {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
// width: 190px;
|
|
||||||
height: 32px;
|
|
||||||
font-family: YouSheBiaoTiHei;
|
|
||||||
font-size: 32px;
|
|
||||||
color: #0B58FF;
|
|
||||||
line-height: 32px;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mom {
|
|
||||||
width: 120px;
|
|
||||||
height: 18px;
|
|
||||||
font-family: PingFangSC, PingFang SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 18px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-align: left;
|
|
||||||
font-style: normal;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// .line {
|
|
||||||
// width: 500px;
|
|
||||||
// height: 205px;
|
|
||||||
// background: #F9FCFF;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .leftTitle {
|
|
||||||
// .item {
|
|
||||||
// width: 67px;
|
|
||||||
// height: 180px;
|
|
||||||
// padding: 37px 23px;
|
|
||||||
// background: #F9FCFF;
|
|
||||||
// font-family: PingFangSC, PingFang SC;
|
|
||||||
// font-weight: 400;
|
|
||||||
// font-size: 18px;
|
|
||||||
// color: #000000;
|
|
||||||
// line-height: 25px;
|
|
||||||
// letter-spacing: 1px;
|
|
||||||
// // text-align: left;
|
|
||||||
// font-style: normal;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- <style>
|
|
||||||
/* 全局 tooltip 样式(不使用 scoped,确保生效) */
|
|
||||||
.production-status-chart-tooltip {
|
|
||||||
background: #0a2b4f77 !important;
|
|
||||||
border: none !important;
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.production-status-chart-tooltip * {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
</style> -->
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
v-for="item in sortedIndicators"
|
v-for="item in sortedIndicators"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
class="dashboard"
|
class="dashboard"
|
||||||
@click="handleDashboardClick(item.name)"
|
@click="item.route && handleDashboardClick(item.name,item.route)"
|
||||||
>
|
>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.name }}·{{ item.unit }}
|
{{ item.name }}·{{ item.unit }}
|
||||||
@@ -112,16 +112,17 @@ export default {
|
|||||||
console.log('组件挂载时的相关数据:', this.relatedData);
|
console.log('组件挂载时的相关数据:', this.relatedData);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleDashboardClick(name) {
|
handleDashboardClick(material, path) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: 'singleProcMfgOverheadCost',
|
path: path,
|
||||||
query: {
|
query: {
|
||||||
name,
|
name: material,
|
||||||
factory: this.$route.query.factory ? this.$route.query.factory : this.factory,
|
month: this.month,
|
||||||
|
factory: this.$route.query.factory ? this.$route.query.factory :5,
|
||||||
dateData: this.dateData
|
dateData: this.dateData
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ export default {
|
|||||||
// index: this.index,
|
// index: this.index,
|
||||||
// sort: 1,
|
// sort: 1,
|
||||||
paramName: '产销率',
|
paramName: '产销率',
|
||||||
paramList: ['产量(深加工)', '销量'],
|
paramList: ['加工产量', '销量'],
|
||||||
baseId: this.factory,
|
baseId: this.factory,
|
||||||
// baseId: Number(this.factory),
|
// baseId: Number(this.factory),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default {
|
|||||||
profitOptions:[
|
profitOptions:[
|
||||||
{name:'产销率',unit:'%'},
|
{name:'产销率',unit:'%'},
|
||||||
{name:'销量',unit:'万㎡'},
|
{name:'销量',unit:'万㎡'},
|
||||||
{name:'产量(深加工)',unit:'㎡'},
|
{name:'加工产量',unit:'㎡'},
|
||||||
],
|
],
|
||||||
unit:'%',
|
unit:'%',
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user