style:设备台账-关键件/备件列表更换接口

main
黄伟杰 11 hours ago
parent 172d5cacea
commit a9eeef6abd

@ -41,6 +41,7 @@ export interface DeviceOperationOverviewTimelineRowVO {
id: string
name: string
utilizationRate: number
totalWarningTime?: number
segments: DeviceOperationOverviewTimelineSegmentVO[]
}

@ -103,8 +103,12 @@ export const DeviceLedgerApi = {
exportDeviceLedger: async (params) => {
return await request.download({ url: `/mes/device-ledger/export-excel`, params })
},
exportSpareBased: async (params) => {
return await request.download({ url: `/mes/device-ledger/export-spare-based`, params })
exportDeviceLedgerSpare: async (params: { deviceLedgerId: string | number }) => {
return await request.download({ url: `/mes/device-ledger/export-spare`, params })
},
getDeviceLedgerSparePage: async (params: any) => {
return await request.get({ url: `/mes/device-ledger/spare-page`, params })
},
exportMold: async (params) => {

@ -419,7 +419,7 @@ export default {
currentStatus: 'Status',
runningTime: 'Running Time (Today)',
standbyTime: 'Idle Time (Today)',
alarmTime: 'Alarm Time (Today)',
alarmTime: 'Alarm Time (Hours)',
efficiency: 'Activation (Today)'
},
empty: 'No device operation data'
@ -5681,7 +5681,7 @@ export default {
tableRunningTimeColumn: 'Running Time (Hours)',
tableStandbyTimeColumn: 'Standby Time (Hours)',
tableFaultTimeColumn: 'Fault Time (Hours)',
tableWarningTimeColumn: 'Warning Time (Hours)',
tableWarningTimeColumn: 'Alarm Time (Hours)',
tableUtilizationRateColumn: 'Utilization Rate',
tableUtilizationRateTooltip:
'Power-on Rate = Online Time / Total Time\nOnline Time = Running Time + Standby Time + Fault Time\nUtilization Rate = Running Time / Online Time\nPower-on Rate = (Running Time + Standby Time + Fault Time) / Total Time',

@ -419,7 +419,7 @@ export default {
currentStatus: '当前状态',
runningTime: '运行时间(今日)',
standbyTime: '空闲时间(今日)',
alarmTime: '报警时间(今日)',
alarmTime: '报警时间(小时)',
efficiency: '稼动率(今日)'
},
empty: '暂无设备运行数据'
@ -5575,7 +5575,7 @@ export default {
tableRunningTimeColumn: '运行时间(小时)',
tableStandbyTimeColumn: '待机时间(小时)',
tableFaultTimeColumn: '故障时间(小时)',
tableWarningTimeColumn: '时间(小时)',
tableWarningTimeColumn: '警时间(小时)',
tableUtilizationRateColumn: '稼动率',
tableUtilizationRateTooltip:
'开机率 = 在线时间 / 总的时间\n在线时间 = 运行时间 + 空闲时间 + 故障时间\n稼动率 = 运行时间 / 在线时间\n开机率 =(运行时间 + 空闲时间 + 故障时间)/ 总的时间',

@ -86,12 +86,12 @@
prop="totalFaultTime"
min-width="140px"
sortable />
<!-- <el-table-column
<el-table-column
:label="t('DataCollection.RunReport.tableWarningTimeColumn')"
align="center"
prop="totalWarningTime"
min-width="140px"
sortable /> -->
sortable />
<el-table-column
align="center"
prop="utilizationRate"

@ -423,17 +423,87 @@
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.criticalComponent')" name="criticalComponent">
<div class="device-ledger-tab-toolbar">
<el-button
type="success"
plain
:loading="criticalExportLoading"
@click="handleExportCriticalComponent"
v-hasPermi="['mes:device-ledger:export']"
<el-form
ref="criticalComponentQueryFormRef"
:model="criticalComponentQueryParams"
:inline="true"
class="device-ledger-critical-component-query"
>
<Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
</el-button>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.code')" prop="code">
<el-input
v-model="criticalComponentQueryParams.code"
:placeholder="t('EquipmentManagement.EquipmentKeyItems.placeholderCode')"
clearable
class="!w-240px"
@keyup.enter="handleQueryCriticalComponent"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.name')" prop="name">
<el-input
v-model="criticalComponentQueryParams.name"
:placeholder="t('EquipmentManagement.EquipmentKeyItems.placeholderName')"
clearable
class="!w-240px"
@keyup.enter="handleQueryCriticalComponent"
/>
</el-form-item>
<el-form-item
:label="t('EquipmentManagement.EquipmentKeyItems.description')"
prop="description"
>
<el-input
v-model="criticalComponentQueryParams.description"
:placeholder="t('EquipmentManagement.EquipmentKeyItems.placeholderDescription')"
clearable
class="!w-240px"
@keyup.enter="handleQueryCriticalComponent"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.remark')" prop="remark">
<el-input
v-model="criticalComponentQueryParams.remark"
:placeholder="t('EquipmentManagement.EquipmentKeyItems.placeholderRemark')"
clearable
class="!w-240px"
@keyup.enter="handleQueryCriticalComponent"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.createTime')" prop="createTime">
<el-date-picker
v-model="criticalComponentQueryParams.createTime"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
:start-placeholder="t('common.startTimeText')"
:end-placeholder="t('common.endTimeText')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-220px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" plain @click="handleQueryCriticalComponent">
<Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
</el-button>
<el-button @click="resetCriticalComponentQuery">
<Icon icon="ep:refresh" class="mr-5px" /> {{ t('common.reset') }}
</el-button>
<el-button
type="success"
plain
:loading="criticalExportLoading"
@click="handleExportCriticalComponent"
v-hasPermi="['mes:device-ledger:export']"
>
<Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
</el-button>
</el-form-item>
</el-form>
</div>
<el-table v-loading="tableLoading" :data="detailData?.componentList" :stripe="true" :show-overflow-tooltip="true">
<el-table
v-loading="criticalComponentLoading"
:data="criticalComponentList"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.componentCode')" align="center" prop="code" min-width="140" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.componentName')" align="center" prop="name" min-width="140" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentKeyItems.count')" align="center" prop="count" min-width="180" />
@ -441,6 +511,12 @@
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.remark')" align="center" prop="remark" min-width="180" />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')" align="center" prop="createTime" :formatter="dateFormatter" width="180" sortable />
</el-table>
<Pagination
:total="criticalComponentTotal"
v-model:page="criticalComponentQueryParams.pageNo"
v-model:limit="criticalComponentQueryParams.pageSize"
@pagination="getCriticalComponentList"
/>
</el-tab-pane>
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.sparePart')" name="component">
@ -455,13 +531,19 @@
<Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
</el-button>
</div>
<el-table v-loading="tableLoading" :data="detailData?.beijianList" :stripe="true" :show-overflow-tooltip="true">
<el-table v-loading="spareLoading" :data="spareList" :stripe="true" :show-overflow-tooltip="true">
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.spareCode')" align="center" prop="barCode" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.spareName')" align="left" prop="name" width="220px" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.category')" align="center" prop="categoryName" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.category')" align="center" prop="subCategoryName" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.unit')" align="center" prop="unitName" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')" align="center" prop="createTime" :formatter="dateFormatter" width="180px" sortable />
</el-table>
<Pagination
:total="spareTotal"
v-model:page="spareQueryParams.pageNo"
v-model:limit="spareQueryParams.pageSize"
@pagination="getSpareList"
/>
</el-tab-pane>
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.mold')" name="mold">
@ -497,7 +579,8 @@ import { dateFormatter, formatDate } from '@/utils/formatTime'
import download from '@/utils/download'
import { DeviceLedgerApi, DeviceLedgerVO } from '@/api/mes/deviceledger'
import { DeviceTypeApi, DeviceTypeTreeVO } from '@/api/mes/devicetype'
import { CriticalComponentApi } from '@/api/mes/criticalComponent'
import { CriticalComponentApi, CriticalComponentVO } from '@/api/mes/criticalComponent'
import { ProductVO } from '@/api/erp/product/product'
import { TicketManagementApi } from '@/api/mes/ticketManagement'
import { DvRepairApi } from '@/api/mes/dvrepair'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
@ -522,6 +605,67 @@ const detailLoading = ref(false)
const tableLoading = ref(false)
const detailData = ref<DeviceLedgerDetailVO | undefined>()
const detailActiveTab = ref('check')
const criticalComponentLoading = ref(false)
const criticalComponentList = ref<CriticalComponentVO[]>([])
const criticalComponentTotal = ref(0)
const criticalComponentQueryFormRef = ref()
const criticalComponentQueryParams = reactive({
pageNo: 1,
pageSize: 10,
deviceLedgerId: undefined as string | undefined,
code: undefined as string | undefined,
name: undefined as string | undefined,
description: undefined as string | undefined,
remark: undefined as string | undefined,
createTime: [] as string[]
})
const spareLoading = ref(false)
const spareList = ref<ProductVO[]>([])
const spareTotal = ref(0)
const spareQueryParams = reactive({
pageNo: 1,
pageSize: 10
})
const getCriticalComponentList = async () => {
if (!deviceId.value) return
criticalComponentLoading.value = true
try {
const data = await CriticalComponentApi.getCriticalComponentPage({
...criticalComponentQueryParams,
deviceLedgerId: deviceId.value
})
criticalComponentList.value = data.list ?? []
criticalComponentTotal.value = data.total ?? 0
} finally {
criticalComponentLoading.value = false
}
}
const handleQueryCriticalComponent = async () => {
criticalComponentQueryParams.pageNo = 1
await getCriticalComponentList()
}
const resetCriticalComponentQuery = async () => {
criticalComponentQueryFormRef.value?.resetFields()
await handleQueryCriticalComponent()
}
const getSpareList = async () => {
if (!deviceId.value) return
spareLoading.value = true
try {
const data = await DeviceLedgerApi.getDeviceLedgerSparePage({
...spareQueryParams,
deviceLedgerId: deviceId.value
})
spareList.value = data.list ?? []
spareTotal.value = data.total ?? 0
} finally {
spareLoading.value = false
}
}
const deviceTypeNameMap = ref<Record<string, string>>({})
@ -965,7 +1109,7 @@ const handleExportSpareBased = async () => {
try {
await message.exportConfirm()
spareExportLoading.value = true
const data = await DeviceLedgerApi.exportSpareBased({ id: deviceId.value })
const data = await DeviceLedgerApi.exportDeviceLedgerSpare({ deviceLedgerId: deviceId.value })
download.excel(data, '备件.xls')
} catch {
} finally {
@ -999,6 +1143,8 @@ const getDetail = async () => {
onMounted(async () => {
await getTypeTreeForNameMap()
await getDetail()
await getCriticalComponentList()
await getSpareList()
})
</script>
@ -1203,6 +1349,10 @@ onMounted(async () => {
text-align: right;
}
.device-ledger-critical-component-query {
text-align: left;
}
.device-ledger-history-items {
display: flex;
flex-direction: column;

@ -50,7 +50,7 @@
<div v-if="alarmDevices.length" class="alarm-list">
<div v-for="item in alarmDevices" :key="item.id" class="alarm-item">
<strong :title="item.name">{{ item.name }}</strong>
<span>{{ t('AlarmBoard.alarmPrefix') }} {{ formatHours(item.alarmTime) }}</span>
<span>{{ t('AlarmBoard.alarmPrefix') }} {{ formatHours(item.totalWarningTime) }}</span>
<span>{{ item.lastReportTime }}</span>
</div>
</div>
@ -69,7 +69,7 @@
<span>{{ t('Detail.columns.currentStatus') }}</span>
<span>运行时间(小时)</span>
<span>待机时间(小时)</span>
<span>故障时间(小时)</span>
<span>{{ t('Detail.columns.alarmTime') }}</span>
<span>稼动率</span>
</div>
<div v-if="pagedRows.length" class="table-body">
@ -85,7 +85,7 @@
</span>
<span>{{ formatHours(row.runningTime) }}</span>
<span>{{ formatHours(row.standbyTime) }}</span>
<span>{{ formatHours(row.alarmTime) }}</span>
<span>{{ formatHours(row.totalWarningTime) }}</span>
<span class="rate">{{ formatPercentText(row.utilizationRate) }}</span>
</div>
</div>
@ -158,7 +158,7 @@ interface DetailRow {
status: RunStatus
runningTime: number
standbyTime: number
alarmTime: number
totalWarningTime: number
utilizationRate: string
lastReportTime: string
}
@ -273,9 +273,9 @@ const detailRows = computed<DetailRow[]>(() => {
status,
runningTime: Number(row.totalRunningTime) || 0,
standbyTime: Number(row.totalStandbyTime) || 0,
alarmTime: Number(row.totalFaultTime) || 0,
totalWarningTime: Number(row.totalWarningTime) || 0,
utilizationRate: row.utilizationRate || '0%',
lastReportTime: status === 'fault' || Number(row.totalFaultTime) > 0 ? lastUpdateTime.value || '-' : '-'
lastReportTime: status === 'fault' || Number(row.totalWarningTime) > 0 ? lastUpdateTime.value || '-' : '-'
}
})
})
@ -296,8 +296,8 @@ const pagedRows = computed(() => {
const detailPageText = computed(() => `${detailPage.value} / ${totalDetailPages.value}`)
const alarmDevices = computed(() => {
return detailRows.value
.filter((item) => item.status === 'fault' || item.alarmTime > 0)
.sort((a, b) => b.alarmTime - a.alarmTime)
.filter((item) => item.status === 'fault' || item.totalWarningTime > 0)
.sort((a, b) => b.totalWarningTime - a.totalWarningTime)
.slice(0, 2)
})
const hourlyRates = computed(() => {

@ -84,7 +84,7 @@
</span>
<span>{{ formatMinutes(row.runningMinutes) }}</span>
<span>{{ formatMinutes(row.standbyMinutes) }}</span>
<span>{{ formatMinutes(row.alarmMinutes) }}</span>
<span>{{ formatHours(row.totalWarningTime) }}</span>
<span class="rate">{{ formatPercent(row.utilizationRate) }}</span>
</div>
</div>
@ -140,7 +140,7 @@ interface DetailRow {
status: RunStatus
runningMinutes: number
standbyMinutes: number
alarmMinutes: number
totalWarningTime: number
utilizationRate: number
lastReportTime: string
}
@ -259,9 +259,9 @@ const detailRows = computed<DetailRow[]>(() => {
status,
runningMinutes: minutes.running,
standbyMinutes: minutes.standby,
alarmMinutes: minutes.fault,
totalWarningTime: Number(row.totalWarningTime) || 0,
utilizationRate: Number(row.utilizationRate) || 0,
lastReportTime: status === 'fault' || minutes.fault > 0 ? lastUpdateTime.value || '-' : '-'
lastReportTime: status === 'fault' || Number(row.totalWarningTime) > 0 ? lastUpdateTime.value || '-' : '-'
}
})
})
@ -283,8 +283,8 @@ const pagedRows = computed(() => {
const detailPageText = computed(() => `${detailPage.value} / ${totalDetailPages.value}`)
const alarmDevices = computed(() => {
return detailRows.value
.filter((item) => item.status === 'fault' || item.alarmMinutes > 0)
.sort((a, b) => b.alarmMinutes - a.alarmMinutes)
.filter((item) => item.status === 'fault' || item.totalWarningTime > 0)
.sort((a, b) => b.totalWarningTime - a.totalWarningTime)
.slice(0, 2)
})
const hourlyRates = computed(() =>
@ -310,6 +310,12 @@ const formatMinutes = (minutes: number) => {
return t('Time.hourMinute', { hour: hours, minute: rest })
}
const formatHours = (value?: number) => {
const hours = Number(value)
const safeHours = Number.isFinite(hours) && hours > 0 ? Math.round(hours * 100) / 100 : 0
return t('Time.hour', { hour: safeHours })
}
const average = (values: number[]) => {
const valid = values.filter((item) => Number.isFinite(item))
if (!valid.length) return 0

Loading…
Cancel
Save