修复批次托盘分页和设备监控统计排序
Some checks failed
Release pipeline / publish (push) Has been cancelled
Release pipeline / Always run job (push) Has been cancelled

This commit is contained in:
sheng
2026-06-25 01:00:08 +08:00
parent c2db61dad9
commit f07f5d91c4
2 changed files with 119 additions and 27 deletions

View File

@@ -297,12 +297,30 @@ export default {
},
methods: {
normalizeListResponse (res) {
const data = Array.isArray(res) ? res : (res && res.data) || []
if (Array.isArray(data)) return { list: data, total: data.length }
return {
list: data.data || [],
total: data.count || 0
const root = res || {}
const data = root.data !== undefined ? root.data : root
if (Array.isArray(data)) {
return { list: data, total: Number(root.count || root.total || data.length) }
}
if (data && Array.isArray(data.list)) {
return { list: data.list, total: Number(root.count || root.total || data.count || data.total || data.list.length) }
}
if (data && Array.isArray(data.rows)) {
return { list: data.rows, total: Number(root.count || root.total || data.count || data.total || data.rows.length) }
}
if (data && Array.isArray(data.records)) {
return { list: data.records, total: Number(root.count || root.total || data.count || data.total || data.records.length) }
}
if (data && Array.isArray(data.data)) {
return { list: data.data, total: Number(root.count || root.total || data.count || data.total || data.data.length) }
}
if (data && data.data && Array.isArray(data.data.data)) {
return { list: data.data.data, total: Number(root.count || root.total || data.count || data.total || data.data.count || data.data.total || data.data.data.length) }
}
if (data && data.data && Array.isArray(data.data.list)) {
return { list: data.data.list, total: Number(root.count || root.total || data.count || data.total || data.data.count || data.data.total || data.data.list.length) }
}
return { list: [], total: Number(root.count || root.total || data.count || data.total || 0) }
},
async fetchData () {
this.loading = true
@@ -329,8 +347,8 @@ export default {
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.pagination.current = Number(page.current || page.currentPage || 1)
this.pagination.size = Number(page.size || page.pageSize || this.pagination.size)
this.fetchData()
},
openTrayDetails (row) {

View File

@@ -21,9 +21,6 @@
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">
{{ $t(key('query')) }}
</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">
{{ $t(key('reset')) }}
</el-button>
@@ -54,12 +51,13 @@
<page-table
:columns="columns"
:data="tableData"
:data="sortedTableData"
:loading="loading"
:toolbar-buttons="[]"
:row-buttons="[]"
:pagination="null"
:table-attrs="{ size: 'mini', rowKey: 'id', highlightCurrentRow: true }"
:table-listeners="tableListeners"
auto-height
>
<template #col-status="{ row }">
@@ -103,39 +101,53 @@ export default {
activeStatus: '',
tableData: [],
statusNum: [],
totalCount: 0,
deviceCategoryOptions: [],
search: {
device_category_id: ''
},
sortState: {
prop: '',
order: ''
},
refreshTimer: null
}
},
computed: {
columns () {
return useTableColumns([
{ prop: 'code', label: this.key('device_code'), minWidth: 140, showOverflowTooltip: true },
{ prop: 'name', label: this.key('device_name'), minWidth: 160, showOverflowTooltip: true },
{ prop: 'area_name', label: this.key('area'), minWidth: 120, showOverflowTooltip: true },
{ prop: 'line_name', label: this.key('production_line'), minWidth: 140, showOverflowTooltip: true },
{ prop: 'workstation_name', label: this.key('workstation'), minWidth: 140, showOverflowTooltip: true },
{ prop: 'heartbeat', label: this.key('last_response'), minWidth: 170, showOverflowTooltip: true },
{ prop: 'status', label: this.key('work_status'), minWidth: 110, slot: 'status' },
{ prop: 'msg', label: this.key('msg'), minWidth: 180, slot: 'msg', showOverflowTooltip: true }
{ prop: 'code', label: this.key('device_code'), minWidth: 140, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'name', label: this.key('device_name'), minWidth: 160, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'area_name', label: this.key('area'), minWidth: 120, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'line_name', label: this.key('production_line'), minWidth: 140, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'workstation_name', label: this.key('workstation'), minWidth: 140, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'heartbeat', label: this.key('last_response'), minWidth: 170, sortable: 'custom', showOverflowTooltip: true },
{ prop: 'status', label: this.key('work_status'), minWidth: 110, sortable: 'custom', slot: 'status' },
{ prop: 'msg', label: this.key('msg'), minWidth: 180, sortable: 'custom', slot: 'msg', showOverflowTooltip: true }
], {
selectionWidth: 0,
indexWidth: 55
})
},
tableListeners () {
return {
'sort-change': this.onSortChange
}
},
statusCountMap () {
return this.statusNum.reduce((result, item) => {
result[item.status] = Number(item.num || 0)
const status = this.normalizeStatus(item.status || item.key || item.name || item.type)
if (status) {
result[status] = Number(item.num || item.count || item.value || item.total || 0)
}
return result
}, {})
},
totalDeviceCount () {
return Object.keys(this.statusCountMap).reduce((total, status) => {
const statusTotal = Object.keys(this.statusCountMap).reduce((total, status) => {
return total + this.statusCountMap[status]
}, 0)
return statusTotal || this.totalCount || this.tableData.length
},
statusCards () {
return Object.keys(STATUS_META).map(status => ({
@@ -143,6 +155,13 @@ export default {
count: this.statusCountMap[status] || 0,
...STATUS_META[status]
}))
},
sortedTableData () {
if (!this.sortState.prop || !this.sortState.order) return this.tableData
const direction = this.sortState.order === 'ascending' ? 1 : -1
return [...this.tableData].sort((a, b) => {
return this.compareValue(a[this.sortState.prop], b[this.sortState.prop]) * direction
})
}
},
mounted () {
@@ -164,13 +183,15 @@ export default {
this.fetchData()
},
normalizePayload (res) {
const payload = res && res.data !== undefined ? res.data : (res || {})
if (!res) return {}
if (Array.isArray(res)) return { data: res, status_num: [] }
if (res.data && !Array.isArray(res.data) && (res.data.data || res.data.status_num || res.data.statusNum || res.data.status_count || res.data.statusCount)) {
return res.data
}
const payload = res || {}
if (Array.isArray(payload)) {
return { data: payload, status_num: [] }
}
if (payload && payload.data && !Array.isArray(payload.data) && (payload.data.data || payload.data.status_num)) {
return payload.data
}
return payload || {}
},
normalizeList (res) {
@@ -178,8 +199,37 @@ export default {
if (Array.isArray(payload)) return payload
if (Array.isArray(payload.data)) return payload.data
if (Array.isArray(payload.list)) return payload.list
if (Array.isArray(payload.rows)) return payload.rows
if (Array.isArray(payload.records)) return payload.records
return []
},
normalizeStatus (status) {
return String(status || '').toUpperCase()
},
normalizeStatusNum (payload, list) {
const statusNum = payload.status_num || payload.statusNum || payload.status_count || payload.statusCount || payload.status_counts || payload.statusCounts
if (Array.isArray(statusNum)) return statusNum
if (statusNum && typeof statusNum === 'object') {
return Object.keys(statusNum).map(status => ({
status,
num: statusNum[status]
}))
}
const counts = list.reduce((result, row) => {
const status = this.normalizeStatus(row.status)
if (status) {
result[status] = (result[status] || 0) + 1
}
return result
}, {})
return Object.keys(counts).map(status => ({
status,
num: counts[status]
}))
},
normalizeTotal (payload, list) {
return Number(payload.count || payload.total || payload.total_count || payload.totalCount || list.length || 0)
},
async loadDeviceCategoryOptions () {
try {
const res = await getDeviceCategoryAll()
@@ -196,6 +246,28 @@ export default {
onSearch () {
this.fetchData()
},
onSortChange ({ prop, order }) {
this.sortState = {
prop: prop || '',
order: order || ''
}
},
compareValue (left, right) {
if (left === right) return 0
if (left === undefined || left === null || left === '') return -1
if (right === undefined || right === null || right === '') return 1
const leftNumber = Number(left)
const rightNumber = Number(right)
if (!Number.isNaN(leftNumber) && !Number.isNaN(rightNumber)) {
return leftNumber - rightNumber
}
const leftDate = Date.parse(left)
const rightDate = Date.parse(right)
if (!Number.isNaN(leftDate) && !Number.isNaN(rightDate)) {
return leftDate - rightDate
}
return String(left).localeCompare(String(right), 'zh-Hans-CN')
},
async fetchData (showLoading = true) {
if (showLoading) this.loading = true
try {
@@ -204,8 +276,10 @@ export default {
device_category_id: this.search.device_category_id
})
const payload = this.normalizePayload(res)
this.statusNum = Array.isArray(payload.status_num) ? payload.status_num : []
this.tableData = Array.isArray(payload.data) ? payload.data : []
const list = this.normalizeList(payload)
this.statusNum = this.normalizeStatusNum(payload, list)
this.totalCount = this.normalizeTotal(payload, list)
this.tableData = list
} finally {
if (showLoading) this.loading = false
}