Files
fad_oa/ruoyi-ui/src/views/oa/project/dashboard/components/StatusChart.vue
2026-04-13 17:04:38 +08:00

146 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>