运营驾驶舱对接

This commit is contained in:
2026-03-31 15:13:13 +08:00
parent 05fe91618c
commit 161d6a1bdf
44 changed files with 625 additions and 522 deletions

View File

@@ -15,6 +15,8 @@ VUE_APP_BASE_API = 'http://172.16.20.218:7070'
# VUE_APP_BASE_API = 'http://172.16.19.232:7070'
# 测试
# VUE_APP_BASE_API = 'http://192.168.0.35:8080'
# 闫阳
# VUE_APP_BASE_API = 'http://172.16.19.131:7070'
# 路由懒加载

View File

@@ -346,3 +346,38 @@ export function getDictListData(query) {
params: query,
});
}
export function getAccountsReceivableData(data) {
return request({
url: "/lb/accounts-receivable/getGroupData",
method: "post",
data: data,
});
}
export function getInventoryData(data) {
return request({
url: "/lb/inventory/getGroupData",
method: "post",
data: data,
});
}
export function getElectricityCostAnalysisData(data) {
return request({
url: "/lb/electricity-cost-analysis/getGroupData",
method: "post",
data: data,
});
}
export function getDepreciationAnalysisData(data) {
return request({
url: "/lb/depreciation-analysis/getGroupData",
method: "post",
data: data,
});
}
export function getElectricityCostAnalysisFData(data) {
return request({
url: "/lb/electricity-cost-analysis/getFactoryData",
method: "post",
data: data,
});
}

View File

@@ -96,6 +96,7 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
"/salesVolumeAnalysis",
'/procurementGainAnalysis',
'/fullCostAnalysis',
'/electricityCostAnalysis',
// '/expenseAnalysis',
"/cost", // cost 根路由
"/cost/profitImpactAnalysis", // cost 子菜单(完整路径)

View File

@@ -39,7 +39,7 @@ import { mapState } from "vuex";
import operatingLineChart from "../accountsReceivableComponents/operatingLineChart";
import operatingLineChartCumulative from "../accountsReceivableComponents/operatingLineChartCumulative.vue";
import { getSalesRevenueGroupData } from '@/api/cockpit'
import { getAccountsReceivableData } from '@/api/cockpit'
export default {
name: "AccountsReceivable",
components: {
@@ -59,6 +59,7 @@ export default {
selectDate:{},
monthData: {},
ytdData:{},
dateData: {},
};
},
@@ -132,15 +133,14 @@ export default {
// this.getData()
// },
getData() {
getSalesRevenueGroupData({
getAccountsReceivableData({
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
sort: this.sort,
index: undefined,
factory: undefined
// timeDim: obj.mode
}).then((res) => {
console.log(res);
console.log('res==============================',res);
this.monthData= res.data.month
this.ytdData = res.data.ytd

View File

@@ -87,11 +87,14 @@ export default {
// 如果没有 X 轴数据,则返回空数组
if (xAxisKeys.length === 0) {
return [];
return {};
}
let obj = {
unit:'万元',
series:[]
}
// 遍历配置项,生成 series
return Object.keys(this.chartConfig).map(key => {
obj.series = Object.keys(this.chartConfig).map(key => {
const config = this.chartConfig[key];
// 确保数据顺序和 X 轴一致
const dataValues = xAxisKeys.map(date => lineData[key] ? lineData[key].real[date] : 0);
@@ -114,6 +117,7 @@ export default {
data: dataValues
};
});
return obj;
}
},
methods: {}

View File

@@ -11,8 +11,8 @@
@mouseleave.native="autoScroll(false)" v-loading="isLoading"
:header-cell-style="{ background: 'rgba(218, 226, 237, 1)', color: 'rgba(0, 0, 0, .6)',padding:'3px 2px'}" :row-style="setRowStyle"
:data="renderData" border style="width: 100%; background: transparent">
<el-table-column v-if="page && limit && showIndex" prop="_pageIndex" label="序号" :width="70" align="center" />
<el-table-column v-for="item in renderTableHeadList" :key="item.prop" :show-overflow-tooltip="showOverflow"
<el-table-column v-if="page && limit && showIndex" prop="_pageIndex" label="序号" :width="60" align="center" />
<el-table-column v-for="item in renderTableHeadList" :key="item.prop" :show-overflow-tooltip="showOverflow" :width='item.width || ""'
v-bind="item">
<template slot-scope="scope">

View File

@@ -90,7 +90,7 @@
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
<el-button @click="cancelBtn"> </el-button>
</div>
</el-dialog>
</Container>
@@ -512,6 +512,10 @@ export default {
this.$message.error('上传失败!')
}
},
cancelBtn() {
this.upload.open = false
this.$refs.upload.clearFiles();
}
}
}
</script>

View File

@@ -57,10 +57,10 @@ export default {
activeButton: 0,
// 定义按钮与 line 数据中 key 的映射关系
buttonToDataKey: [
'单价',
'净价',
'销量',
'双镀销量' // 注意:数据中的 key 是“双镀面板”,按钮显示的是“双镀产品”
{name:'单价',unit:'元/㎡'},
{name:'净价',unit:'元/㎡'},
{name:'销量',unit:'万㎡'},
{name:'双镀销量',unit:'万㎡'}
]
};
},
@@ -69,7 +69,7 @@ export default {
xAxisData() {
const lineData = this.line || {};
// 获取当前激活按钮对应的数据
const currentDataKey = this.buttonToDataKey[this.activeButton];
const currentDataKey = this.buttonToDataKey[this.activeButton].name;
const currentIndicatorData = lineData[currentDataKey];
// 使用 'target' 的键作为 x 轴,如果 'target' 不存在,则使用 'real' 的键
@@ -83,19 +83,20 @@ export default {
// 根据激活按钮动态返回对应 series 数据
currentSeries() {
const lineData = this.line || {};
const currentDataKey = this.buttonToDataKey[this.activeButton];
const currentDataKey = this.buttonToDataKey[this.activeButton].name;
const chartData = lineData[currentDataKey];
if (!chartData) {
return [];
return {};
}
// 提取目标和实际数据的值,并确保顺序与 X 轴一致
const xAxisKeys = this.xAxisData;
const targetDataValues = xAxisKeys.map(date => chartData.target ? chartData.target[date] : 0);
const realDataValues = xAxisKeys.map(date => chartData.real ? chartData.real[date] : 0);
return [
let obj = {
unit:this.buttonToDataKey[this.activeButton].unit,
series:[
{
name: '预算',
type: 'line',
@@ -136,7 +137,8 @@ export default {
},
data: realDataValues
}
];
]}
return obj;
}
}
};

View File

@@ -6,8 +6,8 @@
<coreBottomLeftItem :dateData="dateData" :purchase="purchase">
</coreBottomLeftItem>
<div class="content-right" style="background: #F9FCFF;padding: 15px 12px;">
<base-table style="height: 180px;width: 260px;" :page="1" :limit="10" :show-index="true" :beilv="1"
:tableConfig="tableProps" :table-data="maintenanceTasks" />
<base-table style="height: 221px;width: 260px;" :page="1" :limit="10" :show-index="true" :beilv="1"
:tableConfig="tableProps" :table-data="maintenanceTasks" :maxHeight='220'/>
</div>
</div>
</Container>
@@ -43,20 +43,13 @@ export default {
maintenanceTasks: [
{ id: 1, name: '纯碱', number: '1313,252', },
{ id: 2, name: '硅砂', number: '14,252', },
{ id: 2, name: '白云石', number: '23,252', },
{ id: 2, name: '石灰石', number: '34,421', },
{ id: 2, name: '氧化铝', number: '1,251.34', },
{ id: 2, name: '氢氧化铝', number: '14,252', },
// { id: 2, eqName: '螺杆挤出', taskName: '例行维护', },
// { id: 2, eqName: '螺杆挤出', taskName: '例行维护', },
// { id: 2, eqName: '螺杆挤出', taskName: '例行维护', },
// { id: 2, eqName: '螺杆挤出', taskName: '例行维护', },
// { id: 2, eqName: '螺杆挤出', taskName: '例行维护', },
{ id: 3, name: '白云石', number: '23,252', },
{ id: 4, name: '石灰石', number: '34,421', },
{ id: 5, name: '氧化铝', number: '1,251.34', },
{ id: 6, name: '氢氧化铝', number: '14,252', }
],
tableProps: [
// { prop: 'id', label: '序号', width: 50, align: 'center' },
{ prop: 'name', label: '物料', align: 'left' },
{ prop: 'number', label: '库存/吨', align: 'left' },
]
@@ -102,7 +95,7 @@ export default {
return {
id: index + 1, // id 从 1 开始自增
name: name, // 物料名称
number: String(value) // 将数值转换为字符串,以匹配 "number" 字段
number: value ? String(value) : '-' // 将数值转换为字符串,以匹配 "number" 字段
};
});
}

View File

@@ -1,5 +1,5 @@
<template>
<div ref="cockpitEffChip" id="coreLineChart" style="height: 219px; width: 100%;"></div>
<div ref="cockpitEffChip" id="coreLineChart" style="height: 184px; width: 100%;"></div>
</template>
<script>
@@ -11,8 +11,8 @@ export default {
// 接收父组件传递的 series 数据
props: {
chartSeries: {
type: Array,
default: () => [] // 默认空数组,避免报错
type: Object,
default: () => {{}} // 默认空数组,避免报错
},
xAxisData: {
type: Array,
@@ -68,7 +68,6 @@ export default {
// 单独提取更新图表的方法,方便复用
updateChart() {
if (!this.myChart) return;
console.log('this.chartSeries', this.chartSeries,this.xAxisData);
const option = {
tooltip: {
@@ -78,7 +77,7 @@ export default {
label: { backgroundColor: '#6a7985' }
}
},
grid: { top: 35, bottom: 3, right: 15, left: 10, containLabel: true},
grid: { top: 35, bottom: 3, right: 15, left: 15, containLabel: true},
xAxis: [
{
type: 'category',
@@ -108,19 +107,14 @@ export default {
}
],
yAxis: {
// type: 'value',
name: '元/㎡',
// nameLocation:'center',
name: this.chartSeries.unit,
nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' },
// min: () => 0,
// max: (value) => Math.ceil(value.max),
axisTick: { show: false },
axisLabel: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 12 },
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { show: true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }
},
series: this.chartSeries // 使用父组件传递的 series 数据
series: this.chartSeries.series // 使用父组件传递的 series 数据
};
this.myChart.setOption(option, true); // 第二个参数 true 表示替换现有配置

View File

@@ -24,7 +24,7 @@
<div class="right">
<!-- 环比额计算差值并动态绑定颜色 -->
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
{{ item.hbe }}
{{ item.thbe }}
</div>
<div class="title">环比额</div>
</div>
@@ -101,12 +101,12 @@ export default {
// 遍历映射关系,转换数据
return costMapping.map(mappingItem => {
// 获取对应费用类型的数据,若不存在则使用默认值
const costData = rawData[mappingItem.key] || { last: 0, this: 0, hbe: 0 };
const costData = rawData[mappingItem.key] || { last: 0, this: 0, thbe: 0 };
return {
name: mappingItem.name,
path: mappingItem.path,
hbe: costData.hbe,
thbe: costData.thbe,
targetValue: costData.last, // 上月值
currentValue: costData.this // 本月值
};

View File

@@ -2,10 +2,10 @@
<div style="flex: 1">
<!-- 传入点击切换的状态到Container组件 -->
<Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch" @tabChange='tabChange'>
<div class="bottom-left-content" style="display: flex;gap: 9px;padding: 14px 16px;flex-direction: column;">
<div class="bottom-left-content" style="display: flex;gap: 0px;padding: 14px 16px;flex-direction: column;">
<!-- 根据activeTab状态切换显示采购/存货内容 -->
<template v-if="activeTab === 'purchase'">
<!-- 采购重点指标应的内容 -->
<!-- 财务重点指标应的内容 -->
<coreBottomLeftItem :dateData="dateData" :finance="financeData"></coreBottomLeftItem>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
@@ -13,10 +13,10 @@
</div>
</template>
<template v-else-if="activeTab === 'inventory'">
<!-- 存货重点指标对应的内容 -->
<!-- 费用重点指标对应的内容 -->
<costItem :dateData="dateData" :cost="costData" :currentTap='currentTap'></costItem>
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
style="display: flex; width: 100%;margin-top: 4px;background-color: rgba(249, 252, 255, 1);">
<CostsBottomBar :line="cost.line" :dateData="dateData">
</CostsBottomBar>
</div>

View File

@@ -27,11 +27,21 @@
<div class="item-button" :class="{ active: activeButton === 3 }" @click="activeButton = 3">
毛利率
</div>
<div class="button-line lineFour" v-if="activeButton !== 3 && activeButton !== 4"></div>
<div class="item-button" :class="{ active: activeButton === 4 }" @click="activeButton = 4">
应收账款
</div>
<div class="button-line lineFive" v-if="activeButton !== 4 && activeButton !== 5"></div>
<div class="item-button" :class="{ active: activeButton === 5 }" @click="activeButton = 5">
存货
</div>
</div>
<div class="lineBottom" style="height: 210px; width: 100%">
</div>
<div class="lineBottom" style="height: 184px; width: 100%">
<!-- 传递当前选中的 series 数据和 xAxis 数据给子组件 -->
<coreLineChart style="height: 210px; width: 680px" :chart-series="currentSeries" :x-axis-data="xAxisData"
<coreLineChart style="height: 184px; width: 680px" :chart-series="currentSeries" :x-axis-data="xAxisData"
:dateData="dateData" />
</div>
</div>
@@ -59,10 +69,12 @@ export default {
activeButton: 0, // 初始激活第一个按钮索引0
// 定义按钮与 line 数据中 key 的映射关系
buttonToDataKey: [
'营业收入',
'经营性利润', // 注意:数据中的 key 是“经营收入”,按钮显示的是“经营性利润”
'利润总额',
'毛利率'
{name:'营业收入',unit:'万元'},
{name:'经营性利润',unit:'万元'},
{name:'利润总额',unit:'万元'},
{name:'毛利率',unit:'%'},
{name:'应收账款',unit:'万元'},
{name:'存货',unit:'万元'}
]
};
},
@@ -70,20 +82,19 @@ export default {
// 根据当前激活的按钮,动态生成对应的 series 数据
currentSeries() {
const dataKey = this.buttonToDataKey[this.activeButton];
const dataKey = this.buttonToDataKey[this.activeButton].name;
const chartData = this.line[dataKey];
console.log('this.line[dataKey', this.buttonToDataKey[this.activeButton]);
if (!chartData) {
return [];
return {};
}
// 提取目标和实际数据的值
const targetDataValues = Object.values(chartData.target || {});
const realDataValues = Object.values(chartData.real || {});
console.log('realDataValues', realDataValues);
return [
let obj = {
unit: this.buttonToDataKey[this.activeButton].unit,
series:[
{
name: '预算',
type: 'line',
@@ -116,11 +127,12 @@ export default {
},
data: realDataValues
}
];
]}
return obj;
},
// 提取 x 轴数据(日期)
xAxisData() {
const dataKey = this.buttonToDataKey[this.activeButton];
const dataKey = this.buttonToDataKey[this.activeButton].name;
const chartData = this.line[dataKey];
// 使用 'target' 的键作为 x 轴,如果 'target' 不存在,则使用 'real' 的键
if (chartData && chartData.target) {
@@ -205,7 +217,7 @@ export default {
display: flex;
position: relative;
gap: 2px;
width: 252px;
width: 350px;
align-items: center;
height: 24px;
background: #ecf4fe;
@@ -219,18 +231,27 @@ export default {
}
.lineOne {
top: 5px;
top: 6px;
left: 59px;
}
.lineTwo {
top: 5px;
left: 134px;
top: 6px;
left: 131px;
}
.lineThree {
top: 5px;
left: 193px;
top: 6px;
left: 190px;
}
.lineFour {
top: 6px;
left: 238px;
}
.lineFive {
top: 6px;
left: 302px;
}
.item-button {

View File

@@ -1,7 +1,7 @@
<template>
<!-- 显示累计值并绑定颜色类 -->
<div class="accumulated-value" :class="injectData.status">
{{ injectData.accumulated }} <!-- 显示累计数据 -->
{{ injectData.total }} <!-- 显示累计数据 -->
</div>
</template>

View File

@@ -15,10 +15,6 @@ export default {
lineData: {
type: Object,
default: () => ({}),
},
xData: {
type: Array,
default: () => []
}
},
mounted() {
@@ -32,7 +28,6 @@ export default {
// 深度监听数据变化,仅更新图表配置(不销毁实例)
lineData: {
handler() {
console.log(this.lineData,'lineData');
this.updateChart();
},
deep: true,
@@ -52,8 +47,12 @@ export default {
}
this.myChart = echarts.init(chartDom);
const entries = Object.entries(this.lineData);
entries.sort((item1, item2) => item2[1] - item1[1]);
const sortedObj = Object.fromEntries(entries);
let xData = Object.keys(sortedObj);
let yData = Object.values(sortedObj);
console.log('linedaata',this.lineData)
const option = {
tooltip: {
@@ -86,7 +85,7 @@ export default {
interval: 0,
padding: [5, 0, 0, 0]
},
data:this.xData
data:xData
}
],
yAxis: [
@@ -112,7 +111,31 @@ export default {
splitNumber: 4
},
],
series: []
series: [
{
name: '实际',
type: 'bar',
yAxisIndex: 0,
barWidth: 40,
label: {
show: true,
position: 'top'
},
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: yData
}
]
};
option && this.myChart.setOption(option);

View File

@@ -77,7 +77,7 @@ font-style: normal;">指标详情</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
<el-button @click="cancelBtn"> </el-button>
</div>
</el-dialog>
</Container>
@@ -387,6 +387,10 @@ export default {
console.error('文件上传出错:', error)
this.$message.error('上传失败!')
}
},
cancelBtn(){
this.upload.open = false
this.$refs.upload.clearFiles();
}
}
}

View File

@@ -17,10 +17,10 @@
<div class="bottom" style="background-color: rgba(249, 252, 255, 1);">
<div class="bottom" style="margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<div style='text-align: center;margin: 5px;font-size: 18px;font-weight: 400;color: #000;'>1200t/d</div>
<heatBar :lineData="heatData['1200t']" :xData="['桐城','洛阳','江苏','秦皇岛']" :dateData="dateData" />
<heatBar :lineData="heatData['1200t']"/>
</div>
<div style='text-align: center;margin: 5px;font-size: 18px;font-weight: 400;color: #000;'>650t/d</div>
<heatBar :lineData="heatData['650t']" :xData="['宜兴','自贡','漳州']" :dateData="dateData" />
<heatBar :lineData="heatData['650t']"/>
</div>
</template>
</div>
@@ -51,10 +51,6 @@ export default {
type: Object,
default: () => { } // 默认空数组,避免报错
},
heat: {
type: Object,
default: () => { }
}
},
data() {
return {

View File

@@ -15,7 +15,7 @@
<span class="legend-text">未完成</span>
</div>
</div>
<base-table style="height: 180px;" :page="1" :limit="10" :show-index="true" :beilv="1"
<base-table style="height: 204px;" :page="1" :limit="10" :show-index="true" :beilv="1"
:tableConfig="tableProps" :table-data="tableData" />
</div>
</div>
@@ -33,18 +33,18 @@ export default {
components: { Container, baseTable },
props: {
importantWork: {
type: Object,
default: () => ({})
type: Array,
default: () => ([])
}
},
data() {
return {
tableData: [],
tableProps: [
{ prop: 'name', label: '攻坚指标', align: 'center' },
{ prop: 'index', label: '攻坚指标', align: 'center',width:150 },
{ prop: 'target', label: '攻坚预算', align: 'center' },
{ prop: 'monthlyActual', label: '当月实际', align: 'center' },
{ prop: 'accumulated', label: '累计', align: 'center', subcomponent: finishDiv },
{ prop: 'real', label: '当月实际', align: 'center' },
{ prop: 'total', label: '累计', align: 'center', subcomponent: finishDiv },
]
}
},
@@ -59,33 +59,13 @@ export default {
},
methods: {
transformData(rawData) {
if (!rawData || typeof rawData !== 'object') return [];
const mapping = [
{ key: 'jyxxjl', name: '经营现金流', unit: '万元' },
{ key: 'yszk', name: '应收账款', unit: '万元' },
{ key: 'ch', name: '存货', unit: '万元' },
{ key: 'yysr', name: '营业收入', unit: '万元' },
{ key: 'snysysk', name: '三年以上应收款', unit: '万元' },
{ key: 'dzje', name: '非经营性资产处置到账金额', unit: '万元' },
{ key: 'yfjftr', name: '研发经费投入', unit: '万元' },
{ key: 'yfjftrqd', name: '研发经费投入强度', unit: '%' }
];
return mapping.map((item, index) => {
const data = rawData[item.key] || { monValue: 0, real: 0, target: 0 };
const accumulated = data.real || 0;
const target = data.target || 0;
return rawData.map((item, index) =>{
return {
...item,
id: index + 1,
name: item.name + '/' + item.unit,
target: target,
monthlyActual: data.monValue,
accumulated: accumulated,
status: accumulated > 0 && target > 0 && accumulated / target >= 1 ? 'done' : 'pending'
status: (item.real > 0 && item.target > 0 && item.real / item.target >= 1 || item.real >= item.target) ? 'done' : 'pending'
};
});
})
}
}
}

View File

@@ -1,18 +1,18 @@
<template>
<div class="coreItem">
<!-- 单独渲染第一个item -->
<div class="item" v-if="itemList.length > 0">
<div class="unit">{{ itemList[0].unit }}</div>
<div class="item" v-if="itemList.length > 0" v-for="(item, index) in itemList">
<div class="unit">{{ item.unit }}</div>
<div class="item-content">
<div class="content-wrapper">
<div class="left">
<div class="number">{{ itemList[0].targetValue }}</div>
<div class="number">{{ item.targetValue }}</div>
<div class="title">预算值</div>
</div>
<div class="line"></div>
<div class="right">
<div class="number" :style="{ color: getColor(itemList[0].currentValue, itemList[0].targetValue) }">
{{ itemList[0].currentValue }}
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
{{ item.currentValue }}
</div>
<div class="title">实际值</div>
</div>
@@ -23,7 +23,7 @@
<!-- 进度条颜色和宽度动态绑定 -->
<div class="progress-bar" :style="{
width: itemList[0].progress + '%',
background: getColor(itemList[0].currentValue, itemList[0].targetValue)
background: getColor(item.currentValue, item.targetValue)
}"></div>
</div>
</div>
@@ -32,67 +32,9 @@
<div class="progress-percent">完成率</div>
<!-- 百分比颜色动态绑定 -->
<div class="progress-percent" :style="{
color: getColor(itemList[0].currentValue, itemList[0].targetValue)
color: getColor(item.currentValue, item.targetValue)
}">
{{ itemList[0].progress }}%
</div>
</div>
</div>
</div>
<!-- 循环渲染剩余的item从索引1开始 -->
<div class="item groupData" style="display: flex;padding: 0;" v-for="(item, index) in itemList.slice(1)"
:key="index">
<!-- 左侧预算值/实际值部分不变 -->
<div class="left" style="display: flex;align-items: start;gap: 4px;padding: 12px 0 0 12px;">
<div class="groupName">{{ item.unit }}</div>
<div class="left-target">
<div class="number">{{ item.targetValue }}</div>
<div class="title">预算值</div>
</div>
<div class="left-real">
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
{{ item.currentValue }}
</div>
<div class="title">实际值</div>
</div>
</div>
<div class="cityLine"></div>
<div class="right">
<!-- 顶部完成率部分不变 -->
<div class="groupName" :class="{
'bg-default': item.currentValue < item.targetValue,
'bg-green': item.currentValue >= item.targetValue
}" style="font-size: 12px;display: flex;align-items: center;justify-content: flex-end;">
<div class="title">完成率</div>
<div class="yield" style="font-size: 22px;margin-bottom: 4px;">
{{ item.progress }}
</div>
<div class="unit">%</div>
</div>
<!-- 动态渲染城市进度循环 item.cities -->
<div class="right-city" v-for="(city, cityIdx) in item.cities" :key="cityIdx"
:style="{ marginTop: cityIdx > 0 ? '2px' : '0' }" @click="getTableData(city.num)" style="cursor: pointer;">
<div class="city">{{ city.name }}</div> <!-- 动态城市名 -->
<div class="city-progress-group">
<div class="city-progress-container">
<!-- 动态城市进度条颜色按城市进度判断 -->
<div class="city-progress-bar" :style="{
width: city.progress + '%',
background: getColor(city.completed, city.total) // 用城市已完成/总数判断颜色
}"></div>
</div>
</div>
<div class="city-progress-yield" style="display: flex;justify-content: space-between;">
<!-- 动态比值已完成/总数 -->
<div class="numerator" :style="{ color: getColor(city.completed, city.total) }">
{{ city.completed }}/{{ city.total }}
</div>
<!-- 动态城市完成率 -->
<div class="city-yield" :style="{ color: getColor(city.completed, city.total) }">
{{ city.progress }}%
</div>
{{ item.progress }}%
</div>
</div>
</div>
@@ -108,60 +50,7 @@ export default {
data() {
return {
progress: 90, // 进度值基础参数
itemList: [
// {
// unit: "总进度",
// targetValue: 16,
// currentValue: 14.5,
// progress: 90,
// cities: [] // 总进度无需城市数据,留空
// },
// {
// unit: "一组",
// targetValue: 16,
// currentValue: 17,
// progress: 106,
// cities: [
// { name: "桐城", completed: 12, total: 13, progress: 92 },
// { name: "自贡", completed: 15, total: 16, progress: 93 } // 新增城市示例
// ]
// },
// {
// unit: "二组",
// targetValue: 16,
// currentValue: 16,
// progress: 100,
// cities: [
// { name: "蚌埠", completed: 10, total: 12, progress: 83 },
// { name: "合肥", completed: 8, total: 10, progress: 80 }
// ]
// },
// // 其他组同理,按需添加 cities 数据
// {
// unit: "三组",
// targetValue: 16,
// currentValue: 15.2,
// progress: 85,
// cities: [{ name: "宜兴", completed: 9, total: 11, progress: 81 }]
// },
// {
// unit: "四组",
// targetValue: 16,
// currentValue: 18,
// progress: 112,
// cities: [
// { name: "漳州", completed: 14, total: 15, progress: 93 },
// { name: "洛阳", completed: 12, total: 14, progress: 85 }
// ]
// },
// {
// unit: "五组",
// targetValue: 16,
// currentValue: 14,
// progress: 80,
// cities: [{ name: "桐城", completed: 7, total: 9, progress: 77 }]
// }
]
itemList: []
};
},
watch: {
@@ -180,56 +69,36 @@ export default {
targetValue: data.totalProgress.target,
currentValue: data.totalProgress.real,
progress: data.totalProgress.rate,
cities: [] // 总进度无需城市数据,留空
},
{
unit: "一组",
targetValue: data.group1.target,
currentValue: data.group1.real,
progress: data.group1.rate,
cities: [
{ name: "桐城", completed: data[2].real, total: data[2].target, progress: data[2].rate,num:2 },
{ name: "自贡", completed: data[3].real, total: data[3].target, progress: data[3].rate, num: 3 } // 新增城市示例
]
progress: data.group1.rate
},
{
unit: "二组",
targetValue: data.group2.target,
currentValue: data.group2.real,
progress: data.group2.rate,
cities: [
{ name: "蚌埠", completed: data[4].real, total: data[4].target, progress: data[4].rate, num: 4 },
{ name: "合肥", completed: data[5].real, total: data[5].target, progress: data[5].rate, num: 5 }
]
progress: data.group2.rate
},
// 其他组同理,按需添加 cities 数据
{
unit: "三组",
targetValue: data.group3.target,
currentValue: data.group3.real,
progress: data.group3.rate,
cities: [{ name: "江苏凯盛", completed: data[6].real, total: data[6].target, progress: data[6].rate, num: 6 },
{ name: "宜兴", completed: data[7].real, total: data[7].target, progress: data[7].rate, num: 7 }
]
progress: data.group3.rate
},
{
unit: "四组",
targetValue: data.group4.target,
currentValue: data.group4.real,
progress: data.group4.rate,
cities: [
{ name: "漳州", completed: data[8].real, total: data[8].target, progress: data[8].rate, num: 8 },
{ name: "洛阳", completed: data[9].real, total: data[9].target, progress: data[9].rate, num: 9 }
]
progress: data.group4.rate
},
{
unit: "五组",
targetValue: data.group5.target,
currentValue: data.group5.real,
progress: data.group5.rate,
cities: [{ name: "秦皇岛", completed: data[10].real, total: data[10].target, progress: data[10].rate, num: 10 },
// { name: "秦皇岛", completed: 7, total: 9, progress: 77 }
]
progress: data.group5.rate
}
]
},
@@ -240,7 +109,6 @@ export default {
: "rgba(249, 164, 74, 1)";
},
getTableData(data) {
console.log(data, 'data');
this.$emit('handleShowTable',data)
}
@@ -257,11 +125,12 @@ export default {
.coreItem {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 8px;
}
.item {
width: 220px;
width: 227px;
height: 122px;
background: #f9fcff;
padding: 12px;

View File

@@ -19,7 +19,7 @@ import * as echarts from 'echarts';
export default {
name: 'Container',
props: ["chartData",'dateData'],
props: ["chartData",'dateData','unit'],
components: {},
data() {
return {
@@ -131,7 +131,7 @@ export default {
],
yAxis: {
type: 'value',
name: '元/㎡',
name: this.unit,
// nameLocation:'center',
nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' },
min: 0,

View File

@@ -14,18 +14,28 @@
<div class="button-line lineFour" v-if="activeButton !== 3 && activeButton !== 4"></div>
<div class="item-button" style="width: 75px;" :class="{ active: activeButton === 4 }" @click="activeButton = 4">
投入产出率</div>
<div class="button-line lineFive" v-if="activeButton !== 4 && activeButton !== 5"></div>
<div class="item-button" style="width: 45px;" :class="{ active: activeButton === 5 }" @click="activeButton = 5">
折旧</div>
</div>
</div>
<div class="lineBottom" style="height: 219px; width: 100%" v-if="isLineDataReady">
<!-- 核心改动动态传递数据给子组件 -->
<coreLineChart style="height: 219px; width: 100%" :chart-data="selectedChartData" :dateData="dateData" />
<coreLineChart style="height: 219px; width: 100%" :chart-data="selectedChartData" :unit='unit' :dateData="dateData" />
</div>
</div>
</template>
<script>
import coreLineChart from './productBar.vue';
const dataKeyMap = [
{name:'制造成本',unit:'元/㎡'},
{name:'原片成本',unit:'元/㎡'},
{name:'加工成本',unit:'元/㎡'},
{name:'原片成品率',unit:'%'},
{name:'投入产出率',unit:'%'},
{name:'折旧',unit:'万元'}
];
export default {
name: "Container",
components: { coreLineChart },
@@ -33,6 +43,7 @@ export default {
data() {
return {
activeButton: 0, // 初始激活第一个按钮索引0
dataKeyMap
};
},
computed: {
@@ -42,22 +53,14 @@ export default {
},
// 核心改动计算属性根据activeButton动态返回选中的数据
selectedChartData() {
// 定义按钮索引与lineData中key的映射关系
const dataKeyMap = [
'制造成本',
'原片成本',
'加工成本',
'原片成品率',
'投入产出率'
];
// 根据当前激活的按钮索引获取对应的数据key
const selectedKey = dataKeyMap[this.activeButton];
console.log(this.lineData[selectedKey]);
const selectedKey = this.dataKeyMap[this.activeButton].name;
// 从lineData中获取对应的数据如果不存在则返回一个空对象以防止报错
return this.lineData ? this.lineData[selectedKey] || {} : {};
},
unit() {
return this.dataKeyMap[this.activeButton].unit;
}
},
methods: {},
@@ -73,7 +76,7 @@ export default {
.barTop {
display: flex;
gap: 40px;
gap: 20px;
.title {
height: 18px;
@@ -91,7 +94,7 @@ export default {
display: flex;
position: relative;
gap: 2px;
width: 327px;
width: 356px;
align-items: center;
height: 24px;
background: #ecf4fe;
@@ -105,23 +108,27 @@ export default {
}
.lineOne {
top: 5px;
left: 57px;
top: 6px;
left: 55px;
}
.lineTwo {
top: 5px;
left: 118px;
top: 6px;
left: 111px;
}
.lineThree {
top: 5px;
left: 177px;
top: 6px;
left: 169px;
}
.lineFour {
top: 5px;
left: 252px;
top: 6px;
left: 240px;
}
.lineFive {
top: 6px;
left: 314px;
}
.item-button {

View File

@@ -1,6 +1,7 @@
<template>
<div>
<div class="coreItem">
<div class="item" @click="handleRoute(item.route)" v-for="(item, index) in itemList" :key="index">
<div class="item" @click="handleRoute(item.route)" v-for="(item, index) in itemList" :key="index" v-if='index<4'>
<div class="name">{{ item.name }}</div>
<div class="item-content">
<div class="content-wrapper">
@@ -48,6 +49,49 @@
</div>
</div>
</div>
<div class="itemBottom">
<div class="item" v-for="(item, index) in itemList" :key="index" @click="handleRoute(item.route)" v-if='index>=4'>
<div class="unit">{{ item.name }}</div>
<div class="item-content">
<div class="content-wrapper">
<div class="left">
<div class="number">{{ item.targetValue }}</div>
<div class="title">目标值</div>
</div>
<div class="line"></div>
<!-- 实际值:根据与目标值的比较动态变色 -->
<div class="right">
<div class="number" :class="{
'exceed-target': item.currentValue > item.targetValue,
'below-target': item.currentValue < item.targetValue,
'equal-target': item.currentValue === item.targetValue
}">
{{ item.currentValue }}
</div>
<div class="title">实际值</div>
</div>
</div>
<!-- 进度条和百分比:同步变色逻辑 -->
<div class="progress-group">
<div class="progress-container">
<div class="progress-bar" :style="{ width: item.progress + '%' }" :class="{
'exceed-pro-target': item.currentValue > item.targetValue,
'below-pro-target': item.currentValue < item.targetValue,
'equal-pro-target': item.currentValue === item.targetValue
}"></div>
</div>
<div class="progress-percent" :class="{
'exceed-target': item.currentValue > item.targetValue,
'below-target': item.currentValue < item.targetValue,
'equal-target': item.currentValue === item.targetValue
}">
{{ item.progressDisplay }}
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
@@ -160,6 +204,18 @@ export default {
name: '毛利率·%',
route: '/grossMargin/grossMargin',
isPercentage: true // 需要加%符号
},
{
key: 'accountsReceivable',
name: '应收账款·万元',
route: '/accountsReceivable/accountsReceivableIndex',
isPercentage: false // 需要加%符号
},
{
key: 'inventory',
name: '存货·万元',
route: '/inventoryAnalysis/inventoryAnalysisIndex',
isPercentage: false // 需要加%符号
}
];
@@ -219,14 +275,11 @@ export default {
.coreItem {
display: flex;
gap: 8px;
// padding: 8px; // 避免边缘item hover阴影被截断
}
.item {
.item {
width: 170px;
height: 228px;
height: 168px;
background: #f9fcff;
padding: 12px 0px 17px 12px;
padding: 12px 0px 0px 12px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.3s ease;
@@ -235,7 +288,6 @@ export default {
box-shadow: 0px 4px 12px 2px #B5CDE5;
transform: translateY(-2px);
}
.name {
height: 18px;
font-family: PingFangSC, PingFang SC;
@@ -246,36 +298,32 @@ export default {
letter-spacing: 1px;
text-align: left;
font-style: normal;
margin-bottom: 2px;
}
.item-content {
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100% - 26px);
}
.content-wrapper {
display: flex;
flex-direction: column;
gap: 10px;
gap: 2px;
}
.line {
width: 149px;
height: 1px;
background: linear-gradient(to left, rgba(255, 0, 0, 0), #cbcbcb);
}
.left,
.right {
margin-top: 11px;
margin-top: 0px;
display: flex;
flex-direction: column;
gap: 2px;
width: 100%;
}
/* 实际值 - 基础样式(无颜色) */
.number {
height: 22px;
@@ -286,17 +334,14 @@ export default {
text-align: left;
font-style: normal;
}
/* 实际值 - 实际值≥目标值(绿色) */
.number-exceed {
color: rgba(54, 181, 138, 1) !important;
}
/* 实际值 - 实际值<目标值(黄色) */
.number-below {
color: rgba(249, 164, 74, 1) !important;
}
.title {
height: 14px;
font-family: PingFangSC, PingFang SC;
@@ -307,14 +352,12 @@ export default {
text-align: left;
font-style: normal;
}
.progress-group {
display: flex;
align-items: center;
gap: 8px;
margin-top: 15px;
margin-top: 2px;
}
.progress-container {
width: 138px;
height: 10px;
@@ -322,26 +365,22 @@ export default {
border-radius: 8px;
overflow: hidden;
}
/* 进度条 - 基础样式(无颜色) */
.progress-bar {
height: 100%;
border-radius: 8px;
transition: width 0.5s ease;
}
/* 进度条 - 实际值≥目标值(绿色) */
.bar-exceed {
background: rgba(98, 213, 180, 1) !important;
opacity: 1 !important;
}
/* 进度条 - 实际值<目标值(黄色) */
.bar-below {
background: rgba(249, 164, 74, 1) !important;
opacity: 1 !important;
}
/* 百分比 - 基础样式(无颜色) */
.progress-percent {
font-family: PingFangSC, PingFang SC;
@@ -349,20 +388,185 @@ export default {
font-size: 12px;
line-height: 1;
}
/* 百分比 - 实际值≥目标值(绿色) */
.percent-exceed {
color: rgba(54, 181, 138, 1) !important;
}
/* 百分比 - 实际值<目标值(黄色) */
.percent-below {
color: rgba(249, 164, 74, 1) !important;
}
.yield {
width: 138px;
margin-top: 3px;
}
}
}
.itemBottom {
display: flex;
gap: 8px;
margin-top: 5px;
.item {
width: 350px;
height: 90px;
background: #f9fcff;
padding: 8px 8px 0px;
box-sizing: border-box;
cursor: pointer; // 提示可点击
transition: all 0.3s ease; // 动画过渡
&:hover {
box-shadow: 0px 4px 12px 2px #B5CDE5;
transform: translateY(-2px); // 轻微上浮增强交互感
}
.unit {
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;
margin-bottom: 2px;
}
.item-content {
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100% - 29px);
}
.content-wrapper {
display: flex;
align-items: center;
justify-content: space-around;
flex: 1;
}
.line {
width: 1px;
height: 46px;
background: linear-gradient(to bottom, rgba(255, 0, 0, 0), #cbcbcb);
}
.left,
.right {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 2px;
flex: 1;
}
.number {
height: 22px;
font-family: PingFangSC, PingFang SC;
font-weight: 600;
font-size: 24px;
color: rgba(103, 103, 103, 0.79);
/* 默认颜色(等于目标值时) */
line-height: 22px;
text-align: center;
font-style: normal;
}
.title {
height: 14px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #868687;
line-height: 14px;
text-align: center;
font-style: normal;
}
.progress-group {
display: flex;
align-items: center;
gap: 8px;
}
.progress-container {
width: 280px;
height: 10px;
background: #ECEFF7;
border-radius: 8px;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: rgba(98, 213, 180, 1);
/* 默认进度条颜色(等于目标值时) */
border-radius: 8px;
opacity: 0.7;
transition: width 0.5s ease; // 进度条动画
}
.progress-percent {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #868687;
/* 默认百分比颜色(等于目标值时) */
line-height: 1;
}
/* 实际值 > 目标值:绿色样式 */
.exceed-target {
color: rgba(98, 213, 180, 1) !important;
/* 文字绿色 */
// background: rgba(98, 213, 180, 1) !important;
/* 进度条绿色 */
opacity: 1 !important;
}
/* 实际值 < 目标值:黄色样式 */
.below-target {
color: rgba(249, 164, 74, 1) !important;
/* 文字黄色 */
// background: rgba(249, 164, 74, 1) !important;
/* 进度条黄色 */
opacity: 1 !important;
}
.exceed-pro-target {
// color: rgba(98, 213, 180, 1) !important;
/* 文字绿色 */
background: rgba(98, 213, 180, 1) !important;
/* 进度条绿色 */
opacity: 1 !important;
}
/* 实际值 < 目标值:黄色样式 */
.below-pro-target {
// color: rgba(249, 164, 74, 1) !important;
/* 文字黄色 */
background: rgba(249, 164, 74, 1) !important;
/* 进度条黄色 */
opacity: 1 !important;
}
/* 实际值 = 目标值:默认灰色(可自定义) */
.equal-target{
color: rgba(98, 213, 180, 1) !important;
/* 文字绿色 */
// background: rgba(98, 213, 180, 1) !important;
/* 进度条绿色 */
opacity: 1 !important;
}
.equal-pro-target {
// color: rgba(98, 213, 180, 1) !important;
/* 文字绿色 */
background: rgba(98, 213, 180, 1) !important;
/* 进度条绿色 */
opacity: 1 !important;
}
}
}
</style>

View File

@@ -1,15 +1,15 @@
<template>
<div class="coreItem">
<div class="item" :class="`item${index + 1}`" @click="handleItemClick(index)" v-for="(item, index) in itemList"
<div class="item" @click="handleItemClick(index)" v-for="(item, index) in itemList"
:key="index">
<div class="unit">{{ item.unit }}</div>
<div class="item-content">
<div class="content-wrapper">
<div class="left">
<div class="left" v-if="item.unit !== '折旧·万元'">
<div class="number">{{ item.target }}</div>
<div class="title">预算值</div>
</div>
<div class="line"></div>
<div class="line" v-if="item.unit !== '折旧·万元'"></div>
<div class="right">
<!-- 实际值颜色动态绑定 -->
<div class="number" :style="{ color: getColor(index) }">
@@ -18,7 +18,7 @@
<div class="title">实际值</div>
</div>
</div>
<div class="progress-group">
<div class="progress-group" v-if="item.unit !== '折旧·万元'">
<div class="progress-container">
<!-- 进度条样式动态绑定 -->
<div class="progress-bar" :style="{
@@ -88,12 +88,17 @@ export default {
{
key: 'rawYield',
unit: '原片成品率·%',
route: '/rawSheetYield/rawSheetYield' // 假设这个没有路由
route: '/rawSheetYield/rawSheetYield'
},
{
key: 'ioYield',
unit: '投入产出率·%',
route: '/inputOutputRatio/inputOutputRatio' // 假设这个没有路由
route: '/inputOutputRatio/inputOutputRatio'
},
{
key: 'depreciation',
unit: '折旧·万元',
route: '/depreciationAnalysis/depreciationAnalysisIndex'
}
];
@@ -194,7 +199,7 @@ export default {
}
.item {
width: 252px;
width: 166px;
height: 110px;
background: #f9fcff;
padding: 12px;
@@ -300,10 +305,4 @@ export default {
line-height: 1;
}
}
.item1,
.item2,
.item3 {
width: 166px;
}
</style>

View File

@@ -2,7 +2,7 @@
<div id="dayReport" class="dayReport" :style="styles">
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
<ReportHeader :dateData="dateData" top-title="应收账款" :is-full-screen="isFullScreen"
<ReportHeader :dateData="dateData" top-title="折旧分析" :is-full-screen="isFullScreen"
@screenfullChange="screenfullChange" @timeRangeChange="handleTimeChange" />
<div class="main-body" style="
flex: 1;
@@ -39,7 +39,7 @@ import { mapState } from "vuex";
import operatingLineChart from "../depreciationAnalysisComponents/operatingLineChart";
import operatingLineChartCumulative from "../depreciationAnalysisComponents/operatingLineChartCumulative.vue";
import { getSalesRevenueGroupData } from '@/api/cockpit'
import { getDepreciationAnalysisData } from '@/api/cockpit'
export default {
name: "DepreciationAnalysis",
components: {
@@ -132,7 +132,7 @@ export default {
// this.getData()
// },
getData() {
getSalesRevenueGroupData({
getDepreciationAnalysisData({
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
sort: this.sort,

View File

@@ -16,7 +16,7 @@
gap: 12px;
grid-template-columns:1624px;
">
<operatingLineChart :dateData="dateData" :monData="monData" />
<operatingLineChart :dateData="dateData" :monthData="monthData" />
</div>
</div>
<div class="top" style="display: flex; gap: 16px;margin-top: 6px;">
@@ -25,40 +25,27 @@
gap: 12px;
grid-template-columns: 1624px;
">
<operatingLineChartCumulative :dateData="dateData" :totalData="totalData" />
<!-- <keyWork /> -->
<operatingLineChartCumulative :dateData="dateData" :ytdData="ytdData" />
</div>
</div>
</div>
<!-- <div class="centerImg" style="
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1; /* 确保在 backp 之上、内容之下 */
"></div> -->
</div>
</template>
<script>
import ReportHeader from "../components/noRouterHeader.vue";
import { Sidebar } from "../../../layout/components";
import screenfull from "screenfull";
// import operatingSalesRevenue from "./operatingComponents/operatingSalesRevenue";
// import premProdStatus from "./components/premProdStatus.vue";
import { mapState } from "vuex";
import operatingLineChart from "../electricityCostAnalysisComponents/operatingLineChart";
import operatingLineChartCumulative from "../electricityCostAnalysisComponents/operatingLineChartCumulative.vue";
import operatingLineChart from "../accountsReceivableComponents/operatingLineChart";
import operatingLineChartCumulative from "../accountsReceivableComponents/operatingLineChartCumulative.vue";
import { getProfitAnalysisTotalList } from '@/api/cockpit'
import moment from "moment";
import { getElectricityCostAnalysisData } from '@/api/cockpit'
export default {
name: "DayReport",
name: "AccountsReceivable",
components: {
ReportHeader,
operatingLineChartCumulative,
operatingLineChart,
// premProdStatus,
Sidebar,
},
data() {
@@ -68,9 +55,11 @@ export default {
timer: null,
beilv: 1,
value: 100,
sort:1,
selectDate:{},
monthData: {},
ytdData:{},
dateData: {},
monData: [],
totalData: [],
};
},
@@ -139,20 +128,22 @@ export default {
this.dateData = this.$route.query.dateData ? this.$route.query.dateData : undefined
},
methods: {
// sortChange(value) {
// this.sort = value
// this.getData()
// },
getData() {
getProfitAnalysisTotalList({
getElectricityCostAnalysisData({
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
analysisObject: [
"利润总额"
],
levelId: 1,
// timeDim: this.dateData.mode
sort: this.sort,
index: undefined,
factory: undefined
}).then((res) => {
console.log(res);
this.monData = res.data.currentMonthData
this.totalData = res.data.totalMonthData
// this.totalData = res.data.totalData
console.log('res==============================',res);
this.monthData= res.data.month
this.ytdData = res.data.ytd
// this.saleData = res.data.SaleData
// this.premiumProduct = res.data.premiumProduct
// this.salesTrendMap = res.data.salesTrendMap
@@ -161,7 +152,7 @@ export default {
})
},
handleTimeChange(obj) {
// console.log(obj, 'obj');
console.log(obj, 'obj');
this.dateData= obj
this.getData()
},
@@ -235,14 +226,12 @@ export default {
<style scoped lang="scss">
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
.dayReport {
width: 1920px;
height: 1080px;
background: url("../../../assets/img/backp.png") no-repeat;
background-size: cover;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px);
}

View File

@@ -73,7 +73,7 @@ import totalOverview from "../electricityCostAnalysisComponents/totalOverview.vu
import relatedIndicatorsAnalysis from "../electricityCostAnalysisComponents/relatedIndicatorsAnalysis.vue";
import dataTrend from "../electricityCostAnalysisComponents/dataTrend.vue";
import { mapState } from "vuex";
import { getProfitAnalysisTotalList } from '@/api/cockpit'
import { getElectricityCostAnalysisFData } from '@/api/cockpit'
// import PSDO from "./components/PSDO.vue";
// import psiLineChart from "./components/psiLineChart.vue";
@@ -108,7 +108,7 @@ export default {
totalData: {},
trend: [],
relatedData: [],
trendName: '利润总额',
trendName: '原片电费',
// cusProData: {},
};
},
@@ -199,45 +199,26 @@ export default {
const requestParams = {
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
// index: this.index,
// sort: 1,
trendName: this.trendName,
analysisObject: [
"利润总额",
],
// paramList: ['制造成本', '财务费用', '销售费用', '管理费用', '运费'],
levelId: this.factory,
// baseId: Number(this.factory),
sort: 1,
index: this.trendName,
factory: null
};
// 调用接口
getProfitAnalysisTotalList(requestParams).then((res) => {
this.monData = res.data.currentMonthData.find(item => {
return item.name === "利润总额";
});
console.log('this.monData', this.monData);
this.totalData = res.data.totalMonthData.find(item => {
return item.name === "利润总额";
});
// this.relatedMon = res.data.relatedMon
getElectricityCostAnalysisFData(requestParams).then((res) => {
this.monData = res.data.month
this.totalData = res.data.ytd
this.relatedData = {
relatedMon: res.data.currentMonthData.filter(item => {
return item.name !== "利润总额";
}), // 兜底月度数据
relatedTotal: res.data.totalMonthData.filter(item => {
return item.name !== "利润总额";
}) // 兜底累计数据
relatedMon: res.data.monthAnalysis,
relatedTotal: res.data.ytdAnalysis
}
this.trend = res.data.dataTrend
});
},
handleTimeChange(obj) {
this.month = obj.targetMonth
this.dateData = {
startTime: obj.startTime,
endTime: obj.endTime,
// mode: obj.mode,
}
this.getData()

View File

@@ -60,16 +60,13 @@ export default {
data() {
return {
isDropdownShow: false,
selectedProfit: '利润总额', // 选中的名称初始为null
selectedProfit: '原片电费', // 选中的名称初始为null
profitOptions: [
'利润总额',
'销量',
'单价',
'制造成本',
'管理费用',
'销售费用',
'财务费用',
'非经营性利润',
'原片电费',
'加工电费',
'外围电费',
'发电量',
'日均发电量'
]
};
},

View File

@@ -65,13 +65,13 @@ export default {
*/
factoryData() { // 整合原始数据 + 计算flag
return {
completeRate: this.monData.proportion ? Number(this.monData.proportion) : 0,
diff: this.monData.diffValue,
real: this.monData.value,
target: this.monData.targetValue,
thb: this.monData.thb,
completeRate: this.monData.rate ? Number(this.monData.rate) : 0,
diff: this.monData.diff,
real: this.monData.real,
target: this.monData.target,
thb: this.monData.momRate,
// ...rawData,
flag: this.monData.completed // 新增flag字段
flag: this.monData.rate >= 100 ? 1 : 0,
};
}
},

View File

@@ -67,13 +67,11 @@ export default {
computed: {
indicatorDefs() {
return [
{ key: 'sales', name: '销量', unit: '万', route: '/salesVolumeAnalysis/salesVolumeAnalysisBase'},
{ key: 'price', name: '单价', unit: '元/㎡', route: '/unitPriceAnalysis/unitPriceAnalysisBase'},
{ key: 'mfgCost', name: '制造成本', unit: '元/㎡', route: '/productionCostAnalysis/productionCostAnalysisBase'},
{ key: 'mgmtFee', name: '管理费用', unit: '万元', route: '/expenseAnalysis/expenseAnalysisBase'},
{ key: 'salesFee', name: '销售费用', unit: '万元', route: '/expenseAnalysis/expenseAnalysisBase'},
{ key: 'finFee', name: '财务费用', unit: '万元', route: '/expenseAnalysis/expenseAnalysisBase'},
{ key: 'nonOpProfit', name: '非经营性利润', unit: '万元', route: null}
{ key: 'elecFee', name: '原片电费', unit: '万', route: null},
{ key: 'elecCost', name: '加工电费', unit: '元', route: null},
{ key: 'elecCostW', name: '外围电费', unit: '元', route: null},
{ key: 'fdl', name: '发电量', unit: '', route: null},
{ key: 'rjfdl', name: '日均发电量', unit: '', route: null},
]
},
indicators() {
@@ -90,7 +88,7 @@ export default {
})
},
sortedIndicators() {
const unitOrder = ['万㎡', '元/㎡', '万元']
const unitOrder = ['万', '']
const unitRank = (u) => {
const idx = unitOrder.indexOf(u)
return idx === -1 ? 999 : idx
@@ -173,7 +171,7 @@ export default {
}
.dashboard {
width: 220px;
width: 312px;
height: 205px;
background: #F9FCFF;
padding: 16px 0 0 10px;

View File

@@ -68,13 +68,13 @@ export default {
*/
factoryData() { // 整合原始数据 + 计算flag
return {
completeRate: this.totalData.proportion ? Number(this.totalData.proportion) : 0,
diff: this.totalData.diffValue,
real: this.totalData.value,
target: this.totalData.targetValue,
thb: this.totalData.thb,
completeRate: this.totalData.rate ? Number(this.totalData.rate) : 0,
diff: this.totalData.diff,
real: this.totalData.real,
target: this.totalData.target,
thb: this.totalData.yoyRate,
// ...rawData,
flag: this.totalData.completed// 新增flag字段
flag: this.totalData.rate >= 100 ? 1 : 0,
};
}
},

View File

@@ -56,10 +56,11 @@ export default {
value: 100,
orderTableData:[],
productData: {},
heat:{},
purchase: {},
dateData:{},
inventory: {},
importantWork: {},
importantWork: [],
finance: {},
cost: {},
sale: {},

View File

@@ -39,7 +39,7 @@ import { mapState } from "vuex";
import operatingLineChart from "../inventoryAnalysisComponents/operatingLineChart";
import operatingLineChartCumulative from "../inventoryAnalysisComponents/operatingLineChartCumulative.vue";
import { getSalesRevenueGroupData } from '@/api/cockpit'
import { getInventoryData } from '@/api/cockpit'
export default {
name: "InventoryAnalysis",
components: {
@@ -59,6 +59,7 @@ export default {
selectDate:{},
monthData: {},
ytdData:{},
dateData:{}
};
},
@@ -132,7 +133,7 @@ export default {
// this.getData()
// },
getData() {
getSalesRevenueGroupData({
getInventoryData({
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
sort: this.sort,

View File

@@ -147,7 +147,6 @@ export default {
"经营性利润"
],
levelId:1,
// timeDim: this.dateData.mode
}).then((res) => {
console.log(res);
this.monData = res.data.currentMonthData

View File

@@ -143,7 +143,7 @@ export default {
{ offset: 1, color: 'rgba(40, 138, 255, 0)' }
])
},
data: data.rate || [],
data: data.rates || [],
symbol: 'circle',
symbolSize: 6
},

View File

@@ -72,6 +72,7 @@ export default {
selectDate:{},
monthData: {},
ytdData:{},
dateData: {},
};
},

View File

@@ -189,23 +189,23 @@ export default {
startTime: this.dateData.startTime,
endTime: this.dateData.endTime,
trendName: '原料' + this.meterialName + this.trendName,
analysisObject: ['原料' + this.meterialName],
analysisObject: [this.meterialName],
levelId: this.factory,
};
// 调用接口
getSingleMaterialAnalysis(requestParams).then((res) => {
this.monData = res.data.currentMonthData.find(item => {
return item.name === '原料' + this.meterialName;
return item.name === this.meterialName + '成本';
});
this.totalData = res.data.totalMonthData.find(item => {
return item.name === '原料' + this.meterialName;
return item.name === this.meterialName + '成本';
});
this.relatedData = {
relatedMon: res.data.currentMonthData.filter(item => {
return item.name !== '原料' + this.meterialName;
return item.name !== this.meterialName + '成本';
}), // 兜底月度数据
relatedTotal: res.data.totalMonthData.filter(item => {
return item.name !== '原料' + this.meterialName;
return item.name !== this.meterialName + '成本';
}) // 兜底累计数据
}
this.trend = res.data.dataTrend

View File

@@ -108,9 +108,7 @@ export default {
totalData: {},
trend: [],
relatedData: {},
trendName: '原片原料成本',
// monthRelatedData: [],
// totalRelatedData: [],
trendName: '原片原料',
};
},

View File

@@ -84,7 +84,7 @@ export default {
overheadName:'',
overheadOptions:[
{value:'包材',label:'包材'},
{value:'备品丶机物料',label:'备品丶机物料'},
{value:'备件、机物料',label:'备件、机物料'},
{value:'折旧',label:'折旧'},
{value:'其他',label:'其他'}
]

View File

@@ -39,7 +39,7 @@
grid-template-columns: 1624px;
">
<!-- <monthlyRelatedMetrics :itemData="renderList" :title="'月度·相关指标分析'" /> -->
<relateSingleFuelCostAnalysis :relatedData="relatedData" :title="'相关指标分析'" />
<relateSingleFuelCostAnalysis :fuelName='fuelName' :relatedData="relatedData" :title="'相关指标分析'" />
</div>
</div>
@@ -213,7 +213,7 @@ export default {
// index: this.index,
// sort: 1,
trendName: this.trendName,
analysisObject: [this.fuelName + '成本'],
analysisObject: [this.fuelName],
// paramList: ['制造成本', '财务费用', '销售费用', '管理费用', '运费'],
levelId: this.factory,
// baseId: Number(this.factory),

View File

@@ -211,7 +211,7 @@ export default {
// index: this.index,
// sort: 1,
trendName: this.trendName,
analysisObject: [this.fuelName + '成本'],
analysisObject: [this.fuelName],
// paramList: ['制造成本', '财务费用', '销售费用', '管理费用', '运费'],
levelId: this.factory,
// baseId: Number(this.factory),

View File

@@ -64,7 +64,7 @@ export default {
profitOptions: [
'原片制造费用成本',
'包材',
'备品丶机物料',
'备件、机物料',
'折旧',
'其他',
]

View File

@@ -60,9 +60,9 @@ export default {
data() {
return {
isDropdownShow: false,
selectedProfit: '原片原料成本', // 选中的名称初始为null
selectedProfit: '原片原料', // 选中的名称初始为null
profitOptions: [
'原片原料成本',
'原片原料',
'硅砂',
'纯碱',
'白云石',

View File

@@ -63,7 +63,7 @@ export default {
selectedProfit: '制造费用', // 选中的名称初始为null
profitOptions: [
'制造费用',
'备品丶机物料',
'备件、机物料',
'折旧',
'其他',
]

View File

@@ -135,9 +135,9 @@ export default {
mounted() {
let timeArr = []
if (this.$route.query.startTime && this.$route.query.endTime) {
timeArr = [moment(Number(this.$route.query.startTime)).format('YYYY-MM'), moment(Number(this.$route.query.endTime)).format('YYYY-MM')]
timeArr = [moment(Number(this.$route.query.startTime)).format('YYYY-MM-DD'), moment(Number(this.$route.query.endTime)).format('YYYY-MM-DD')]
}else{
timeArr = [moment().startOf('month').format('YYYY-MM'), moment().endOf('month').format('YYYY-MM')]
timeArr = [moment().startOf('month').format('YYYY-MM-DD'), moment().endOf('month').format('YYYY-MM-DD')]
};
this.$refs.searchBarForm.formInline.timeValMonth = timeArr
this.listQuery.startTime = moment(timeArr[0]).startOf('day').valueOf();
@@ -195,8 +195,8 @@ export default {
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.status = val.status ? val.status : undefined;
this.listQuery.startTime = moment(val.timeValMonth[0]).startOf('day').valueOf();
this.listQuery.endTime = moment(val.timeValMonth[1]).endOf('day').valueOf();
this.listQuery.startTime = moment(moment(val.timeValMonth[0]).startOf('month').format('YYYY-MM-DD')).startOf('day').valueOf();
this.listQuery.endTime = moment(moment(val.timeValMonth[1]).endOf('month').format('YYYY-MM-DD')).endOf('day').valueOf();
switch (val.btnName) {
case 'search':
this.getDataList();