From 833d0b717734b08c8b32ae057679282be6c2b66d Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期四, 05 六月 2025 16:25:41 +0800
Subject: [PATCH] 首页
---
src/assets/styles/ruoyi.scss | 2
src/views/index-nongtou.vue | 882 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/router/index.js | 2
3 files changed, 884 insertions(+), 2 deletions(-)
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index 2a328ff..14d1b7e 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -197,7 +197,7 @@
}
.el-card__header {
- padding: 14px 15px 7px !important;
+ padding: 7px 15px 7px !important;
min-height: 40px;
}
diff --git a/src/router/index.js b/src/router/index.js
index 64c8440..99fc5a2 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -68,7 +68,7 @@
children: [
{
path: 'index',
- component: () => import('@/views/index'),
+ component: () => import('@/views/index-nongtou'),
name: 'Index',
meta: { title: '棣栭〉', icon: 'dashboard', affix: true }
}
diff --git a/src/views/index-nongtou.vue b/src/views/index-nongtou.vue
new file mode 100644
index 0000000..2ad76fc
--- /dev/null
+++ b/src/views/index-nongtou.vue
@@ -0,0 +1,882 @@
+<template>
+ <div class="project-management-container">
+ <!-- 椤甸潰鏍囬 -->
+<!-- <div class="page-header">-->
+<!-- <h1>椤圭洰绠$悊绯荤粺</h1>-->
+<!-- <div class="user-info">-->
+<!-- <span>娆㈣繋锛寋{ userName }}</span>-->
+<!-- <el-avatar :size="36" :src="userAvatar"></el-avatar>-->
+<!-- </div>-->
+<!-- </div>-->
+
+ <!-- 鏁版嵁姒傝鍗$墖 -->
+ <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-select
+ v-model="selectedMonth"
+ placeholder="閫夋嫨鏈堜唤"
+ style="width: 120px; margin-right: 10px;"
+ @change="updateProgressChart"
+ >
+ <el-option
+ v-for="month in months"
+ :key="month.value"
+ :label="month.label"
+ :value="month.value"
+ ></el-option>
+ </el-select>
+ <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="project" label="鎵�灞為」鐩�"></el-table-column>
+ <el-table-column prop="owner" label="璐熻矗浜�" width="100"></el-table-column>
+ <el-table-column prop="startTime" label="寮�濮嬫椂闂�" width="120"></el-table-column>
+ <el-table-column prop="deadline" label="鎴鏃ユ湡" width="120"></el-table-column>
+ <el-table-column prop="overTime" label="宸茶秴鏃�" width="120"></el-table-column>
+ <el-table-column prop="totalOverTimes" 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';
+
+export default {
+ name: 'ProjectManagement',
+ data() {
+ return {
+ userName: '寮犵粡鐞�',
+ userAvatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
+ overviewData: {
+ totalProjects: 42,
+ inProgress: 28,
+ atRisk: 7,
+ delayed: 5
+ },
+ blockingTasks: [
+ {
+ taskName: '鍙栧緱鍦熷湴鏉冨睘',
+ project: '灏勬椽甯傞厭绮熀鍦板缓璁鹃」鐩�',
+ owner: '鏉庡洓',
+ startTime: '2025-05-15',
+ overTime: '10澶�06灏忔椂',
+ deadline: '2025-06-05',
+ totalOverTimes: 4,
+ status: '绱ф��'
+ },
+ {
+ taskName: '鍙鎬х爺绌舵姤鍛婄敵璇�',
+ project: '灏勬椽甯傞厭绮熀鍦板缓璁鹃」鐩�',
+ owner: '鐜嬩簲',
+ startTime: '2025-05-21',
+ overTime: '8澶�',
+ deadline: '2025-05-30',
+ totalOverTimes: '5',
+ status: '楂橀闄�'
+ },
+ {
+ taskName: '寤鸿宸ョ▼绔e伐楠屾敹鐢宠',
+ project: '灏勬椽甯傚疁灞呭疁涓氬拰缇庝埂鏉戝缓璁鹃」鐩�',
+ owner: '璧靛叚',
+ startTime: '2025-05-24',
+ overTime: '4澶�14灏忔椂',
+ deadline: '2025-06-04',
+ totalOverTimes: '4',
+ status: '寤舵湡'
+ },
+ {
+ taskName: '鐢熶骇寤鸿椤圭洰姘村湡淇濇寔鏂规缂栧埗',
+ project: '灏勬椽甯傚疁灞呭疁涓氬拰缇庝埂鏉戝缓璁鹃」鐩�',
+ owner: '閽变竷',
+ startTime: '2025-06-01',
+ overTime: '4澶�',
+ deadline: '2025-06-07',
+ totalOverTimes: '6',
+ status: '杩涜涓�'
+ },
+ ],
+ progressChart: null,
+ fundChart: null,
+ stageChart: null,
+ // 绛涢�夋暟鎹�
+ selectedMonth: '2025-06',
+ 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: [
+ { id: 'p1', name: '灏勬椽甯傚浗瀹跺偍澶囨灄寤鸿椤圭洰锛堜竴鏈燂級' },
+ { id: 'p2', name: '灏勬椽甯傜櫧缇借倝楦′骇涓氬缓璁鹃」鐩�' },
+ { id: 'p3', name: '閬傚畞甯傚皠娲�2024鈥�2027骞村害涓滃寳鐗囧尯楂樻爣鍑嗗啘鐢板缓璁鹃」鐩�' },
+ { id: 'p4', name: '灏勬椽甯傜幇浠g涓氱ず鑼冨熀鍦板缓璁鹃」鐩�' },
+ { id: 'p5', name: '灏勬椽甯傚疁灞呭疁涓氬拰缇庝埂鏉戝缓璁鹃」鐩�' },
+ { id: 'p6', name: '灏勬椽甯傛脖鐗岄晣缁煎悎姘村埄璁炬柦寤鸿椤圭洰' }
+ ],
+ // 椤圭洰杩涘害妯℃嫙鏁版嵁
+ progressData: {
+ '2025-05': {
+ 'p1': { completed: 30, inProgress: 50, notStarted: 20 },
+ 'p2': { completed: 40, inProgress: 40, notStarted: 20 },
+ 'p3': { completed: 10, inProgress: 60, notStarted: 30 },
+ 'p4': { completed: 60, inProgress: 30, notStarted: 10 },
+ 'p5': { completed: 25, inProgress: 45, notStarted: 30 },
+ 'p6': { completed: 35, inProgress: 35, notStarted: 30 }
+ },
+ '2025-06': {
+ 'p1': { completed: 50, inProgress: 40, notStarted: 10 },
+ 'p2': { completed: 60, inProgress: 30, notStarted: 10 },
+ 'p3': { completed: 30, inProgress: 50, notStarted: 20 },
+ 'p4': { completed: 80, inProgress: 15, notStarted: 5 },
+ 'p5': { completed: 45, inProgress: 35, notStarted: 20 },
+ 'p6': { completed: 55, inProgress: 25, notStarted: 20 }
+ },
+ '2025-07': {
+ 'p1': { completed: 70, inProgress: 25, notStarted: 5 },
+ 'p2': { completed: 80, inProgress: 15, notStarted: 5 },
+ 'p3': { completed: 50, inProgress: 40, notStarted: 10 },
+ 'p4': { completed: 90, inProgress: 10, notStarted: 0 },
+ 'p5': { completed: 65, inProgress: 25, notStarted: 10 },
+ 'p6': { completed: 75, inProgress: 15, notStarted: 10 }
+ },
+ '2025-08': {
+ 'p1': { completed: 90, inProgress: 10, notStarted: 0 },
+ 'p2': { completed: 95, inProgress: 5, notStarted: 0 },
+ 'p3': { completed: 70, inProgress: 25, notStarted: 5 },
+ 'p4': { completed: 100, inProgress: 0, notStarted: 0 },
+ 'p5': { completed: 85, inProgress: 10, notStarted: 5 },
+ 'p6': { completed: 90, inProgress: 5, notStarted: 5 }
+ }
+ },
+ // 璧勯噾浣跨敤妯℃嫙鏁版嵁
+ fundData: {
+ 'p1': {
+ total: 5000,
+ allocated: 3500,
+ remaining: 1500,
+ completed: 2800,
+ sources: {
+ projectCapital: 2000,
+ countyInvestment: 1500,
+ otherInvestment: 1000,
+ governmentInvestment: 500
+ }
+ },
+ 'p2': {
+ total: 3200,
+ allocated: 2500,
+ remaining: 700,
+ completed: 1800,
+ sources: {
+ projectCapital: 1200,
+ countyInvestment: 1000,
+ governmentInvestment: 1000
+ }
+ },
+ 'p3': {
+ total: 4200,
+ allocated: 3000,
+ remaining: 1200,
+ completed: 2200,
+ sources: {
+ projectCapital: 1500,
+ otherInvestment: 1200,
+ governmentInvestment: 1500
+ }
+ },
+ 'p4': {
+ total: 2800,
+ allocated: 2000,
+ remaining: 800,
+ completed: 1500,
+ sources: {
+ projectCapital: 1000,
+ countyInvestment: 800,
+ otherInvestment: 500,
+ governmentInvestment: 500
+ }
+ },
+ 'p5': {
+ total: 3800,
+ allocated: 3000,
+ remaining: 800,
+ completed: 2500,
+ sources: {
+ projectCapital: 1500,
+ countyInvestment: 1000,
+ governmentInvestment: 1300
+ }
+ },
+ 'p6': {
+ total: 4500,
+ allocated: 3500,
+ remaining: 1000,
+ completed: 3000,
+ sources: {
+ projectCapital: 2000,
+ countyInvestment: 1500,
+ otherInvestment: 500,
+ governmentInvestment: 500
+ }
+ }
+ }
+ };
+ },
+ mounted() {
+ this.selectedProjects = this.allProjects.map(p => p.id); // 榛樿鍏ㄩ��
+ this.fundSelectedProjects = this.allProjects.map(p => p.id); // 榛樿鍏ㄩ��
+ this.initCharts();
+ window.addEventListener('resize', this.handleResize);
+ },
+ 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: {
+ 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.stageChart.setOption({
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ }
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ data: ['鍦ㄥ簱', '鍌ㄥ', '鍓嶆湡', '瀹炴柦', '绔e伐'],
+ axisLine: {
+ lineStyle: {
+ color: '#409EFF'
+ }
+ }
+ },
+ yAxis: {
+ type: 'value',
+ axisLine: {
+ lineStyle: {
+ color: '#409EFF'
+ }
+ }
+ },
+ series: [
+ {
+ data: [15, 12, 10, 8, 6, 4, 2],
+ type: 'line',
+ smooth: true,
+ lineStyle: {
+ width: 3,
+ color: '#409EFF'
+ },
+ itemStyle: {
+ color: '#409EFF'
+ },
+ 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)'
+ }
+ ])
+ }
+ }
+ ]
+ });
+ },
+
+ // 鏇存柊椤圭洰杩涘害鍥捐〃鏁版嵁
+ updateProgressChart() {
+ if (!this.progressChart) return;
+
+ const monthData = this.progressData[this.selectedMonth];
+ 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);
+ const inProgressData = filteredProjects.map(p => monthData[p.id].inProgress);
+ const notStartedData = filteredProjects.map(p => monthData[p.id].notStarted);
+
+ 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}%'
+ }
+ }
+ ]
+ });
+ },
+
+ // 鏇存柊璧勯噾浣跨敤鍥捐〃鏁版嵁
+ updateFundChart() {
+ if (!this.fundChart) return;
+
+ const filteredProjects = this.allProjects.filter(p =>
+ this.fundSelectedProjects.includes(p.id)
+ );
+
+ const categories = filteredProjects.map(p => p.name);
+ const allocatedData = filteredProjects.map(p => this.fundData[p.id].allocated);
+ const remainingData = filteredProjects.map(p => this.fundData[p.id].remaining);
+
+ // 璧勯噾鏉ユ簮鏁版嵁
+ const projectCapitalData = filteredProjects.map(p =>
+ this.fundData[p.id].sources.projectCapital || 0
+ );
+ const countyInvestmentData = filteredProjects.map(p =>
+ this.fundData[p.id].sources.countyInvestment || 0
+ );
+ const otherInvestmentData = filteredProjects.map(p =>
+ this.fundData[p.id].sources.otherInvestment || 0
+ );
+ const governmentInvestmentData = filteredProjects.map(p =>
+ this.fundData[p.id].sources.governmentInvestment || 0
+ );
+
+ this.fundChart.setOption({
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ },
+ formatter: function(params) {
+ let result = params[0].name + '<br/>';
+ // 璧勯噾鎷ㄤ粯鍜屽墿浣�
+ result += `璧勯噾鎷ㄤ粯: ${params[0].value}涓囧厓<br/>`;
+ result += `鍓╀綑閲戦: ${params[1].value}涓囧厓<br/>`;
+ result += `鎬婚噾棰�: ${params[0].value + params[1].value}涓囧厓<br/>`;
+ result += `瀹屾垚鎶曡祫: ${params[0].axisValueLabel}涓囧厓<br/><br/>`;
+
+ // 璧勯噾鏉ユ簮
+ result += '<strong>璧勯噾鏉ユ簮鏋勬垚:</strong><br/>';
+ result += `椤圭洰鏈噾: ${params[2].value}涓囧厓<br/>`;
+ result += `鍘�(甯傘�佸尯)鎶曡祫: ${params[3].value}涓囧厓<br/>`;
+ result += `鍏朵粬鎶曡祫: ${params[4].value}涓囧厓<br/>`;
+ result += `鏀垮簻鎶曡祫: ${params[5].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: 'total',
+ emphasis: {
+ focus: 'series'
+ },
+ data: allocatedData,
+ itemStyle: {
+ color: '#409EFF'
+ },
+ label: {
+ show: true,
+ position: 'inside',
+ formatter: '{c}'
+ }
+ },
+ {
+ name: '鍓╀綑閲戦',
+ type: 'bar',
+ stack: 'total',
+ emphasis: {
+ focus: 'series'
+ },
+ data: remainingData,
+ itemStyle: {
+ color: '#E6A23C'
+ },
+ label: {
+ show: true,
+ position: 'inside',
+ formatter: '{c}'
+ }
+ },
+ {
+ name: '椤圭洰鏈噾',
+ type: 'bar',
+ stack: 'sources',
+ emphasis: {
+ focus: 'series'
+ },
+ data: projectCapitalData,
+ itemStyle: {
+ color: '#67C23A'
+ }
+ },
+ {
+ name: '鍘�(甯傘�佸尯)鎶曡祫',
+ type: 'bar',
+ stack: 'sources',
+ emphasis: {
+ focus: 'series'
+ },
+ data: countyInvestmentData,
+ itemStyle: {
+ color: '#F56C6C'
+ }
+ },
+ {
+ name: '鍏朵粬鎶曡祫',
+ type: 'bar',
+ stack: 'sources',
+ emphasis: {
+ focus: 'series'
+ },
+ data: otherInvestmentData,
+ itemStyle: {
+ color: '#909399'
+ }
+ },
+ {
+ name: '鏀垮簻鎶曡祫',
+ type: 'bar',
+ stack: 'sources',
+ emphasis: {
+ focus: 'series'
+ },
+ data: governmentInvestmentData,
+ itemStyle: {
+ color: '#8E44AD'
+ }
+ }
+ ]
+ });
+ },
+
+ // 鏇存柊鎵�鏈夊浘琛�
+ 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) {
+ this.$message.info(`鏌ョ湅浠诲姟璇︽儏: ${task.taskName}`);
+ },
+ 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>
--
Gitblit v1.8.0