运营驾驶舱对接
This commit is contained in:
2
.env.dev
2
.env.dev
@@ -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'
|
||||
|
||||
|
||||
# 路由懒加载
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
|
||||
"/salesVolumeAnalysis",
|
||||
'/procurementGainAnalysis',
|
||||
'/fullCostAnalysis',
|
||||
'/electricityCostAnalysis',
|
||||
// '/expenseAnalysis',
|
||||
"/cost", // cost 根路由
|
||||
"/cost/profitImpactAnalysis", // cost 子菜单(完整路径)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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: {}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -39,7 +39,7 @@ export default {
|
||||
maxHeight: {
|
||||
type: [Number, String], // 支持数字(如300)或字符串(如'300px')
|
||||
required: false,
|
||||
default: 200 // 原固定值,作为默认 fallback
|
||||
default: 200 // 原固定值,作为默认 fallback
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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" 字段
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 表示替换现有配置
|
||||
|
||||
@@ -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 // 本月值
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
<div class="lineBottom" style="height: 210px; width: 100%">
|
||||
<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 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<!-- 显示累计值,并绑定颜色类 -->
|
||||
<div class="accumulated-value" :class="injectData.status">
|
||||
{{ injectData.accumulated }} <!-- 显示累计数据 -->
|
||||
{{ injectData.total }} <!-- 显示累计数据 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,52 +1,96 @@
|
||||
<template>
|
||||
<div class="coreItem">
|
||||
<div class="item" @click="handleRoute(item.route)" v-for="(item, index) in itemList" :key="index">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="item-content">
|
||||
<div class="content-wrapper">
|
||||
<div class="left">
|
||||
<div class="number" style="color: rgba(103, 103, 103, 0.79);">{{ item.targetValue }}</div>
|
||||
<div class="title" style="color: rgba(134, 134, 135, 1);">目标值</div>
|
||||
<div>
|
||||
<div class="coreItem">
|
||||
<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">
|
||||
<div class="left">
|
||||
<div class="number" style="color: rgba(103, 103, 103, 0.79);">{{ item.targetValue }}</div>
|
||||
<div class="title" style="color: rgba(134, 134, 135, 1);">目标值</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<!-- 实际值:根据 实际值≥目标值 动态绑定类名 -->
|
||||
<div class="right">
|
||||
<div class="number" :class="{
|
||||
'number-exceed': item.currentValue >= item.targetValue,
|
||||
'number-below': item.currentValue < item.targetValue
|
||||
}">
|
||||
{{ item.currentValue }}
|
||||
</div>
|
||||
<div class="title" style="color: rgba(134, 134, 135, 1);">实际值</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<!-- 实际值:根据 实际值≥目标值 动态绑定类名 -->
|
||||
<div class="right">
|
||||
<div class="number" :class="{
|
||||
'number-exceed': item.currentValue >= item.targetValue,
|
||||
'number-below': item.currentValue < item.targetValue
|
||||
}">
|
||||
{{ item.currentValue }}
|
||||
|
||||
<!-- 进度条:同步绑定类名 -->
|
||||
<div class="progress-group">
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" :style="{ width: item.progressWidth + '%' }" :class="{
|
||||
'bar-exceed': item.currentValue >= item.targetValue,
|
||||
'bar-below': item.currentValue < item.targetValue
|
||||
}"></div>
|
||||
</div>
|
||||
<div class="title" style="color: rgba(134, 134, 135, 1);">实际值</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
|
||||
<!-- 进度条:同步绑定类名 -->
|
||||
<div class="progress-group">
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" :style="{ width: item.progressWidth + '%' }" :class="{
|
||||
'bar-exceed': item.currentValue >= item.targetValue,
|
||||
'bar-below': item.currentValue < item.targetValue
|
||||
}"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 完成率:同步绑定类名 -->
|
||||
<div class="yield" style="display: flex;justify-content: space-between;">
|
||||
<div class="progress-percent" :class="{
|
||||
'percent-exceed': item.currentValue >= item.targetValue,
|
||||
'percent-below': item.currentValue < item.targetValue
|
||||
}">完成率</div>
|
||||
<div class="progress-percent" :class="{
|
||||
'percent-exceed': item.currentValue >= item.targetValue,
|
||||
'percent-below': item.currentValue < item.targetValue
|
||||
}">
|
||||
{{ item.progressDisplay }}
|
||||
<!-- 完成率:同步绑定类名 -->
|
||||
<div class="yield" style="display: flex;justify-content: space-between;">
|
||||
<div class="progress-percent" :class="{
|
||||
'percent-exceed': item.currentValue >= item.targetValue,
|
||||
'percent-below': item.currentValue < item.targetValue
|
||||
}">完成率</div>
|
||||
<div class="progress-percent" :class="{
|
||||
'percent-exceed': item.currentValue >= item.targetValue,
|
||||
'percent-below': item.currentValue < item.targetValue
|
||||
}">
|
||||
{{ item.progressDisplay }}
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
@@ -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,24 +275,152 @@ export default {
|
||||
.coreItem {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
// padding: 8px; // 避免边缘item hover阴影被截断
|
||||
}
|
||||
.item {
|
||||
width: 170px;
|
||||
height: 168px;
|
||||
background: #f9fcff;
|
||||
padding: 12px 0px 0px 12px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.item {
|
||||
width: 170px;
|
||||
height: 228px;
|
||||
&:hover {
|
||||
box-shadow: 0px 4px 12px 2px #B5CDE5;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.name {
|
||||
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% - 26px);
|
||||
}
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.line {
|
||||
width: 149px;
|
||||
height: 1px;
|
||||
background: linear-gradient(to left, rgba(255, 0, 0, 0), #cbcbcb);
|
||||
}
|
||||
.left,
|
||||
.right {
|
||||
margin-top: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
/* 实际值 - 基础样式(无颜色) */
|
||||
.number {
|
||||
height: 22px;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
line-height: 22px;
|
||||
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;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #868687;
|
||||
line-height: 14px;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
.progress-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.progress-container {
|
||||
width: 138px;
|
||||
height: 10px;
|
||||
background: #ECEFF7;
|
||||
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;
|
||||
font-weight: 400;
|
||||
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: 12px 0px 17px 12px;
|
||||
padding: 8px 8px 0px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer; // 提示可点击
|
||||
transition: all 0.3s ease; // 动画过渡
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 4px 12px 2px #B5CDE5;
|
||||
transform: translateY(-2px);
|
||||
transform: translateY(-2px); // 轻微上浮增强交互感
|
||||
}
|
||||
|
||||
.name {
|
||||
.unit {
|
||||
height: 18px;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 400;
|
||||
@@ -246,57 +430,51 @@ 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);
|
||||
height: calc(100% - 29px);
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 149px;
|
||||
height: 1px;
|
||||
background: linear-gradient(to left, rgba(255, 0, 0, 0), #cbcbcb);
|
||||
width: 1px;
|
||||
height: 46px;
|
||||
background: linear-gradient(to bottom, rgba(255, 0, 0, 0), #cbcbcb);
|
||||
}
|
||||
|
||||
.left,
|
||||
.right {
|
||||
margin-top: 11px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
width: 100%;
|
||||
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: left;
|
||||
text-align: center;
|
||||
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;
|
||||
@@ -304,7 +482,7 @@ export default {
|
||||
font-size: 12px;
|
||||
color: #868687;
|
||||
line-height: 14px;
|
||||
text-align: left;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@@ -312,57 +490,83 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
width: 138px;
|
||||
width: 280px;
|
||||
height: 10px;
|
||||
background: #ECEFF7;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 进度条 - 基础样式(无颜色) */
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: rgba(98, 213, 180, 1);
|
||||
/* 默认进度条颜色(等于目标值时) */
|
||||
border-radius: 8px;
|
||||
transition: width 0.5s ease;
|
||||
opacity: 0.7;
|
||||
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;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #868687;
|
||||
/* 默认百分比颜色(等于目标值时) */
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 百分比 - 实际值≥目标值(绿色) */
|
||||
.percent-exceed {
|
||||
color: rgba(54, 181, 138, 1) !important;
|
||||
/* 实际值 > 目标值:绿色样式 */
|
||||
.exceed-target {
|
||||
color: rgba(98, 213, 180, 1) !important;
|
||||
/* 文字绿色 */
|
||||
// background: rgba(98, 213, 180, 1) !important;
|
||||
/* 进度条绿色 */
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
/* 百分比 - 实际值<目标值(黄色) */
|
||||
.percent-below {
|
||||
/* 实际值 < 目标值:黄色样式 */
|
||||
.below-target {
|
||||
color: rgba(249, 164, 74, 1) !important;
|
||||
/* 文字黄色 */
|
||||
// background: rgba(249, 164, 74, 1) !important;
|
||||
/* 进度条黄色 */
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.yield {
|
||||
width: 138px;
|
||||
margin-top: 3px;
|
||||
.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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -60,16 +60,13 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
isDropdownShow: false,
|
||||
selectedProfit: '利润总额', // 选中的名称,初始为null
|
||||
selectedProfit: '原片电费', // 选中的名称,初始为null
|
||||
profitOptions: [
|
||||
'利润总额',
|
||||
'销量',
|
||||
'单价',
|
||||
'制造成本',
|
||||
'管理费用',
|
||||
'销售费用',
|
||||
'财务费用',
|
||||
'非经营性利润',
|
||||
'原片电费',
|
||||
'加工电费',
|
||||
'外围电费',
|
||||
'发电量',
|
||||
'日均发电量'
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -56,10 +56,11 @@ export default {
|
||||
value: 100,
|
||||
orderTableData:[],
|
||||
productData: {},
|
||||
heat:{},
|
||||
purchase: {},
|
||||
dateData:{},
|
||||
inventory: {},
|
||||
importantWork: {},
|
||||
importantWork: [],
|
||||
finance: {},
|
||||
cost: {},
|
||||
sale: {},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -147,7 +147,6 @@ export default {
|
||||
"经营性利润"
|
||||
],
|
||||
levelId:1,
|
||||
// timeDim: this.dateData.mode
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
this.monData = res.data.currentMonthData
|
||||
|
||||
@@ -143,7 +143,7 @@ export default {
|
||||
{ offset: 1, color: 'rgba(40, 138, 255, 0)' }
|
||||
])
|
||||
},
|
||||
data: data.rate || [],
|
||||
data: data.rates || [],
|
||||
symbol: 'circle',
|
||||
symbolSize: 6
|
||||
},
|
||||
|
||||
@@ -72,6 +72,7 @@ export default {
|
||||
selectDate:{},
|
||||
monthData: {},
|
||||
ytdData:{},
|
||||
dateData: {},
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -108,9 +108,7 @@ export default {
|
||||
totalData: {},
|
||||
trend: [],
|
||||
relatedData: {},
|
||||
trendName: '原片原料成本',
|
||||
// monthRelatedData: [],
|
||||
// totalRelatedData: [],
|
||||
trendName: '原片原料',
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
overheadName:'',
|
||||
overheadOptions:[
|
||||
{value:'包材',label:'包材'},
|
||||
{value:'备品丶机物料',label:'备品丶机物料'},
|
||||
{value:'备件、机物料',label:'备件、机物料'},
|
||||
{value:'折旧',label:'折旧'},
|
||||
{value:'其他',label:'其他'}
|
||||
]
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -64,7 +64,7 @@ export default {
|
||||
profitOptions: [
|
||||
'原片制造费用成本',
|
||||
'包材',
|
||||
'备品丶机物料',
|
||||
'备件、机物料',
|
||||
'折旧',
|
||||
'其他',
|
||||
]
|
||||
|
||||
@@ -60,9 +60,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
isDropdownShow: false,
|
||||
selectedProfit: '原片原料成本', // 选中的名称,初始为null
|
||||
selectedProfit: '原片原料', // 选中的名称,初始为null
|
||||
profitOptions: [
|
||||
'原片原料成本',
|
||||
'原片原料',
|
||||
'硅砂',
|
||||
'纯碱',
|
||||
'白云石',
|
||||
|
||||
@@ -63,7 +63,7 @@ export default {
|
||||
selectedProfit: '制造费用', // 选中的名称,初始为null
|
||||
profitOptions: [
|
||||
'制造费用',
|
||||
'备品丶机物料',
|
||||
'备件、机物料',
|
||||
'折旧',
|
||||
'其他',
|
||||
]
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user