|
|
|
@ -17,6 +17,7 @@ |
|
|
|
<div class="summary-counts"> |
|
|
|
<span>标签 <strong>{{ visibleRows.length }}</strong></span> |
|
|
|
<span>未完成 <strong class="pending-text">{{ pendingCount }}</strong></span> |
|
|
|
<span>数据异常 <strong class="abnormal-text">{{ abnormalCount }}</strong></span> |
|
|
|
<span>已完成 <strong class="completed-text">{{ completedCount }}</strong></span> |
|
|
|
</div> |
|
|
|
<!-- <div class="summary-refresh">--> |
|
|
|
@ -30,17 +31,17 @@ |
|
|
|
<div ref="tableViewport" class="table-viewport" @mouseenter="scrollPaused = true" @mouseleave="scrollPaused = false"> |
|
|
|
<table class="board-table"> |
|
|
|
<colgroup> |
|
|
|
<col style="width: 4%"> |
|
|
|
<col style="width: 13%"> |
|
|
|
<col style="width: 12%"> |
|
|
|
<col style="width: 29%"> |
|
|
|
<col style="width: 19%"> |
|
|
|
<col style="width: 8%"> |
|
|
|
<col style="width: 5%"> |
|
|
|
<col style="width: 16%"> |
|
|
|
<col style="width: 15%"> |
|
|
|
<col style="width: 34%"> |
|
|
|
<col style="width: 22%"> |
|
|
|
<col style="width: 8%"> |
|
|
|
</colgroup> |
|
|
|
<thead> |
|
|
|
<!-- 六屏仅展示标签物料编码,移除产品编码列后将空间分配给物料名称 - rqrq --> |
|
|
|
<tr><th>序号</th><th>工单号</th><th>物料编码</th><th>物料名称</th><th>RFID / 标签号</th><th>状态</th><th>说明</th></tr> |
|
|
|
<!-- 人工四屏暂不展示说明列,异常原因由状态“数据异常”提示;字段仍保留在接口中供后续排查 - rqrq --> |
|
|
|
<tr><th>序号</th><th>工单号</th><th>物料编码</th><th>物料名称</th><th>RFID / 标签号</th><th>状态</th></tr> |
|
|
|
</thead> |
|
|
|
<tbody> |
|
|
|
<tr v-for="(item, index) in visibleRows" :key="item.rfidBarcode"> |
|
|
|
@ -50,8 +51,7 @@ |
|
|
|
<td :title="item.partNo">{{ item.partNo || '-' }}</td> |
|
|
|
<td class="description" :title="(item.partDesc || '').slice(0, 100)">{{ (item.partDesc || '').slice(0, 100) || '-' }}</td> |
|
|
|
<td class="barcode" :title="item.rfidBarcode">{{ item.rfidBarcode }}</td> |
|
|
|
<td><span :class="['status-badge', item.status === '已完成' ? 'completed' : 'pending']">{{ item.status }}</span></td> |
|
|
|
<td class="row-message" :title="item.message">{{ item.message || '-' }}</td> |
|
|
|
<td><span :class="['status-badge', item.status === '已完成' ? 'completed' : item.status === '数据异常' ? 'abnormal' : 'pending']">{{ item.status }}</span></td> |
|
|
|
</tr> |
|
|
|
<!-- 未返回任务时表体留白,不展示空数据或异常提示;连接状态由标题指示灯表示 - rqrq --> |
|
|
|
</tbody> |
|
|
|
@ -108,6 +108,8 @@ export default { |
|
|
|
stale () { return this.lastReceivedAt > 0 && this.now - this.lastReceivedAt > 20000 }, |
|
|
|
visibleRows () { return this.available && !this.stale ? this.rows : [] }, |
|
|
|
pendingCount () { return this.visibleRows.filter(item => item.status === '未完成').length }, |
|
|
|
// 数据异常独立计数,避免隐藏说明列后总数与未完成、已完成之和不一致却没有提示 - rqrq |
|
|
|
abnormalCount () { return this.visibleRows.filter(item => item.status === '数据异常').length }, |
|
|
|
completedCount () { return this.visibleRows.filter(item => item.status === '已完成').length }, |
|
|
|
// 绿灯只代表STOMP连接正常,WCS/WMS查询异常通过旁边业务提示显示,不混淆连接与任务状态 - rqrq |
|
|
|
connectionText () { return { connected: '连接正常', disconnected: '连接断开,等待重连', connecting: '正在连接', disabled: '推送已停用' }[this.wsState] }, |
|
|
|
@ -250,7 +252,28 @@ export default { |
|
|
|
const board = data.row |
|
|
|
this.lastReceivedAt = Date.now() |
|
|
|
this.available = board.available === true |
|
|
|
this.rows = this.available && Array.isArray(board.rows) ? board.rows : [] |
|
|
|
// 四个人工位置的HTTP与推送数据统一按未完成、数据异常、已完成稳定分组,组内保留原顺序 - rqrq |
|
|
|
const sourceRows = this.available && Array.isArray(board.rows) ? board.rows : [] |
|
|
|
const unfinishedRows = [] |
|
|
|
const abnormalRows = [] |
|
|
|
const completedRows = [] |
|
|
|
sourceRows.forEach(item => { |
|
|
|
if (item.status === '已完成') completedRows.push(item) |
|
|
|
else if (item.status === '未完成') unfinishedRows.push(item) |
|
|
|
else abnormalRows.push(item) |
|
|
|
}) |
|
|
|
const nextRows = unfinishedRows.concat(abnormalRows, completedRows) |
|
|
|
const orderChanged = this.rows.length !== nextRows.length || this.rows.some((item, index) => { |
|
|
|
const nextItem = nextRows[index] |
|
|
|
return item.rfidBarcode !== nextItem.rfidBarcode || item.status !== nextItem.status |
|
|
|
}) |
|
|
|
this.rows = nextRows |
|
|
|
// 列表顺序或状态变化且仍有待处理/异常项时回到顶部,避免旧滚动位置让已完成项遮住它们 - rqrq |
|
|
|
if (orderChanged && (unfinishedRows.length > 0 || abnormalRows.length > 0)) { |
|
|
|
this.$nextTick(() => { |
|
|
|
if (this.$refs.tableViewport) this.$refs.tableViewport.scrollTop = 0 |
|
|
|
}) |
|
|
|
} |
|
|
|
this.updatedAt = Number(board.updatedAt) || 0 |
|
|
|
this.message = board.message || (this.rows.length ? '数据正常' : '当前分拣位暂无任务') |
|
|
|
}, |
|
|
|
@ -314,6 +337,8 @@ export default { |
|
|
|
.summary-counts, .summary-refresh { display: flex; align-items: center; gap: 20px; } |
|
|
|
.summary-counts strong { font-size: 26px; margin-left: 8px; } |
|
|
|
.pending-text { color: #ffd17d; } |
|
|
|
/* 人工分拣异常数量和状态使用醒目红色,提醒现场核对标签预留信息 - rqrq */ |
|
|
|
.abnormal-text { color: #ffb3b3; } |
|
|
|
.completed-text { color: #80e5bc; } |
|
|
|
.ws-status-dot { display: inline-block; width: 12px; height: 12px; margin-left: 12px; border-radius: 50%; vertical-align: middle; background: #94a3b8; } |
|
|
|
.ws-status-dot.connected { background: #22c55e; box-shadow: 0 0 10px rgba(34, 197, 94, 0.8); } |
|
|
|
@ -331,6 +356,7 @@ export default { |
|
|
|
.board-table .row-message { color: #ffd17d; font-size: 14px; } |
|
|
|
.status-badge { display: inline-block; padding: 5px 10px; border-radius: 4px; white-space: nowrap; font-size: 16px; } |
|
|
|
.status-badge.pending { background: #745827; color: #fff0cf; } |
|
|
|
.status-badge.abnormal { background: #8b2d2d; color: #ffe2e2; } |
|
|
|
.status-badge.completed { background: #21684e; color: #d4ffeb; } |
|
|
|
.board-table .empty-message { height: 220px; font-size: 24px; color: #d2e1ee; } |
|
|
|
.board-table .empty-message.is-error { color: #ffd17d; } |
|
|
|
|