应收账款等4个新增页面
This commit is contained in:
@@ -51,16 +51,14 @@ export default {
|
||||
|
||||
// 遍历传入的 trendData 数组(响应式依赖,变化时自动重算)
|
||||
this.trendData.forEach((item) => {
|
||||
// 1. 格式化时间并推入时间数组
|
||||
const yearMonth = this.formatTimeToYearMonth(item.time);
|
||||
timeArr.push(yearMonth);
|
||||
timeArr.push(item.title);
|
||||
|
||||
// 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);
|
||||
valueArr.push(item.real ?? 0);
|
||||
diffValueArr.push(item.diff ?? 0);
|
||||
targetValueArr.push(item.budget ?? 0);
|
||||
proportionArr.push(item.rate ?? 0);
|
||||
completedArr.push(item.rate && item.rate>=100 ? 1 : 0);
|
||||
});
|
||||
|
||||
// 组装并返回格式化后的数据(结构与原一致)
|
||||
@@ -81,15 +79,6 @@ export default {
|
||||
* @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)
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div class="dropdown-options" v-if="isDropdownShow">
|
||||
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
|
||||
@click.stop="selectProfit(item)">
|
||||
{{ item }}
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,20 +60,19 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
isDropdownShow: false,
|
||||
selectedProfit: '原片电费', // 选中的名称,初始为null
|
||||
profitOptions: [
|
||||
'原片电费',
|
||||
'加工电费',
|
||||
'外围电费',
|
||||
'发电量',
|
||||
'日均发电量'
|
||||
]
|
||||
selectedProfit: '总电费', // 选中的名称,初始为null
|
||||
profitOptions:[
|
||||
{name:'总电费',unit:'万元'},
|
||||
{name:'原片电费',unit:'万元'},
|
||||
{name:'加工电费',unit:'万元'},
|
||||
{name:'外围电费',unit:'万元'},
|
||||
{name:'发电量',unit:'度'},
|
||||
{name:'日均发电量',unit:'度'}
|
||||
],
|
||||
unit:'万元',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// profitOptions() {
|
||||
// return this.categoryData.map(item => item.name) || [];
|
||||
// },
|
||||
currentDataSource() {
|
||||
return this.chartData
|
||||
},
|
||||
@@ -89,6 +88,7 @@ export default {
|
||||
|
||||
const salesData = {
|
||||
allPlaceNames: this.locations,
|
||||
unit: this.unit,
|
||||
series: [
|
||||
// 1. 完成率(折线图)
|
||||
{
|
||||
@@ -247,9 +247,10 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
selectProfit(item) {
|
||||
this.selectedProfit = item;
|
||||
this.selectedProfit = item.name;
|
||||
this.unit = item.unit;
|
||||
this.isDropdownShow = false;
|
||||
this.$emit('handleGetItemData', item)
|
||||
this.$emit('handleGetItemData', item.name)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -123,6 +123,7 @@ export default {
|
||||
const data = this.currentDataSource;
|
||||
const salesData = {
|
||||
allPlaceNames: this.locations,
|
||||
unit:'万元',
|
||||
series: [
|
||||
// 完成率(折线图)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
|
||||
// 路由跳转时携带序号(或名称+序号)
|
||||
this.$router.push({
|
||||
path: 'totalProfitBase',
|
||||
path: 'electricityCostAnalysisBase',
|
||||
query: { // 使用query传递参数(推荐),也可使用params
|
||||
// baseName: itemName,
|
||||
factory: baseIndex,
|
||||
@@ -119,7 +119,7 @@ export default {
|
||||
return; // 实例未初始化则返回
|
||||
}
|
||||
|
||||
const { allPlaceNames, series } = this.chartData || {};
|
||||
const { allPlaceNames,unit, series } = this.chartData || {};
|
||||
const xData = allPlaceNames || [];
|
||||
const chartSeries = series || [];
|
||||
|
||||
@@ -166,7 +166,7 @@ export default {
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '万元',
|
||||
name: unit,
|
||||
nameTextStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.45)',
|
||||
fontSize: 12,
|
||||
|
||||
@@ -59,9 +59,9 @@ export default {
|
||||
name: "ProductionStatus",
|
||||
components: { Container, operatingBar, operatingTopBar },
|
||||
props: {
|
||||
monData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
monthData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
dateData: {
|
||||
type: Object,
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
monData: {
|
||||
monthData: {
|
||||
handler() {
|
||||
this.processChartData();
|
||||
},
|
||||
@@ -104,52 +104,48 @@ export default {
|
||||
/**
|
||||
* 核心方法:按levelId匹配地名生成locations
|
||||
*/
|
||||
getRateFlag(rate, real, target) {
|
||||
if (isNaN(rate) || rate === null || rate === undefined) return 0;
|
||||
|
||||
// 1. 完成率 >= 100 => 达标
|
||||
if (rate >= 100) return 1;
|
||||
|
||||
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
|
||||
// if (rate === 0 && target === 0) return 1;
|
||||
|
||||
// 其他情况 => 未达标
|
||||
return 0;
|
||||
},
|
||||
processChartData() {
|
||||
// 初始化空数据结构
|
||||
const initTopBarData = {
|
||||
locations: [], diff: [], targets: [], reals: [], rate: [], flags: []
|
||||
};
|
||||
const initBarData = { locations: [], diff: [], targets: [], reals: [], rate: [], flags: [] };
|
||||
|
||||
if (!Array.isArray(this.monData) || this.monData.length === 0) {
|
||||
this.chartData = { topBarData: initTopBarData, barData: initBarData };
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 处理levelId=1的整合数据(逻辑不变)
|
||||
const level1Data = this.monData.filter(item => item.levelId === 1);
|
||||
const level1Data = this.monthData.group;
|
||||
if (!level1Data) return;
|
||||
const topBarData = { ...initTopBarData };
|
||||
level1Data.forEach(item => {
|
||||
if (!item.name) return;
|
||||
topBarData.locations = ["凯盛新能"]; // levelId=1固定为凯盛新能
|
||||
topBarData.diff.push(item.diffValue || 0);
|
||||
topBarData.targets.push(item.targetValue || 0);
|
||||
topBarData.reals.push(item.value || 0);
|
||||
topBarData.rate.push(item.proportion || 0);
|
||||
topBarData.flags.push(item.completed ? 1 : 0);
|
||||
});
|
||||
|
||||
topBarData.locations = ["凯盛新能"];
|
||||
topBarData.diff.push(level1Data.diff || 0);
|
||||
|
||||
topBarData.targets.push(level1Data.target || 0);
|
||||
topBarData.reals.push(level1Data.real || 0);
|
||||
topBarData.rate.push(level1Data.rate || 0);
|
||||
topBarData.flags.push(this.getRateFlag(level1Data.rate, level1Data.real, level1Data.target));
|
||||
// 2. 处理levelId≠1的整合数据(核心:levelId匹配地名)
|
||||
const barData = { ...initBarData };
|
||||
// 筛选有效数据:levelId≠1 且 levelId在baseIndexToNameMap中
|
||||
const validOtherData = this.monData.filter(item => {
|
||||
return item.levelId !== 1 && baseIndexToNameMap.hasOwnProperty(item.levelId);
|
||||
});
|
||||
const validOtherData = this.monthData.factory
|
||||
|
||||
// 遍历有效数据,填充locations(levelId→地名)
|
||||
validOtherData.forEach(item => {
|
||||
// 根据levelId(序号)从映射表获取对应地名
|
||||
const baseName = baseIndexToNameMap[item.levelId];
|
||||
if (baseName) { // 确保地名和原始名称有效
|
||||
// barData.names.push(item.name); // 保留monData中的原始名称
|
||||
barData.locations.push(baseName); // locations=levelId对应的地名(如levelId=7→宜兴)
|
||||
barData.diff.push(item.diffValue || 0);
|
||||
barData.targets.push(item.targetValue || 0);
|
||||
barData.reals.push(item.value || 0);
|
||||
barData.rate.push(item.proportion || 0);
|
||||
barData.flags.push(item.completed ? 1 : 0);
|
||||
// barData.baseIndexes.push(Number(item.levelId) || 0); // 序号转数字
|
||||
}
|
||||
barData.locations.push(item.title); // locations=levelId对应的地名(如levelId=7→宜兴)
|
||||
barData.diff.push(item.diff || 0);
|
||||
barData.targets.push(item.target || 0);
|
||||
barData.reals.push(item.real || 0);
|
||||
barData.rate.push(item.rate || 0);
|
||||
barData.flags.push(this.getRateFlag(item.rate, item.real, item.target));
|
||||
});
|
||||
|
||||
// 3. 更新chartData
|
||||
|
||||
@@ -59,9 +59,9 @@ export default {
|
||||
name: "ProductionStatus",
|
||||
components: { Container, operatingBar, operatingTopBar },
|
||||
props: {
|
||||
totalData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
ytdData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
dateData: {
|
||||
type: Object,
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
totalData: {
|
||||
ytdData: {
|
||||
handler() {
|
||||
this.processChartData();
|
||||
},
|
||||
@@ -104,6 +104,18 @@ export default {
|
||||
/**
|
||||
* 核心方法:按levelId匹配地名生成locations
|
||||
*/
|
||||
getRateFlag(rate, real, target) {
|
||||
if (isNaN(rate) || rate === null || rate === undefined) return 0;
|
||||
|
||||
// 1. 完成率 >= 100 => 达标
|
||||
if (rate >= 100) return 1;
|
||||
|
||||
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
|
||||
// if (rate === 0 && target === 0) return 1;
|
||||
|
||||
// 其他情况 => 未达标
|
||||
return 0;
|
||||
},
|
||||
processChartData() {
|
||||
// 初始化空数据结构
|
||||
const initTopBarData = {
|
||||
@@ -111,45 +123,30 @@ export default {
|
||||
};
|
||||
const initBarData = { locations: [], diff: [], targets: [], reals: [], rate: [], flags: [] };
|
||||
|
||||
if (!Array.isArray(this.totalData) || this.totalData.length === 0) {
|
||||
this.chartData = { topBarData: initTopBarData, barData: initBarData };
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 处理levelId=1的整合数据(逻辑不变)
|
||||
const level1Data = this.totalData.filter(item => item.levelId === 1);
|
||||
const level1Data = this.ytdData.group;
|
||||
if (!level1Data) return;
|
||||
const topBarData = { ...initTopBarData };
|
||||
level1Data.forEach(item => {
|
||||
if (!item.name) return;
|
||||
topBarData.locations = ["凯盛新能"]; // levelId=1固定为凯盛新能
|
||||
topBarData.diff.push(item.diffValue || 0);
|
||||
topBarData.targets.push(item.targetValue || 0);
|
||||
topBarData.reals.push(item.value || 0);
|
||||
topBarData.rate.push(item.proportion || 0);
|
||||
topBarData.flags.push(item.completed ? 1 : 0);
|
||||
});
|
||||
topBarData.locations = ["凯盛新能"];
|
||||
topBarData.diff.push(level1Data.diff || 0);
|
||||
topBarData.targets.push(level1Data.target || 0);
|
||||
topBarData.reals.push(level1Data.real || 0);
|
||||
topBarData.rate.push(level1Data.rate || 0);
|
||||
topBarData.flags.push(this.getRateFlag(level1Data.rate, level1Data.real, level1Data.target));
|
||||
|
||||
// 2. 处理levelId≠1的整合数据(核心:levelId匹配地名)
|
||||
const barData = { ...initBarData };
|
||||
// 筛选有效数据:levelId≠1 且 levelId在baseIndexToNameMap中
|
||||
const validOtherData = this.totalData.filter(item => {
|
||||
return item.levelId !== 1 && baseIndexToNameMap.hasOwnProperty(item.levelId);
|
||||
});
|
||||
const validOtherData = this.ytdData.factory
|
||||
|
||||
// 遍历有效数据,填充locations(levelId→地名)
|
||||
validOtherData.forEach(item => {
|
||||
// 根据levelId(序号)从映射表获取对应地名
|
||||
const baseName = baseIndexToNameMap[item.levelId];
|
||||
if (baseName) { // 确保地名和原始名称有效
|
||||
// barData.names.push(item.name); // 保留monData中的原始名称
|
||||
barData.locations.push(baseName); // locations=levelId对应的地名(如levelId=7→宜兴)
|
||||
barData.diff.push(item.diffValue || 0);
|
||||
barData.targets.push(item.targetValue || 0);
|
||||
barData.reals.push(item.value || 0);
|
||||
barData.rate.push(item.proportion || 0);
|
||||
barData.flags.push(item.completed ? 1 : 0);
|
||||
// barData.baseIndexes.push(Number(item.levelId) || 0); // 序号转数字
|
||||
}
|
||||
barData.locations.push(item.title); // locations=levelId对应的地名(如levelId=7→宜兴)
|
||||
barData.diff.push(item.diff || 0);
|
||||
barData.targets.push(item.target || 0);
|
||||
barData.reals.push(item.real || 0);
|
||||
barData.rate.push(item.rate || 0);
|
||||
barData.flags.push(this.getRateFlag(item.rate, item.real, item.target));
|
||||
});
|
||||
|
||||
// 3. 更新chartData
|
||||
|
||||
@@ -22,13 +22,13 @@ export default {
|
||||
chartD() {
|
||||
// 背景图片路径(若不需要可注释)
|
||||
// const bgImageUrl = require('@/assets/img/labelBg.png');
|
||||
const rate = this.detailData?.proportion? Number(this.detailData?.proportion) : 0
|
||||
const diff = this.detailData?.diffValue || 0
|
||||
const rate = this.detailData?.rate? Number(this.detailData?.rate) : 0
|
||||
const diff = this.detailData?.diff || 0
|
||||
console.log('diff', diff);
|
||||
|
||||
const seriesData = [
|
||||
{
|
||||
value: this.detailData?.targetValue || 0,
|
||||
value: this.detailData?.budget || 0,
|
||||
flag: 1, // 实际项:达标(绿色)
|
||||
label: {
|
||||
show: true,
|
||||
@@ -49,8 +49,8 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
value: this.detailData?.value || 0,
|
||||
flag: this.detailData?.completed, // 实际项:达标(绿色)
|
||||
value: this.detailData?.real || 0,
|
||||
flag: this.detailData?.rate>=100, // 实际项:达标(绿色)
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
{{ 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>
|
||||
<span>完成率:<span style='color: #0B58FF;'>{{item.data.rate}}%</span></span>
|
||||
<span style='display: inline-block;margin-left: 10px;'>差值:<span :style="{color:item.data.rate>=100?'#30B590':'#FF9423'}" >{{item.data.diff}}</span></span>
|
||||
</div>
|
||||
<operatingSingleBar :detailData="item.data"></operatingSingleBar>
|
||||
</div>
|
||||
@@ -61,7 +61,8 @@ export default {
|
||||
return {
|
||||
chart: null,
|
||||
// 核心:当前激活的数据集(月度/累计),默认初始化月度数据
|
||||
activeData: this.relatedData.relatedMon || []
|
||||
activeData: this.relatedData.relatedMon || [],
|
||||
currentTab: 'month'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -79,11 +80,11 @@ export default {
|
||||
const list = (Array.isArray(this.activeData) ? this.activeData : [])
|
||||
|
||||
return this.indicatorDefs.map(def => {
|
||||
const data = list.find(item => item && item.name === def.name) || fallback
|
||||
const data = list.find(item => item && item.title === def.name) || fallback
|
||||
return {
|
||||
...def,
|
||||
data,
|
||||
sortValue: Number((data && data.value) ?? 0)
|
||||
sortValue: Number((data && data.real) ?? 0)
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -107,7 +108,12 @@ export default {
|
||||
// 可选:监听 relatedData 初始变化(若父组件异步传递数据,确保 activeData 同步更新)
|
||||
relatedData: {
|
||||
handler(newVal) {
|
||||
this.activeData = newVal.relatedMon || [];
|
||||
if(this.currentTab === 'month') {
|
||||
this.activeData = newVal.relatedMon || [];
|
||||
}else{
|
||||
this.activeData = newVal.relatedTotal || [];
|
||||
}
|
||||
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
@@ -132,6 +138,7 @@ export default {
|
||||
*/
|
||||
handleChange(value) {
|
||||
console.log('Tab 切换值:', value);
|
||||
this.currentTab = value;
|
||||
// 根据 Tab 值更新当前激活的数据集
|
||||
if (value === 'month') {
|
||||
// 切换为月度数据
|
||||
|
||||
Reference in New Issue
Block a user