<template>
|
<div class="project-management-container">
|
<!-- 数据概览卡片 -->
|
<div class="overview-cards">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #409EFF20;">
|
<i class="el-icon-s-data" style="color: #409EFF;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">项目总数</div>
|
<div class="card-value">{{ overviewData.totalProjects }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #67C23A20;">
|
<i class="el-icon-success" style="color: #67C23A;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">进行中</div>
|
<div class="card-value">{{ overviewData.inProgress }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #E6A23C20;">
|
<i class="el-icon-warning" style="color: #E6A23C;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">有风险</div>
|
<div class="card-value">{{ overviewData.atRisk }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #F56C6C20;">
|
<i class="el-icon-error" style="color: #F56C6C;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">已延期</div>
|
<div class="card-value">{{ overviewData.delayed }}</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 主要内容区域 -->
|
<div class="main-content">
|
<!-- 左侧内容 -->
|
<div class="left-content">
|
<!-- 项目进度图表 -->
|
<el-card class="chart-card" style="min-height: 400px" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex: 1">项目进度统计</div>
|
<div style="flex: 3;display: flex;justify-content: flex-end">
|
<el-date-picker
|
v-model="selectedMonth"
|
type="month"
|
placeholder="选择月份"
|
style="width: 180px; margin-right: 10px;"
|
@change="updateProgressChart"
|
format="yyyy-MM"
|
value-format="yyyy-MM"
|
></el-date-picker>
|
<el-select
|
v-model="selectedProjects"
|
multiple
|
collapse-tags
|
placeholder="选择项目"
|
style="width: 350px; margin-right: 10px;"
|
@change="updateProgressChart"
|
>
|
<el-option
|
v-for="project in allProjects"
|
:key="project.id"
|
:label="project.name"
|
:value="project.id"
|
></el-option>
|
</el-select>
|
<!-- <el-button type="text" @click="showDetail">详情</el-button>-->
|
</div>
|
</div>
|
<div class="chart-container" ref="progressChart" style="height: 400px;"></div>
|
</el-card>
|
|
<!-- 卡点任务列表 -->
|
<el-card class="blocking-tasks-card" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex: 1">推进卡点</div>
|
<div style="flex: 3; display: flex; justify-content: flex-end">
|
<!-- <el-button type="text">全部</el-button>-->
|
</div>
|
</div>
|
<el-table :data="blockingTasks" style="width: 100%" height="250">
|
<el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
|
<el-table-column prop="checkPointInfo.projectName" label="所属项目"></el-table-column>
|
<el-table-column prop="customerTaskInfo.promoterName" label="负责人" width="100"></el-table-column>
|
<el-table-column prop="startTime" label="开始时间" width="120"></el-table-column>
|
<el-table-column prop="endTime" label="截止日期" width="120"></el-table-column>
|
<el-table-column prop="totalOverTime" label="已超时" width="120"></el-table-column>
|
<el-table-column prop="overTimeCount" label="累计超时次数" width="120" align="center"></el-table-column>
|
<el-table-column label="操作" width="80">
|
<template slot-scope="scope">
|
<el-button size="mini" @click="handleTaskDetail(scope.row)">查看</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-card>
|
</div>
|
|
<!-- 右侧内容 -->
|
<div class="right-content">
|
<!-- 资金使用情况 -->
|
<el-card class="chart-card" style="min-height: 400px" shadow="hover">
|
<div slot="header" class="clearfix">
|
<span>资金情况</span>
|
<div style="float: right;">
|
<el-select
|
v-model="fundSelectedProjects"
|
multiple
|
collapse-tags
|
placeholder="选择项目"
|
style="width: 350px; margin-right: 10px;"
|
@change="updateFundChart"
|
>
|
<el-option
|
v-for="project in allProjects"
|
:key="project.id"
|
:label="project.name"
|
:value="project.id"
|
></el-option>
|
</el-select>
|
<!-- <el-button type="text" @click="showFundDetail">详情</el-button>-->
|
</div>
|
</div>
|
<div class="chart-container" ref="fundChart" style="height: 400px;"></div>
|
</el-card>
|
|
<!-- 项目阶段统计 -->
|
<el-card class="chart-card" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex:1">项目阶段统计</div>
|
<div style="flex:3;display: flex;justify-content: flex-end">
|
<!-- <el-button type="text">详情</el-button>-->
|
</div>
|
</div>
|
<div class="chart-container" ref="stageChart" style="height: 250px;"></div>
|
</el-card>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import * as echarts from 'echarts';
|
import {
|
getCodingCount,
|
getFundingStatus,
|
getTaskStatus,
|
getProjectSelectList,
|
getStageCount,
|
getProjectAdvanceCheckPoint
|
} from '@/api/index/index.js'
|
export default {
|
name: 'ProjectManagement',
|
data() {
|
return {
|
pathMap:{
|
'在库': { path: '/projectEngineering/project/projectLibrary' },
|
'储备': {
|
path: '/projectEngineering/project/reserveProjects',
|
query: { projectPhase: 1 }
|
},
|
'前期': {
|
path:'/projectEngineering/project/previousProjects',
|
query: { projectPhase: 2 }
|
},
|
'实施': {
|
path:'/projectEngineering/project/implementationProject',
|
query: { projectPhase: 3 }
|
},
|
'竣工': {
|
path:'/projectEngineering/project/completedProjects',
|
query: { projectPhase: 4 }
|
}
|
},
|
userName: '张经理',
|
userAvatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
|
overviewData: {
|
totalProjects: 0,
|
inProgress: 0,
|
atRisk: 0,
|
delayed: 0
|
},
|
blockingTasks: [
|
],
|
progressChart: null,
|
fundChart: null,
|
stageChart: null,
|
// 筛选数据
|
selectedMonth: this.getCurrentMonth(),
|
months: [
|
{ value: '2025-05', label: '2025年5月' },
|
{ value: '2025-06', label: '2025年6月' },
|
{ value: '2025-07', label: '2025年7月' },
|
{ value: '2025-08', label: '2025年8月' }
|
],
|
selectedProjects: [],
|
fundSelectedProjects: [],
|
allProjects: [
|
],
|
// 项目进度模拟数据
|
progressData: {},
|
fundData: {}
|
};
|
},
|
mounted() {
|
this.initData();
|
|
},
|
beforeDestroy() {
|
window.removeEventListener('resize', this.handleResize);
|
if (this.progressChart) {
|
this.progressChart.dispose();
|
}
|
if (this.fundChart) {
|
this.fundChart.dispose();
|
}
|
if (this.stageChart) {
|
this.stageChart.dispose();
|
}
|
},
|
methods: {
|
getCurrentMonth() {
|
const now = new Date();
|
const year = now.getFullYear();
|
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要+1
|
return `${year}-${month}`;
|
},
|
async initData(){
|
|
await this.initSelect();
|
await this.initCodingCount();
|
await this.initCharts();
|
await this.initProjectAdvanceCheckPoint();
|
window.addEventListener('resize', this.handleResize);
|
},
|
initProjectAdvanceCheckPoint(){
|
getProjectAdvanceCheckPoint().then(res =>{
|
if (res.code === 200){
|
this.blockingTasks = res.data;
|
|
}
|
|
})
|
},
|
initCodingCount(){
|
getCodingCount().then(res =>{
|
if(res.code === 200){
|
this.overviewData.totalProjects = res.data.total;
|
this.overviewData.inProgress = res.data.green;
|
this.overviewData.atRisk = res.data.yellow;
|
this.overviewData.delayed = res.data.red;
|
}
|
})
|
|
},
|
initSelect(){
|
getProjectSelectList().then(res =>{
|
if (res.code === 200){
|
this.allProjects = Object.entries(res.data).map(([id, name]) => ({
|
id: id, // 项目ID(如"151")
|
name: name // 项目名称(如"射洪市万林钢厂片区棚户区改造项目")
|
}));
|
this.selectedProjects = this.allProjects.slice(0, 5).map(p => p.id);
|
this.fundSelectedProjects = this.allProjects.slice(0, 5).map(p => p.id);
|
}
|
})
|
},
|
initCharts() {
|
// 初始化项目进度图表
|
this.progressChart = echarts.init(this.$refs.progressChart);
|
this.updateProgressChart();
|
|
// 初始化资金使用情况图表
|
this.fundChart = echarts.init(this.$refs.fundChart);
|
this.updateFundChart();
|
|
// 初始化项目阶段统计图表
|
this.stageChart = echarts.init(this.$refs.stageChart);
|
this.updateStageChart();
|
|
},
|
updateStageChart(){
|
if (!this.stageChart) return;
|
getStageCount().then(res =>{
|
if (res.code ===200){
|
const xData = res.data.xData || [];
|
const yData = res.data.yData || [];
|
this.stageChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
triggerOn: 'mousemove',
|
axisPointer: {
|
type: 'shadow'
|
}
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: xData,
|
axisLine: {
|
lineStyle: {
|
color: '#409EFF'
|
}
|
}
|
},
|
yAxis: {
|
type: 'value',
|
axisLine: {
|
lineStyle: {
|
color: '#409EFF'
|
}
|
}
|
},
|
series: [
|
{
|
data: yData,
|
type: 'line',
|
smooth: true,
|
lineStyle: {
|
width: 3,
|
color: '#409EFF'
|
},
|
itemStyle: {
|
color: '#409EFF'
|
},
|
emphasis: {
|
itemStyle: {
|
color: '#1989fa',
|
size: 10
|
},
|
lineStyle: {
|
width: 4
|
},
|
// 整个系列区域hover都显示手型
|
cursor: 'pointer',
|
areaStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{ offset: 0, color: 'rgba(25, 137, 250, 0.6)' },
|
{ offset: 1, color: 'rgba(25, 137, 250, 0.2)' }
|
])
|
}
|
},
|
areaStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{
|
offset: 0,
|
color: 'rgba(64, 158, 255, 0.5)'
|
},
|
{
|
offset: 1,
|
color: 'rgba(64, 158, 255, 0.1)'
|
}
|
])
|
},
|
triggerLineEvent: true,
|
triggerAreaEvent: true
|
}
|
]
|
});
|
|
this.stageChart.off('click');
|
this.stageChart.on('click', (params) => {
|
console.log('图表点击参数:', params);
|
// 仅点击系列区域时处理
|
if (params.componentType === 'series') {
|
// 1. 将点击的像素坐标转换为X轴索引
|
const pointInPixel = [params.event.offsetX, params.event.offsetY];
|
const xAxisIndex = 0; // X轴索引(只有一个X轴,固定为0)
|
const xAxisValue = this.stageChart.convertFromPixel({ seriesIndex: 0, axisIndex: xAxisIndex }, pointInPixel)[0];
|
|
// 2. 计算所属的X轴标签索引(取整)
|
const targetIndex = Math.max(0, Math.min(xData.length - 1, Math.floor(xAxisValue)));
|
// 3. 获取对应标签
|
const targetLabel = xData[targetIndex];
|
|
// 4. 匹配pathMap跳转(无匹配则走默认)
|
if (targetLabel && Object.keys(this.pathMap).includes(targetLabel)) {
|
console.log(targetLabel)
|
const targetRoute = this.pathMap[targetLabel] || { path: '/projectEngineering/project/projectLibrary' };
|
this.$router.push(targetRoute);
|
}
|
}
|
});
|
}
|
})
|
},
|
// 更新项目进度图表数据
|
updateProgressChart() {
|
if (!this.progressChart) return;
|
const form ={
|
startTime:this.selectedMonth
|
}
|
getTaskStatus(form).then(res => {
|
if (res.code === 200) {
|
// 从响应数据中提取流程统计信息
|
const processStatistics = res.data || [];
|
|
|
// 将后端数据转换为前端需要的格式
|
const monthData = {};
|
processStatistics.forEach(item => {
|
// 假设后端返回的项目ID字段是 projectId,需要和前端的 allProjects 中的 id 匹配
|
monthData[item.id] = {
|
completed: item.completed || 0,
|
inProgress: item.inProgress || 0,
|
notStarted: item.notStarted || 0
|
};
|
});
|
// 筛选选中的项目
|
const filteredProjects = this.allProjects.filter(p =>
|
this.selectedProjects.includes(p.id)
|
);
|
|
// 准备图表数据
|
const categories = filteredProjects.map(p => p.name);
|
const completedData = filteredProjects.map(p => monthData[p.id]?.completed || 0);
|
const inProgressData = filteredProjects.map(p => monthData[p.id]?.inProgress || 0);
|
const notStartedData = filteredProjects.map(p => monthData[p.id]?.notStarted || 0);
|
|
// 更新图表配置
|
this.progressChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
},
|
formatter: function(params) {
|
let result = params[0].name + '<br/>';
|
params.forEach(param => {
|
result += `${param.seriesName}: ${param.value}%<br/>`;
|
});
|
// result += `总计: ${params.reduce((sum, param) => sum + param.value, 0)}%`;
|
return result;
|
}
|
},
|
legend: {
|
data: ['已完成事项', '进行中事项', '未开始事项']
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'value',
|
max: 100,
|
axisLabel: {
|
formatter: '{value}%'
|
}
|
},
|
yAxis: {
|
type: 'category',
|
data: categories
|
},
|
series: [
|
{
|
name: '已完成事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: completedData,
|
itemStyle: {
|
color: '#67C23A'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
},
|
{
|
name: '进行中事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: inProgressData,
|
itemStyle: {
|
color: '#409EFF'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
},
|
{
|
name: '未开始事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: notStartedData,
|
itemStyle: {
|
color: '#E6A23C'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
}
|
]
|
});
|
}
|
}).catch(error => {
|
// 错误处理
|
this.progressChart.hideLoading();
|
console.error('获取任务状态数据失败:', error);
|
// 可以显示错误提示或使用默认数据
|
});
|
},
|
|
// 更新资金使用图表数据
|
updateFundChart() {
|
if (!this.fundChart) return;
|
getFundingStatus().then(res=> {
|
if (res.code === 200) {
|
const fundingData = res.data || [];
|
const data = {};
|
fundingData.forEach(item => {
|
// 仅组装 SQL 查询返回的 9 个字段,字段名与 VO 一致
|
data[item.projectId] = {
|
id: item.projectId || '', // 项目ID(关联键)
|
totalInvestment: item.totalInvestment || '0', // 项目总投资额
|
principal: item.principal || '0', // 项目本金
|
governmentInvestmentTotal: item.governmentInvestmentTotal || '0', // 政府投资总额
|
centralInvestmentTotal: item.centralInvestmentTotal || '0', // 中央投资总额
|
provincialInvestmentTotal: item.provincialInvestmentTotal || '0', // 省级投资总额
|
cityInvestmentTotal: item.cityInvestmentTotal || '0', // 市(州)投资总额
|
countyInvestmentTotal: item.countyInvestmentTotal || '0', // 县(市、区)投资总额
|
otherInvestmentTotal: item.otherInvestmentTotal || '0', // 其他投资总额
|
enterpriseSelfRaisedTotal: item.enterpriseSelfRaisedTotal || '0',
|
foreignInvestmentTotal: item.foreignInvestmentTotal || '0',
|
bankLoan: item.bankLoan || '0',//银行贷款
|
domesticLoanTotal: item.domesticLoanTotal || '0',
|
};
|
});
|
console.log(data)
|
const filteredProjects = this.allProjects.filter(p =>
|
this.fundSelectedProjects.includes(p.id)
|
);
|
const categories = filteredProjects.map(p => p.name);
|
// console.log(categories)
|
// const allocatedData = filteredProjects.map(p => data[p.id].allocated);
|
// console.log(allocatedData)
|
// const remainingData = filteredProjects.map(p => data[p.id].remaining);
|
// console.log(remainingData)
|
|
// 资金来源数据 本金
|
const projectCapitalData = filteredProjects.map(p =>
|
data[p.id].principal || 0
|
);
|
//总投资
|
const totalInvestmentData = filteredProjects.map(p =>
|
data[p.id].totalInvestment || 0
|
);
|
// 县(市、区)投资总额
|
const countyInvestmentData = filteredProjects.map(p =>
|
data[p.id].countyInvestmentTotal || 0
|
);
|
// 市(州)投资总额
|
const cityInvestmentTotalData = filteredProjects.map(p =>
|
data[p.id].cityInvestmentTotal || 0)
|
// 省级投资总额
|
const provincialInvestmentTotalData = filteredProjects.map(p =>
|
data[p.id].provincialInvestmentTotal || 0)
|
//政府投资
|
const governmentInvestmentData = filteredProjects.map(p =>
|
data[p.id].governmentInvestmentTotal || 0
|
);
|
//其他投资
|
const otherInvestmentData = filteredProjects.map(p =>
|
data[p.id].otherInvestmentTotal || 0
|
);
|
//中央
|
const centralInvestmentTotalData = filteredProjects.map(p =>
|
data[p.id].centralInvestmentTotal || 0
|
);
|
//企业自筹
|
const enterpriseSelfRaisedTotalData = filteredProjects.map(p =>
|
data[p.id].enterpriseSelfRaisedTotal || 0
|
);
|
//外商投资
|
const foreignInvestmentTotalData = filteredProjects.map(p =>
|
data[p.id].foreignInvestmentTotal || 0
|
);
|
const bankLoanData = filteredProjects.map(p =>
|
data[p.id].bankLoan || 0
|
);
|
const domesticLoanTotalData = filteredProjects.map(p =>
|
data[p.id].domesticLoanTotal || 0
|
);
|
|
|
this.fundChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
confine: true,
|
axisPointer: {
|
type: 'shadow'
|
},
|
zIndex: 9999,
|
|
formatter: function(params) {
|
let result = params[0].name + '<br/>';
|
// 资金拨付和剩余
|
// result += `资金拨付: ${params[0].value}万元<br/>`;
|
// result += `剩余金额: ${params[1].value}万元<br/>`;
|
const value1 = Number(params[0].value) || 0;
|
const value2 = Number(params[1].value) || 0;
|
result += `总金额: ${value1 + value2}万元<br/>`;
|
// result += `完成投资: ${params[0].axisValueLabel}万元<br/><br/>`;
|
//
|
// // 资金来源
|
result += '<strong>资金来源构成:</strong><br/>';
|
result += `项目本金: ${params[0].value}万元<br/>`;
|
result += `县(市、区)投资: ${params[2].value}万元<br/>`;
|
result += `市(州)投资: ${params[3].value}万元<br/>`;
|
result += `省级投资: ${params[4].value}万元<br/>`;
|
result += `中央投资: ${params[5].value}万元<br/>`;
|
result += `政府投资: ${params[6].value}万元<br/>`;
|
result += `其他投资: ${params[7].value}万元<br/>`;
|
result += `企业自筹: ${params[8].value}万元<br/>`;
|
result += `外商投资: ${params[9].value}万元<br/>`;
|
result += `银行贷款: ${params[10].value}万元<br/>`;
|
result += `国内贷款: ${params[11].value}万元<br/>`;
|
return result;
|
}
|
},
|
legend: {
|
data: [
|
// '剩余金额', '资金拨付',
|
'项目本金','项目总投资', '县(市、区)投资','市(州)投资','省级投资','中央投资', '政府投资', '其他投资',
|
'企业自筹', '外商投资', '银行贷款', '国内贷款',]
|
},
|
grid: {
|
top: '30%',
|
left: '3%',
|
right: '4%',
|
bottom: '5%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: categories,
|
axisLabel: {
|
interval: 0,
|
rotate: 30
|
}
|
},
|
yAxis: {
|
type: 'value',
|
name: '金额(万元)'
|
},
|
series: [
|
{
|
name: '项目本金',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: projectCapitalData,
|
itemStyle: {
|
color: '#42B983' // 主绿色:项目核心自有资金
|
}
|
},
|
{
|
name: '项目总投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: totalInvestmentData,
|
itemStyle: {
|
color: '#36CFC9' // 青绿色:总投资汇总数据
|
}
|
},
|
{
|
name: '县(市、区)投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: countyInvestmentData,
|
itemStyle: {
|
color: '#A0D911' // 浅黄绿色:县级投资
|
}
|
},
|
{
|
name: '市(州)投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: cityInvestmentTotalData,
|
itemStyle: {
|
color: '#7CB305' // 亮绿色:市州级投资
|
}
|
},
|
{
|
name: '省级投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: provincialInvestmentTotalData,
|
itemStyle: {
|
color: '#40A9FF' // 中蓝色:省级投资
|
}
|
},
|
{
|
name: '中央投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: centralInvestmentTotalData,
|
itemStyle: {
|
color: '#1890FF' // 深蓝色:中央投资(层级最高)
|
}
|
},
|
{
|
name: '政府投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: governmentInvestmentData,
|
itemStyle: {
|
color: '#8E44AD' // 紫色:政府投资总额(汇总项)
|
}
|
},{
|
name: '其他投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: otherInvestmentData,
|
itemStyle: {
|
color: '#909399' // 深灰色:其他投资
|
}
|
},
|
{
|
name: '企业自筹',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: enterpriseSelfRaisedTotalData,
|
itemStyle: {
|
color: '#e6cb6d' // 深灰色:其他投资
|
}
|
},
|
{
|
name: '外商投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: foreignInvestmentTotalData,
|
itemStyle: {
|
color: '#f443b9' // 深灰色:其他投资
|
}
|
},{
|
name: '银行贷款',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: bankLoanData,
|
itemStyle: {
|
color: '#bd5fd8' // 深灰色:其他投资
|
}
|
},{
|
name: '国内贷款',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: domesticLoanTotalData,
|
itemStyle: {
|
color: '#4373d3' // 深灰色:其他投资
|
}
|
}
|
]
|
});
|
this.fundChart.on('click', (params) => { // 这里改为箭头函数
|
const clickedProject = filteredProjects[params.dataIndex];
|
const projectId = clickedProject ? clickedProject.id : '无';
|
const audit = 1;
|
// 此时 this 指向 Vue 组件,可正常访问 $router
|
this.$router.push({
|
path: '/projectEngineering/project/ProjectDetails',
|
query: { projectId: projectId, disabled: 'true', audit: audit }
|
});
|
});
|
}
|
});
|
|
|
},
|
removeStore() {
|
localStorage.removeItem("projectForm")
|
localStorage.removeItem("investmentForm")
|
localStorage.removeItem("investmentFundsForm")
|
localStorage.removeItem("legalPersonForm")
|
localStorage.removeItem("policyInfoForm")
|
localStorage.removeItem("documentsInfoForm")
|
},
|
// 更新所有图表
|
updateCharts() {
|
this.updateProgressChart();
|
this.updateFundChart();
|
},
|
|
handleResize() {
|
if (this.progressChart) {
|
this.progressChart.resize();
|
}
|
if (this.fundChart) {
|
this.fundChart.resize();
|
}
|
if (this.stageChart) {
|
this.stageChart.resize();
|
}
|
},
|
getStatusTagType(status) {
|
const map = {
|
'紧急': 'danger',
|
'高风险': 'warning',
|
'延期': 'info',
|
'进行中': 'primary'
|
};
|
return map[status] || '';
|
},
|
handleTaskDetail(task) {
|
console.log(task)
|
const queryParams= {
|
taskName: '',
|
taskType: 'todo',
|
pageSize: 5,
|
currentPage: 1,
|
projectId: null,
|
processDefId: null,
|
processInsId: null,
|
deployId: null,
|
processName: '' // 流程名称
|
}
|
this.$router.push({ path: '/flowable/task/myProcess/detail/index',
|
query: {
|
projectName: task.checkPointInfo.projectName,
|
flowName: task.checkPointInfo.processName,
|
procInsId: task.checkPointInfo.processInstanceId,
|
deployId: task.checkPointInfo.deployId,
|
taskId: task.id,
|
projectId: task.checkPointInfo.id,
|
goBackParams: queryParams
|
}})
|
},
|
showDetail() {
|
this.$message.info(`查看${this.selectedMonth}月份的项目进度详情`);
|
},
|
showFundDetail() {
|
this.$message.info('查看资金使用详情');
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.project-management-container {
|
padding: 20px;
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
}
|
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding-bottom: 15px;
|
border-bottom: 1px solid #ebeef5;
|
}
|
|
.page-header h1 {
|
color: #409EFF;
|
margin: 0;
|
}
|
|
.user-info {
|
display: flex;
|
align-items: center;
|
}
|
|
.user-info span {
|
margin-right: 10px;
|
color: #606266;
|
}
|
|
.overview-cards {
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 20px;
|
margin-bottom: 20px;
|
}
|
|
.overview-card {
|
border-radius: 8px;
|
border-top: 3px solid #409EFF;
|
}
|
|
.overview-card:nth-child(1) {
|
border-top-color: #409EFF;
|
}
|
.overview-card:nth-child(2) {
|
border-top-color: #67C23A;
|
}
|
.overview-card:nth-child(3) {
|
border-top-color: #E6A23C;
|
}
|
.overview-card:nth-child(4) {
|
border-top-color: #F56C6C;
|
}
|
|
.card-content {
|
display: flex;
|
align-items: center;
|
padding: 10px 0;
|
}
|
|
.card-icon {
|
width: 50px;
|
height: 50px;
|
border-radius: 50%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-right: 15px;
|
}
|
|
.card-icon i {
|
font-size: 24px;
|
}
|
|
.card-info {
|
flex: 1;
|
}
|
|
.card-title {
|
font-size: 14px;
|
color: #909399;
|
margin-bottom: 5px;
|
}
|
|
.card-value {
|
font-size: 24px;
|
font-weight: bold;
|
color: #303133;
|
}
|
|
.main-content {
|
display: grid;
|
grid-template-columns: 2fr 1fr;
|
gap: 20px;
|
}
|
|
.chart-card, .blocking-tasks-card {
|
border-radius: 8px;
|
margin-bottom: 20px;
|
border: 1px solid #ebeef5;
|
}
|
|
.chart-card >>> .el-card__header {
|
background-color: #f5f7fa;
|
border-bottom: 1px solid #ebeef5;
|
padding: 12px 20px;
|
font-weight: bold;
|
color: #409EFF;
|
}
|
|
.blocking-tasks-card >>> .el-card__header {
|
background-color: #f5f7fa;
|
border-bottom: 1px solid #ebeef5;
|
padding: 12px 20px;
|
font-weight: bold;
|
color: #409EFF;
|
}
|
|
.chart-container {
|
width: 100%;
|
}
|
|
.row {
|
display: flex;
|
align-items: center;
|
height: 36px;
|
}
|
</style>
|