feat(停机统计): 优化停机统计页面并添加图表展示功能

重构停机统计页面,主要变更包括:
1. 添加核心指标卡片展示停机次数、总时长和作业率
2. 新增按天汇总的折线图和按类型汇总的饼图
3. 优化数据展示逻辑,增加无数据状态处理
4. 移除冗余CSS样式,简化DOM结构
5. 添加图表自适应功能,优化移动端显示
This commit is contained in:
砂糖
2026-01-21 13:02:22 +08:00
parent 9d35f39906
commit 8139143ecc
2 changed files with 419 additions and 66 deletions

View File

@@ -87,7 +87,7 @@
<div class="section-header">
<span class="section-title">停机详情</span>
</div>
<div class="detail-list">
<div>
<div v-if="tableData.length === 0" class="empty-state">
<span class="empty-text">暂无停机记录</span>
</div>
@@ -104,7 +104,7 @@
<div class="section-header">
<span class="section-title">停机趋势</span>
</div>
<div class="chart-wrapper trend-chart" ref="trendChart" id="trendChart"></div>
<div class="chart-wrapper trend-chart" v-show="activeTab !== 'day'" ref="trendChart" id="trendChart"></div>
</div>
</div>
</template>
@@ -342,53 +342,7 @@ export default {
loading.close()
console.log('停机统计响应:', response)
if (response.code === 200 && response.rows && response.rows.length > 0) {
this.tableData = response.rows.map(item => ({
time: this.formatDateTime(item.startDate) + ' - ' + this.formatDateTime(item.endDate),
duration: this.secondsToMinutes(item.duration) + 'min',
remark: item.remark || '-',
machine: item.unit || '-'
}))
const totalDurationSeconds = response.rows.reduce((sum, item) => sum + (Number(item.duration) || 0), 0)
const totalDurationMinutes = this.secondsToMinutes(totalDurationSeconds)
const totalCount = response.rows.length
const totalAvailableMinutes = this.getTotalAvailableMinutes()
const workRate = this.calculateWorkRate(totalDurationMinutes, totalAvailableMinutes)
this.summaryData = [
{ label: '停机时间', value: totalDurationMinutes, unit: 'min' },
{ label: '停机次数', value: totalCount, unit: '次' },
{ label: '作业率', value: workRate, unit: '%' }
]
const crewMap = {}
const typeMap = {}
response.rows.forEach(item => {
const crew = item.crew || '未知班组'
const type = item.stopType || '未知类型'
const durationMinutes = this.secondsToMinutes(item.duration)
crewMap[crew] = (crewMap[crew] || 0) + durationMinutes
typeMap[type] = (typeMap[type] || 0) + durationMinutes
})
this.crewPieData = Object.keys(crewMap).map(crew => ({ name: crew, value: crewMap[crew] }))
this.typePieData = Object.keys(typeMap).map(type => ({ name: type, value: typeMap[type] }))
// 渲染饼图
this.$nextTick(() => {
this.renderPieChart('crew', this.crewPieData)
this.renderPieChart('type', this.typePieData)
})
if (this.activeTab !== 'day') {
if (response.rows.length > 0) {
this.buildTrendChart(response.rows)
} else {
this.trendXData = []
}
}
} else {
if (response.code !== 200 || !response.rows || response.rows.length === 0) {
console.log('暂无停机数据')
this.tableData = []
this.summaryData = [
@@ -403,6 +357,53 @@ export default {
this.clearChart(this.trendChart)
this.renderPieChart('crew', [])
this.renderPieChart('type', [])
return
}
this.tableData = response.rows.map(item => ({
time: this.formatDateTime(item.startDate) + ' - ' + this.formatDateTime(item.endDate),
duration: this.secondsToMinutes(item.duration) + 'min',
remark: item.remark || '-',
machine: item.unit || '-'
}))
const totalDurationSeconds = response.rows.reduce((sum, item) => sum + (Number(item.duration) || 0), 0)
const totalDurationMinutes = this.secondsToMinutes(totalDurationSeconds)
const totalCount = response.rows.length
const totalAvailableMinutes = this.getTotalAvailableMinutes()
const workRate = this.calculateWorkRate(totalDurationMinutes, totalAvailableMinutes)
this.summaryData = [
{ label: '停机时间', value: totalDurationMinutes, unit: 'min' },
{ label: '停机次数', value: totalCount, unit: '次' },
{ label: '作业率', value: workRate, unit: '%' }
]
const crewMap = {}
const typeMap = {}
response.rows.forEach(item => {
const crew = item.crew || '未知班组'
const type = item.stopType || '未知类型'
const durationMinutes = this.secondsToMinutes(item.duration)
crewMap[crew] = (crewMap[crew] || 0) + durationMinutes
typeMap[type] = (typeMap[type] || 0) + durationMinutes
})
this.crewPieData = Object.keys(crewMap).map(crew => ({ name: crew, value: crewMap[crew] }))
this.typePieData = Object.keys(typeMap).map(type => ({ name: type, value: typeMap[type] }))
// 渲染饼图
this.$nextTick(() => {
this.renderPieChart('crew', this.crewPieData)
this.renderPieChart('type', this.typePieData)
})
if (this.activeTab !== 'day') {
if (response.rows.length > 0) {
this.buildTrendChart(response.rows)
} else {
this.trendXData = []
}
}
}).catch(error => {
loading.close()
@@ -807,6 +808,7 @@ export default {
.trend-chart {
height: 250px !important;
min-height: 250px;
max-height: 300px;
}
// ✅【修复】饼图容器增加固定高度,解决高度塌陷
@@ -845,13 +847,6 @@ export default {
color: #909399;
}
.detail-list {
background: #fff;
border-radius: 4px;
border: 1px solid #e4e7ed;
overflow: hidden;
}
.detail-item {
padding: 12px;
border-bottom: 1px solid #f5f7fa;