146 lines
4.0 KiB
Vue
146 lines
4.0 KiB
Vue
<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> |