feat:修改
This commit is contained in:
453
server/app.js
453
server/app.js
@@ -242,33 +242,135 @@ app.get('/wms/acid-rolling/dashboard/overview', async (req, res) => {
|
||||
return
|
||||
}
|
||||
try {
|
||||
// 1. 获取当前班次OEE数据
|
||||
const [shiftRows] = await acidPool.execute(
|
||||
'SELECT * FROM klptcm1_shift_current ORDER BY create_time DESC LIMIT 1'
|
||||
)
|
||||
const currentShift = shiftRows[0] || {}
|
||||
|
||||
// 2. 获取今日产出统计
|
||||
const [coilRows] = await acidPool.execute(
|
||||
'SELECT COUNT(*) as count, SUM(weight) as totalWeight FROM klptcm1_pdo_excoil WHERE DATE(create_time) = CURDATE()'
|
||||
`SELECT
|
||||
COUNT(*) as count,
|
||||
SUM(weight) as totalWeight,
|
||||
SUM(CASE WHEN quality_status = 'A' THEN 1 ELSE 0 END) as qualifiedCount
|
||||
FROM klptcm1_pdo_excoil
|
||||
WHERE DATE(create_time) = CURDATE()`
|
||||
)
|
||||
|
||||
// 3. 计算OEE指标
|
||||
const totalCoils = coilRows[0]?.count || 0
|
||||
const qualifiedCoils = coilRows[0]?.qualifiedCount || 0
|
||||
const qualityRate = totalCoils > 0 ? (qualifiedCoils / totalCoils * 100) : 0
|
||||
const availabilityRate = currentShift.availability || 92.1
|
||||
const performanceRate = currentShift.performance || 89.8
|
||||
const oeeValue = (availabilityRate * performanceRate * qualityRate / 10000).toFixed(1)
|
||||
|
||||
// 4. 获取OEE趋势数据(最近7天)
|
||||
const [trendingRows] = await acidPool.execute(
|
||||
`SELECT
|
||||
DATE(create_time) as date,
|
||||
AVG(oee) as oee,
|
||||
AVG(availability) as availability,
|
||||
AVG(performance) as performance,
|
||||
COUNT(*) as coilCount
|
||||
FROM klptcm1_shift_current
|
||||
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
|
||||
GROUP BY DATE(create_time)
|
||||
ORDER BY date ASC`
|
||||
)
|
||||
|
||||
// 5. 获取7大损失分布(按停机类型统计)
|
||||
const [lossRows] = await acidPool.execute(
|
||||
'SELECT loss_name as name, SUM(loss_time) as value FROM klptcm1_pro_stoppage WHERE DATE(create_time) = CURDATE() GROUP BY loss_name'
|
||||
`SELECT
|
||||
stop_type as name,
|
||||
SUM(duration) as value
|
||||
FROM klptcm1_pro_stoppage
|
||||
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
|
||||
GROUP BY stop_type
|
||||
ORDER BY value DESC`
|
||||
)
|
||||
|
||||
const latest = shiftRows[0] || {}
|
||||
// 6. 获取班组产量排名
|
||||
const [teamRows] = await acidPool.execute(
|
||||
`SELECT
|
||||
crew as name,
|
||||
COUNT(*) as coilCount,
|
||||
SUM(weight) as output
|
||||
FROM klptcm1_pdo_excoil
|
||||
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
|
||||
GROUP BY crew
|
||||
ORDER BY output DESC`
|
||||
)
|
||||
|
||||
// 7. 获取实时告警(停机异常、质量不合格)
|
||||
const [alarmRows] = await acidPool.execute(
|
||||
`SELECT
|
||||
'停机告警' as type,
|
||||
stop_type as message,
|
||||
DATE_FORMAT(create_time, '%H:%i:%s') as time,
|
||||
CASE
|
||||
WHEN duration > 3600 THEN 'danger'
|
||||
WHEN duration > 1800 THEN 'warning'
|
||||
ELSE 'info'
|
||||
END as level
|
||||
FROM klptcm1_pro_stoppage
|
||||
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 5`
|
||||
)
|
||||
|
||||
// 8. 获取质量告警
|
||||
const [qualityAlarmRows] = await acidPool.execute(
|
||||
`SELECT
|
||||
'质量告警' as type,
|
||||
CONCAT('钢卷 ', coil_id, ' 质量异常') as message,
|
||||
DATE_FORMAT(in_date, '%H:%i:%s') as time,
|
||||
'warning' as level
|
||||
FROM klptcm1_pdo_excoil
|
||||
WHERE quality_status IN ('B', 'C', 'D')
|
||||
AND DATE(in_date) = CURDATE()
|
||||
ORDER BY in_date DESC
|
||||
LIMIT 3`
|
||||
)
|
||||
|
||||
const overview = {
|
||||
oee: latest.oee || 86.5,
|
||||
availability: latest.availability || 92.1,
|
||||
performance: latest.performance || 89.8,
|
||||
quality: latest.quality || 97.5,
|
||||
totalOutput: coilRows[0]?.count || mockOverview.totalOutput,
|
||||
totalWeight: coilRows[0]?.totalWeight || mockOverview.totalWeight,
|
||||
// 核心指标
|
||||
oee: parseFloat(oeeValue),
|
||||
availability: availabilityRate,
|
||||
performance: performanceRate,
|
||||
quality: qualityRate.toFixed(1),
|
||||
totalOutput: totalCoils,
|
||||
totalWeight: coilRows[0]?.totalWeight || 0,
|
||||
targetOutput: 15000,
|
||||
efficiency: 92.0,
|
||||
trendingData: mockOverview.trendingData,
|
||||
lossData: lossRows.length > 0 ? lossRows : mockOverview.lossData,
|
||||
teamRanking: mockOverview.teamRanking,
|
||||
alarms: mockOverview.alarms
|
||||
// OEE趋势数据
|
||||
trendingData: trendingRows.length > 0 ? trendingRows.map(row => ({
|
||||
date: row.date ? row.date.toString().substring(5) : '',
|
||||
oee: parseFloat((row.oee || 0).toFixed(1)),
|
||||
availability: parseFloat((row.availability || 0).toFixed(1)),
|
||||
performance: parseFloat((row.performance || 0).toFixed(1)),
|
||||
coilCount: row.coilCount || 0
|
||||
})) : mockOverview.trendingData,
|
||||
// 7大损失分布
|
||||
lossData: lossRows.length > 0 ? lossRows.map(row => ({
|
||||
name: row.name || '未知损失',
|
||||
value: row.value || 0
|
||||
})) : mockOverview.lossData,
|
||||
// 班组产量排名
|
||||
teamRanking: teamRows.length > 0 ? teamRows.map(row => ({
|
||||
name: row.name || '未知班组',
|
||||
output: Math.round(row.output || 0),
|
||||
coilCount: row.coilCount || 0,
|
||||
rate: 96.5
|
||||
})) : mockOverview.teamRanking,
|
||||
// 告警信息
|
||||
alarms: [...alarmRows, ...qualityAlarmRows].map(row => ({
|
||||
type: row.type,
|
||||
message: row.message,
|
||||
time: row.time,
|
||||
level: row.level
|
||||
}))
|
||||
}
|
||||
|
||||
sendResponse(res, overview)
|
||||
@@ -378,6 +480,331 @@ app.get('/wms/acid-rolling/report/stop', async (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 订单数据接口 ====================
|
||||
|
||||
app.get('/api/dashboard/order', async (req, res) => {
|
||||
if (!masterPool) {
|
||||
sendResponse(res, {
|
||||
todayOrderCount: 45,
|
||||
pendingOrderCount: 12,
|
||||
completedOrderCount: 156,
|
||||
orderTotalAmount: 568,
|
||||
orderTrend: [
|
||||
{ date: '05-11', count: 38, amount: 420 },
|
||||
{ date: '05-12', count: 42, amount: 480 },
|
||||
{ date: '05-13', count: 35, amount: 390 },
|
||||
{ date: '05-14', count: 48, amount: 520 },
|
||||
{ date: '05-15', count: 45, amount: 568 }
|
||||
],
|
||||
statusDistribution: [
|
||||
{ name: '生产中', value: 45 },
|
||||
{ name: '待生产', value: 12 },
|
||||
{ name: '已完成', value: 156 }
|
||||
],
|
||||
recentOrders: [
|
||||
{ orderNo: 'ORD20260515001', customer: '周口钢铁', amount: 125000, status: '生产中', time: '10:30' },
|
||||
{ orderNo: 'ORD20260515002', customer: '南阳重工', amount: 89000, status: '已完成', time: '09:45' },
|
||||
{ orderNo: 'ORD20260515003', customer: '洛阳机械', amount: 156000, status: '待生产', time: '11:20' },
|
||||
{ orderNo: 'ORD20260515004', customer: '开封汽配', amount: 67000, status: '生产中', time: '08:15' },
|
||||
{ orderNo: 'ORD20260515005', customer: '商丘金属', amount: 45000, status: '已完成', time: '07:30' }
|
||||
]
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
const [todayOrders] = await masterPool.execute(
|
||||
'SELECT COUNT(*) as count FROM klp_order WHERE DATE(create_time) = CURDATE()'
|
||||
)
|
||||
const [pendingOrders] = await masterPool.execute(
|
||||
'SELECT COUNT(*) as count FROM klp_order WHERE status = "pending"'
|
||||
)
|
||||
const [completedOrders] = await masterPool.execute(
|
||||
'SELECT COUNT(*) as count FROM klp_order WHERE status = "completed"'
|
||||
)
|
||||
const [totalAmount] = await masterPool.execute(
|
||||
'SELECT SUM(amount) as total FROM klp_order WHERE DATE(create_time) = CURDATE()'
|
||||
)
|
||||
const [trendData] = await masterPool.execute(
|
||||
'SELECT DATE(create_time) as date, COUNT(*) as count, SUM(amount) as amount FROM klp_order GROUP BY DATE(create_time) ORDER BY date DESC LIMIT 7'
|
||||
)
|
||||
const [statusData] = await masterPool.execute(
|
||||
'SELECT status, COUNT(*) as count FROM klp_order GROUP BY status'
|
||||
)
|
||||
const [recentOrders] = await masterPool.execute(
|
||||
'SELECT order_no as orderNo, customer, amount, status, TIME(create_time) as time FROM klp_order ORDER BY create_time DESC LIMIT 5'
|
||||
)
|
||||
|
||||
sendResponse(res, {
|
||||
todayOrderCount: todayOrders[0]?.count || 0,
|
||||
pendingOrderCount: pendingOrders[0]?.count || 0,
|
||||
completedOrderCount: completedOrders[0]?.count || 0,
|
||||
orderTotalAmount: (totalAmount[0]?.total || 0) / 10000,
|
||||
orderTrend: trendData.map(row => ({
|
||||
date: row.date?.substring(5) || '',
|
||||
count: row.count || 0,
|
||||
amount: Math.round((row.amount || 0) / 10000)
|
||||
})),
|
||||
statusDistribution: statusData.map(row => ({
|
||||
name: row.status === 'pending' ? '待生产' : row.status === 'processing' ? '生产中' : '已完成',
|
||||
value: row.count || 0
|
||||
})),
|
||||
recentOrders: recentOrders.map(row => ({
|
||||
orderNo: row.orderNo || '',
|
||||
customer: row.customer || '',
|
||||
amount: row.amount || 0,
|
||||
status: row.status === 'pending' ? '待生产' : row.status === 'processing' ? '生产中' : '已完成',
|
||||
time: row.time?.substring(0, 5) || ''
|
||||
}))
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('订单数据查询失败:', err)
|
||||
sendResponse(res, {
|
||||
todayOrderCount: 45,
|
||||
pendingOrderCount: 12,
|
||||
completedOrderCount: 156,
|
||||
orderTotalAmount: 568,
|
||||
orderTrend: [
|
||||
{ date: '05-11', count: 38, amount: 420 },
|
||||
{ date: '05-12', count: 42, amount: 480 },
|
||||
{ date: '05-13', count: 35, amount: 390 },
|
||||
{ date: '05-14', count: 48, amount: 520 },
|
||||
{ date: '05-15', count: 45, amount: 568 }
|
||||
],
|
||||
statusDistribution: [
|
||||
{ name: '生产中', value: 45 },
|
||||
{ name: '待生产', value: 12 },
|
||||
{ name: '已完成', value: 156 }
|
||||
],
|
||||
recentOrders: [
|
||||
{ orderNo: 'ORD20260515001', customer: '周口钢铁', amount: 125000, status: '生产中', time: '10:30' },
|
||||
{ orderNo: 'ORD20260515002', customer: '南阳重工', amount: 89000, status: '已完成', time: '09:45' },
|
||||
{ orderNo: 'ORD20260515003', customer: '洛阳机械', amount: 156000, status: '待生产', time: '11:20' },
|
||||
{ orderNo: 'ORD20260515004', customer: '开封汽配', amount: 67000, status: '生产中', time: '08:15' },
|
||||
{ orderNo: 'ORD20260515005', customer: '商丘金属', amount: 45000, status: '已完成', time: '07:30' }
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 成本数据接口 ====================
|
||||
|
||||
app.get('/api/dashboard/cost', async (req, res) => {
|
||||
if (!acidPool) {
|
||||
sendResponse(res, {
|
||||
totalCost: 156.8,
|
||||
materialCost: 89.5,
|
||||
laborCost: 32.6,
|
||||
energyCost: 24.7,
|
||||
costTrend: [
|
||||
{ month: '1月', total: 142, material: 82, labor: 30, energy: 22 },
|
||||
{ month: '2月', total: 138, material: 80, labor: 31, energy: 21 },
|
||||
{ month: '3月', total: 152, material: 88, labor: 33, energy: 25 },
|
||||
{ month: '4月', total: 149, material: 86, labor: 32, energy: 24 },
|
||||
{ month: '5月', total: 156.8, material: 89.5, labor: 32.6, energy: 24.7 }
|
||||
],
|
||||
costComposition: [
|
||||
{ name: '材料成本', value: 57.1 },
|
||||
{ name: '人工成本', value: 20.8 },
|
||||
{ name: '能源成本', value: 15.7 },
|
||||
{ name: '其他成本', value: 6.4 }
|
||||
],
|
||||
analysisList: [
|
||||
{ label: '材料成本', value: '89.5万', change: 3.2, color: '#ff6b6b' },
|
||||
{ label: '人工成本', value: '32.6万', change: -1.5, color: '#00d4ff' },
|
||||
{ label: '能源成本', value: '24.7万', change: 5.8, color: '#00ff88' },
|
||||
{ label: '总成本', value: '156.8万', change: 2.1, color: '#7c63ff' }
|
||||
]
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
const [costData] = await acidPool.execute(
|
||||
'SELECT total_cost, material_cost, labor_cost, energy_cost, stat_month FROM klptcm1_cost_month ORDER BY stat_month DESC LIMIT 5'
|
||||
)
|
||||
|
||||
const latest = costData[0] || {}
|
||||
const costTrend = costData.map(row => ({
|
||||
month: row.stat_month?.substring(5) + '月' || '',
|
||||
total: row.total_cost || 0,
|
||||
material: row.material_cost || 0,
|
||||
labor: row.labor_cost || 0,
|
||||
energy: row.energy_cost || 0
|
||||
}))
|
||||
|
||||
const total = latest.total_cost || 0
|
||||
sendResponse(res, {
|
||||
totalCost: total,
|
||||
materialCost: latest.material_cost || 0,
|
||||
laborCost: latest.labor_cost || 0,
|
||||
energyCost: latest.energy_cost || 0,
|
||||
costTrend: costTrend,
|
||||
costComposition: [
|
||||
{ name: '材料成本', value: total > 0 ? Math.round((latest.material_cost || 0) / total * 1000) / 10 : 57.1 },
|
||||
{ name: '人工成本', value: total > 0 ? Math.round((latest.labor_cost || 0) / total * 1000) / 10 : 20.8 },
|
||||
{ name: '能源成本', value: total > 0 ? Math.round((latest.energy_cost || 0) / total * 1000) / 10 : 15.7 },
|
||||
{ name: '其他成本', value: total > 0 ? 100 - Math.round(((latest.material_cost || 0) + (latest.labor_cost || 0) + (latest.energy_cost || 0)) / total * 1000) / 10 : 6.4 }
|
||||
],
|
||||
analysisList: [
|
||||
{ label: '材料成本', value: (latest.material_cost || 89.5) + '万', change: 3.2, color: '#ff6b6b' },
|
||||
{ label: '人工成本', value: (latest.labor_cost || 32.6) + '万', change: -1.5, color: '#00d4ff' },
|
||||
{ label: '能源成本', value: (latest.energy_cost || 24.7) + '万', change: 5.8, color: '#00ff88' },
|
||||
{ label: '总成本', value: total + '万', change: 2.1, color: '#7c63ff' }
|
||||
]
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('成本数据查询失败:', err)
|
||||
sendResponse(res, {
|
||||
totalCost: 156.8,
|
||||
materialCost: 89.5,
|
||||
laborCost: 32.6,
|
||||
energyCost: 24.7,
|
||||
costTrend: [
|
||||
{ month: '1月', total: 142, material: 82, labor: 30, energy: 22 },
|
||||
{ month: '2月', total: 138, material: 80, labor: 31, energy: 21 },
|
||||
{ month: '3月', total: 152, material: 88, labor: 33, energy: 25 },
|
||||
{ month: '4月', total: 149, material: 86, labor: 32, energy: 24 },
|
||||
{ month: '5月', total: 156.8, material: 89.5, labor: 32.6, energy: 24.7 }
|
||||
],
|
||||
costComposition: [
|
||||
{ name: '材料成本', value: 57.1 },
|
||||
{ name: '人工成本', value: 20.8 },
|
||||
{ name: '能源成本', value: 15.7 },
|
||||
{ name: '其他成本', value: 6.4 }
|
||||
],
|
||||
analysisList: [
|
||||
{ label: '材料成本', value: '89.5万', change: 3.2, color: '#ff6b6b' },
|
||||
{ label: '人工成本', value: '32.6万', change: -1.5, color: '#00d4ff' },
|
||||
{ label: '能源成本', value: '24.7万', change: 5.8, color: '#00ff88' },
|
||||
{ label: '总成本', value: '156.8万', change: 2.1, color: '#7c63ff' }
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 能源数据接口 ====================
|
||||
|
||||
app.get('/api/dashboard/energy', async (req, res) => {
|
||||
if (!acidPool) {
|
||||
sendResponse(res, {
|
||||
totalPower: 12560,
|
||||
waterUsage: 856,
|
||||
gasUsage: 325,
|
||||
steamUsage: 156,
|
||||
powerTrend: [
|
||||
{ hour: '08:00', power: 1200, water: 85, gas: 32, steam: 15 },
|
||||
{ hour: '09:00', power: 1350, water: 92, gas: 35, steam: 18 },
|
||||
{ hour: '10:00', power: 1280, water: 88, gas: 33, steam: 16 },
|
||||
{ hour: '11:00', power: 1420, water: 95, gas: 38, steam: 20 },
|
||||
{ hour: '12:00', power: 1100, water: 75, gas: 28, steam: 14 },
|
||||
{ hour: '13:00', power: 1380, water: 90, gas: 36, steam: 17 },
|
||||
{ hour: '14:00', power: 1450, water: 98, gas: 40, steam: 22 },
|
||||
{ hour: '15:00', power: 1320, water: 86, gas: 34, steam: 16 }
|
||||
],
|
||||
equipmentRanking: [
|
||||
{ name: '酸轧线1号机', power: 3200, ratio: 25.5 },
|
||||
{ name: '酸轧线2号机', power: 2850, ratio: 22.7 },
|
||||
{ name: '退火炉A', power: 2100, ratio: 16.7 },
|
||||
{ name: '退火炉B', power: 1980, ratio: 15.8 },
|
||||
{ name: '酸洗线', power: 1560, ratio: 12.4 },
|
||||
{ name: '其他设备', power: 870, ratio: 6.9 }
|
||||
],
|
||||
energyComposition: [
|
||||
{ name: '电力', value: 78.5 },
|
||||
{ name: '水', value: 10.2 },
|
||||
{ name: '天然气', value: 7.8 },
|
||||
{ name: '蒸汽', value: 3.5 }
|
||||
],
|
||||
alarms: [
|
||||
{ level: 'warning', message: '酸轧线1号机电流偏高', time: '14:25:00' },
|
||||
{ level: 'info', message: '退火炉B能耗正常', time: '13:30:00' },
|
||||
{ level: 'success', message: '能源系统运行正常', time: '08:00:00' }
|
||||
]
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
const [powerData] = await acidPool.execute(
|
||||
'SELECT hour, power, water, gas, steam FROM klptcm1_energy_hour ORDER BY hour DESC LIMIT 8'
|
||||
)
|
||||
const [equipmentData] = await acidPool.execute(
|
||||
'SELECT equipment_name, power_consumption, ratio FROM klptcm1_energy_equipment ORDER BY power_consumption DESC LIMIT 6'
|
||||
)
|
||||
const [totalData] = await acidPool.execute(
|
||||
'SELECT SUM(power) as totalPower, SUM(water) as waterUsage, SUM(gas) as gasUsage, SUM(steam) as steamUsage FROM klptcm1_energy_hour WHERE DATE(hour) = CURDATE()'
|
||||
)
|
||||
|
||||
const powerTrend = powerData.map(row => ({
|
||||
hour: row.hour?.substring(11, 16) || '',
|
||||
power: row.power || 0,
|
||||
water: row.water || 0,
|
||||
gas: row.gas || 0,
|
||||
steam: row.steam || 0
|
||||
})).reverse()
|
||||
|
||||
const totalPower = totalData[0]?.totalPower || 12560
|
||||
sendResponse(res, {
|
||||
totalPower: totalPower,
|
||||
waterUsage: totalData[0]?.waterUsage || 856,
|
||||
gasUsage: totalData[0]?.gasUsage || 325,
|
||||
steamUsage: totalData[0]?.steamUsage || 156,
|
||||
powerTrend: powerTrend,
|
||||
equipmentRanking: equipmentData.map(row => ({
|
||||
name: row.equipment_name || '',
|
||||
power: row.power_consumption || 0,
|
||||
ratio: row.ratio || 0
|
||||
})),
|
||||
energyComposition: [
|
||||
{ name: '电力', value: totalPower > 0 ? Math.round((totalPower / (totalPower + 1500)) * 100) : 78.5 },
|
||||
{ name: '水', value: 10.2 },
|
||||
{ name: '天然气', value: 7.8 },
|
||||
{ name: '蒸汽', value: 3.5 }
|
||||
],
|
||||
alarms: [
|
||||
{ level: 'warning', message: '酸轧线1号机电流偏高', time: '14:25:00' },
|
||||
{ level: 'info', message: '退火炉B能耗正常', time: '13:30:00' },
|
||||
{ level: 'success', message: '能源系统运行正常', time: '08:00:00' }
|
||||
]
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('能源数据查询失败:', err)
|
||||
sendResponse(res, {
|
||||
totalPower: 12560,
|
||||
waterUsage: 856,
|
||||
gasUsage: 325,
|
||||
steamUsage: 156,
|
||||
powerTrend: [
|
||||
{ hour: '08:00', power: 1200, water: 85, gas: 32, steam: 15 },
|
||||
{ hour: '09:00', power: 1350, water: 92, gas: 35, steam: 18 },
|
||||
{ hour: '10:00', power: 1280, water: 88, gas: 33, steam: 16 },
|
||||
{ hour: '11:00', power: 1420, water: 95, gas: 38, steam: 20 },
|
||||
{ hour: '12:00', power: 1100, water: 75, gas: 28, steam: 14 },
|
||||
{ hour: '13:00', power: 1380, water: 90, gas: 36, steam: 17 },
|
||||
{ hour: '14:00', power: 1450, water: 98, gas: 40, steam: 22 },
|
||||
{ hour: '15:00', power: 1320, water: 86, gas: 34, steam: 16 }
|
||||
],
|
||||
equipmentRanking: [
|
||||
{ name: '酸轧线1号机', power: 3200, ratio: 25.5 },
|
||||
{ name: '酸轧线2号机', power: 2850, ratio: 22.7 },
|
||||
{ name: '退火炉A', power: 2100, ratio: 16.7 },
|
||||
{ name: '退火炉B', power: 1980, ratio: 15.8 },
|
||||
{ name: '酸洗线', power: 1560, ratio: 12.4 },
|
||||
{ name: '其他设备', power: 870, ratio: 6.9 }
|
||||
],
|
||||
energyComposition: [
|
||||
{ name: '电力', value: 78.5 },
|
||||
{ name: '水', value: 10.2 },
|
||||
{ name: '天然气', value: 7.8 },
|
||||
{ name: '蒸汽', value: 3.5 }
|
||||
],
|
||||
alarms: [
|
||||
{ level: 'warning', message: '酸轧线1号机电流偏高', time: '14:25:00' },
|
||||
{ level: 'info', message: '退火炉B能耗正常', time: '13:30:00' },
|
||||
{ level: 'success', message: '能源系统运行正常', time: '08:00:00' }
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 大屏管理接口 ====================
|
||||
|
||||
app.get('/api/screens', async (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user