add 车间看板

master
yinq 2 weeks ago
parent 939acbe477
commit 5b24291f8e

@ -41,3 +41,9 @@ export function realTimeAlarm(query) {
url: '/ems/board/realTimeAlarm', method: 'get', params: query
})
}
export function workshopColumns(query) {
return request({
url: '/ems/board/workshopColumns', method: 'get', params: query
})
}

@ -41,6 +41,11 @@ export const constantRoutes = [
component: () => import('@/views/board/lineIndex.vue'),
hidden: true
},
{
path: '/workshopIndex',
component: () => import('@/views/board/workshopIndex.vue'),
hidden: true
},
{
path: '/redirect',
component: Layout,

@ -0,0 +1,507 @@
<template>
<div class="board-wrap">
<div class="bg">
<div class="header">
<div class="title">车间能源看板</div>
<div class="time">{{ clockText }}</div>
</div>
<div class="columns">
<div
class="energy-col"
:class="{
'power-col': String(col.monitorType) === '2',
'steam-col': String(col.monitorType) === '4'
}"
v-for="col in columns"
:key="col.monitorType"
>
<div class="col-head">
<div class="energy-name">{{ col.name }}</div>
<div class="today">
当日能耗
<span class="num">{{ formatNumber(col.todayConsumption) }}</span>
<span class="unit">{{ col.todayUnit }}</span>
</div>
</div>
<div class="table-head">
<span>计量设备</span>
<span>{{ String(col.monitorType) === '2' ? '电流电压' : '实时数据' }}</span>
<span>当日耗量</span>
</div>
<div class="rows">
<div class="row" v-for="row in col.rows" :key="col.monitorType + '-' + rowKey(row)">
<span :title="row.monitorName">{{ row.monitorName || row.monitorCode }}</span>
<span class="realtime">{{ displayRealtime(row) }}</span>
<span>{{ formatNumber(rowTodayVal(row)) }} {{ col.todayUnit }}</span>
</div>
<div class="empty" v-if="!col.rows || col.rows.length === 0"></div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { workshopColumns } from '@/api/board'
export default {
name: 'WorkshopIndex',
data() {
return {
clockText: '',
timer: null,
dataTimer: null,
columns: []
}
},
mounted() {
this.tickClock()
this.timer = setInterval(this.tickClock, 1000)
this.getData()
this.dataTimer = setInterval(this.getData, 2 * 60 * 1000)
},
beforeDestroy() {
if (this.timer) clearInterval(this.timer)
if (this.dataTimer) clearInterval(this.dataTimer)
},
methods: {
tickClock() {
const d = new Date()
const pad = n => (n < 10 ? '0' + n : '' + n)
this.clockText = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
},
getData() {
workshopColumns().then(res => {
this.columns = (res.data && res.data.columns) || []
})
},
rowKey(row) {
return row.monitorCode != null ? String(row.monitorCode) : ''
},
rowTodayVal(row) {
const v = row.rowTodayConsumption != null ? row.rowTodayConsumption : row.rowtodayconsumption
return v
},
displayRealtime(row) {
const type = String(row.monitorType != null ? row.monitorType : '')
if (type === '2') {
const u = this.joinPhases(row, ['vA', 'vB', 'vC'], 'V')
const i = this.joinPhases(row, ['iA', 'iB', 'iC'], 'A')
if (!u && !i) return '--'
if (!u) return i
if (!i) return u
return `${u} / ${i}`
}
const instant = row.instantFlow != null ? row.instantFlow : row.instantflow
const cum =
row.cumulativeFlow != null
? row.cumulativeFlow
: row.cumulativeflow != null
? row.cumulativeflow
: null
const instantUnit = row.instantUnit || row.instantunit || ''
const unit = row.realtimeUnit || row.realtimeunit || ''
const instantNum = this.formatNumber(instant)
const num = this.formatNumber(cum)
if (instantNum === '--' && num === '--') return '--'
const instantText = instantNum === '--' ? '--' : (instantUnit ? `${instantNum} ${instantUnit}` : instantNum)
const cumText = num === '--' ? '--' : (unit ? `${num} ${unit}` : num)
return `瞬时:${instantText}\n累计:${cumText}`
},
joinPhases(row, keys, suffix) {
const parts = []
for (const k of keys) {
const raw = row[k] != null ? row[k] : row[k.toLowerCase()]
if (raw === null || raw === undefined || raw === '') continue
const n = Number(raw)
if (Number.isNaN(n)) continue
parts.push(`${n.toFixed(2)}${suffix}`)
}
return parts.length ? parts.join('/') : ''
},
formatNumber(val) {
if (val === null || val === undefined || val === '') return '--'
const num = Number(val)
if (Number.isNaN(num)) return '--'
return num.toFixed(2)
}
}
}
</script>
<style scoped lang="less">
.board-wrap {
width: 100%;
height: 100%;
}
.bg {
width: 100%;
height: 100%;
min-height: 100vh;
background: #061223 url('~@/assets/board/bg1.jpg') no-repeat center;
background-size: cover;
padding: 12px;
box-sizing: border-box;
color: #d8ecff;
overflow-x: auto;
}
.header {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 12px;
position: relative;
}
.title {
font-size: 28px;
font-weight: 600;
letter-spacing: 2px;
text-align: center;
}
.time {
position: absolute;
right: 0;
font-size: 14px;
color: #9fc4e8;
}
.columns {
display: flex;
gap: 10px;
min-width: 1500px;
}
.energy-col {
width: calc((100% - 40px) / 5);
min-width: 0;
background: rgba(7, 24, 45, 0.82);
border: 1px solid rgba(120, 180, 255, 0.25);
border-radius: 8px;
min-height: calc(100vh - 96px);
display: flex;
flex-direction: column;
}
.col-head {
padding: 10px 10px 8px;
border-bottom: 1px solid rgba(120, 180, 255, 0.22);
text-align: center;
}
.energy-name {
font-size: 18px;
font-weight: 600;
margin-bottom: 4px;
}
.today {
font-size: 13px;
color: #9ec6ef;
}
.today .num {
color: #ffd166;
font-weight: 600;
}
.table-head {
display: grid;
grid-template-columns: 1.45fr 1.05fr 0.7fr;
gap: 6px;
padding: 8px 10px;
font-size: 12px;
color: #7faad5;
border-bottom: 1px solid rgba(120, 180, 255, 0.18);
text-align: center;
}
.rows {
flex: 1;
overflow: auto;
}
.row {
display: grid;
grid-template-columns: 1.45fr 1.05fr 0.7fr;
gap: 6px;
padding: 8px 10px;
font-size: 12px;
border-bottom: 1px dashed rgba(120, 180, 255, 0.12);
text-align: center;
}
.row span:first-child {
white-space: normal;
word-break: break-all;
line-height: 1.35;
}
.row .realtime {
white-space: pre-line;
word-break: break-all;
line-height: 1.2;
font-size: 11px;
}
.power-col .table-head,
.power-col .row {
grid-template-columns: 1fr 1.15fr 0.85fr;
}
.steam-col .table-head,
.steam-col .row {
grid-template-columns: 1.75fr 0.95fr 0.65fr;
}
.empty {
padding: 12px 10px;
color: #7098c2;
font-size: 12px;
text-align: center;
}
</style>
Loading…
Cancel
Save