Files
fad_oa/ruoyi-ui/src/views/oa/project/dashboard/components/StatusChart.vue

146 lines
4.0 KiB
Vue
Raw Normal View History

2026-04-13 17:04:38 +08:00
<template>
<div ref="chart" class="chart" style="width: 100%; height: 300px"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'StatusChart',
data () {
return {
chart: null,
}
},
computed: {
// 从vuex获取项目列表
projects () {
return this.$store.getters.projectList || [];
},
// 按规则统计各状态的项目数量
chartData () {
// 初始化各状态计数
const statusCount = {
'已完成': 0,
'已逾期': 0,
'即将到期': 0,
'进行中': 0
};
// 获取当前日期(仅保留年月日,消除时分秒影响)
const today = new Date();
today.setHours(0, 0, 0, 0);
this.projects.forEach(project => {
// 优先判断已完成状态
if (project.projectStatus == 1) {
statusCount['已完成']++;
} else {
// 处理未完成项目的时间判断
if (project.finishTime) {
try {
// 将finishTime转换为日期对象兼容YYYY-MM-dd hh:mm:ss格式
const finishDate = new Date(project.finishTime);
finishDate.setHours(0, 0, 0, 0); // 统一时间维度
// 计算间隔天数(毫秒转天)
const timeDiff = finishDate - today;
const dayDiff = timeDiff / (1000 * 60 * 60 * 24);
if (dayDiff < 0) {
// 已逾期:截止日期已过
statusCount['已逾期']++;
} else if (dayDiff < 10) {
// 即将到期截止日期在3天内
statusCount['即将到期']++;
} else {
// 其他情况:进行中
statusCount['进行中']++;
}
} catch (e) {
// 日期格式错误时默认归为进行中
console.error('日期格式错误:', project.finishTime, e);
statusCount['进行中']++;
}
} else {
// 无截止日期的未完成项目归为进行中
statusCount['进行中']++;
}
}
});
// 转换为ECharts所需的数据格式过滤数量为0的状态
return Object.entries(statusCount)
.filter(([_, value]) => value > 0)
.map(([name, value]) => {
// 状态颜色映射
const colorMap = {
'已完成': '#1890ff', // 蓝色
'已逾期': '#ff4d4f', // 红色
'即将到期': '#faad14', // 黄色
'进行中': '#52c41a' // 绿色
};
return {
name,
value,
itemStyle: {
color: colorMap[name]
}
};
});
}
},
mounted () {
this.chart = echarts.init(this.$refs.chart);
this.updateChart();
window.addEventListener('resize', this.resize);
},
watch: {
// 监听项目列表变化,更新图表
projects: {
handler: 'updateChart',
deep: true
}
},
methods: {
resize () {
this.chart && this.chart.resize();
},
updateChart () {
if (!this.chart) return;
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{b}: {c}个 ({d}%)' // 显示数量和百分比
},
legend: {
bottom: 10,
textStyle: { fontSize: 12 }
},
series: [{
name: '项目状态',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: { show: false },
emphasis: {
label: { show: true, fontSize: '16', fontWeight: 'bold' }
},
data: this.chartData // 使用计算后的图表数据
}]
});
}
},
beforeDestroy () {
window.removeEventListener('resize', this.resize);
this.chart && this.chart.dispose();
}
};
</script>
<style scoped>
.chart {
width: 100%;
height: 100%;
}
</style>