feat(dashboard): 车间平均单机产量tooltip记录日终汇总规则,多天范围改为日均单机产量

main
haoliang 1 week ago
parent 8ce0c11e0f
commit 3d07293510

@ -4,6 +4,11 @@ import type { MockMethod, MockRequest } from './types'
function getToday(): string { return new Date().toISOString().slice(0, 10) } function getToday(): string { return new Date().toISOString().slice(0, 10) }
function daysAgo(n: number): string { const d = new Date(); d.setDate(d.getDate() - n); return d.toISOString().slice(0, 10) } function daysAgo(n: number): string { const d = new Date(); d.setDate(d.getDate() - n); return d.toISOString().slice(0, 10) }
// 计算日期范围天数
function getDays(startDate: string, endDate: string): number {
return Math.max(1, Math.round((new Date(endDate).getTime() - new Date(startDate).getTime()) / 86400000) + 1)
}
// 不同日期范围的数据倍率(模拟不同日期的数据差异) // 不同日期范围的数据倍率(模拟不同日期的数据差异)
function getMultiplier(startDate: string, endDate: string): number { function getMultiplier(startDate: string, endDate: string): number {
const today = getToday() const today = getToday()
@ -78,10 +83,11 @@ const mock: MockMethod[] = [
method: 'get', method: 'get',
response: (req: MockRequest) => { response: (req: MockRequest) => {
const m = getMultiplier(req.query.startDate, req.query.endDate) const m = getMultiplier(req.query.startDate, req.query.endDate)
const days = getDays(req.query.startDate, req.query.endDate)
return { return {
code: 0, code: 0,
data: { data: {
items: baseMachineRank.map(r => ({ ...r, quantity: Math.round(r.quantity * m) })), items: baseMachineRank.map(r => ({ ...r, quantity: Math.round(r.quantity * m * days) })),
}, },
} }
}, },
@ -91,10 +97,11 @@ const mock: MockMethod[] = [
method: 'get', method: 'get',
response: (req: MockRequest) => { response: (req: MockRequest) => {
const m = getMultiplier(req.query.startDate, req.query.endDate) const m = getMultiplier(req.query.startDate, req.query.endDate)
const days = getDays(req.query.startDate, req.query.endDate)
return { return {
code: 0, code: 0,
data: { data: {
items: baseWorkerRank.map(r => ({ ...r, totalQuantity: Math.round(r.totalQuantity * m) })), items: baseWorkerRank.map(r => ({ ...r, totalQuantity: Math.round(r.totalQuantity * m * days) })),
}, },
} }
}, },
@ -124,14 +131,15 @@ const mock: MockMethod[] = [
method: 'get', method: 'get',
response: (req: MockRequest) => { response: (req: MockRequest) => {
const m = getMultiplier(req.query.startDate, req.query.endDate) const m = getMultiplier(req.query.startDate, req.query.endDate)
const days = getDays(req.query.startDate, req.query.endDate)
return { return {
code: 0, code: 0,
data: { data: {
items: baseWorkshopProduction.map(w => ({ items: baseWorkshopProduction.map(w => {
...w, const totalQty = Math.round(w.quantity * m * days) // 多天总量 = 单天 × 天数
quantity: Math.round(w.quantity * m), const avgQty = Math.round(totalQty / days / w.machineCount * 10) / 10 // 日均单机产量
avgQuantity: Math.round(w.avgQuantity * m * 10) / 10, return { ...w, quantity: totalQty, avgQuantity: avgQty }
})), }),
}, },
} }
}, },

@ -136,7 +136,16 @@
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span class="card-title">车间平均单机产量{{ workshopDateLabel }}<el-tooltip content="各车间总产量除以机床数量,反映每台机床的平均产出效率,消除车间规模差异。" placement="top"><span class="info-icon"></span></el-tooltip></span> <span class="card-title">车间平均单机产量{{ workshopDateLabel }}<el-tooltip placement="top">
<template #content>
<div style="max-width: 360px; line-height: 1.6">
<b>统计规则</b>车间总产量 ÷ 车间机床数 ÷ 天数<br/><br/>
<b>数据来源</b>系统每日凌晨1:00自动执行日终汇总将每台机床当天所有产量分段按程序名合并计算生成日产量记录多天范围取日均单机产量<br/><br/>
<b>产量计算</b>以NC程序名标识零件程序切换时自动结算上一段产量同程序多次出现时分段记录日汇总合并含手工修正值
</div>
</template>
<span class="info-icon"></span>
</el-tooltip></span>
<div class="date-filter"> <div class="date-filter">
<el-radio-group v-model="workshopDateType" size="small" @change="onWorkshopDateChange"> <el-radio-group v-model="workshopDateType" size="small" @change="onWorkshopDateChange">
<el-radio-button value="today">今日</el-radio-button> <el-radio-button value="today">今日</el-radio-button>
@ -291,6 +300,14 @@ const workshopDateLabel = computed(() => dateLabels[workshopDateType.value])
const machineDateLabel = computed(() => dateLabels[machineDateType.value]) const machineDateLabel = computed(() => dateLabels[machineDateType.value])
const workerDateLabel = computed(() => dateLabels[workerDateType.value]) const workerDateLabel = computed(() => dateLabels[workerDateType.value])
//
const workshopDays = computed(() => {
const { startDate, endDate } = getDateRange(workshopDateType.value, workshopDateRange.value)
return Math.max(1, Math.round((new Date(endDate).getTime() - new Date(startDate).getTime()) / 86400000) + 1)
})
const workshopUnit = computed(() => workshopDays.value > 1 ? '件/台/天' : '件/台')
const workshopUnitLabel = computed(() => workshopDays.value > 1 ? '日均' : '平均')
function getDateRange(type: DateType, customRange?: [string, string]): { startDate: string; endDate: string } { function getDateRange(type: DateType, customRange?: [string, string]): { startDate: string; endDate: string } {
const today = new Date() const today = new Date()
const fmt = (d: Date) => d.toISOString().slice(0, 10) const fmt = (d: Date) => d.toISOString().slice(0, 10)
@ -355,22 +372,24 @@ function alertTypeLabel(type: string): string {
function initWorkshopChart() { function initWorkshopChart() {
if (workshopChartRef.value && workshopData.value.length) { if (workshopChartRef.value && workshopData.value.length) {
const unit = workshopUnit.value
const unitLabel = workshopUnitLabel.value
workshopChart = echarts.init(workshopChartRef.value) workshopChart = echarts.init(workshopChartRef.value)
workshopChart.setOption({ workshopChart.setOption({
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
formatter: (params: any) => { formatter: (params: any) => {
const d = workshopData.value[params[0].dataIndex] const d = workshopData.value[params[0].dataIndex]
return `${d.workshopName}<br/>平均产量: ${params[0].value} 件/台<br/>总产量: ${d.quantity} 件<br/>机床数: ${d.machineCount}` return `${d.workshopName}<br/>${unitLabel}产量: ${params[0].value} ${unit}<br/>总产量: ${d.quantity} 件<br/>机床数: ${d.machineCount}`
}, },
}, },
grid: { left: 50, right: 20, top: 20, bottom: 30 }, grid: { left: 60, right: 20, top: 20, bottom: 30 },
xAxis: { type: 'category', data: workshopData.value.map(i => i.workshopName), axisLabel: { fontSize: 12 } }, xAxis: { type: 'category', data: workshopData.value.map(i => i.workshopName), axisLabel: { fontSize: 12 } },
yAxis: { type: 'value', name: '件/台', axisLabel: { fontSize: 12 } }, yAxis: { type: 'value', name: unit, axisLabel: { fontSize: 12 } },
series: [{ series: [{
type: 'bar', data: workshopData.value.map(i => i.avgQuantity), type: 'bar', data: workshopData.value.map(i => i.avgQuantity),
itemStyle: { color: '#67C23A', borderRadius: [4, 4, 0, 0] }, barWidth: '40%', itemStyle: { color: '#67C23A', borderRadius: [4, 4, 0, 0] }, barWidth: '40%',
label: { show: true, position: 'top', formatter: '{c} 件/台', fontSize: 12 }, label: { show: true, position: 'top', formatter: `{c} ${unit}`, fontSize: 12 },
}], }],
}) })
} }

Loading…
Cancel
Save