|
|
|
|
@ -1,20 +1,4 @@
|
|
|
|
|
<!--
|
|
|
|
|
TODO: 字典和统计接口待完善
|
|
|
|
|
|
|
|
|
|
需要引入的字典:
|
|
|
|
|
1. active_flag - 激活标识字典
|
|
|
|
|
2. maint_type - 保养类型字典
|
|
|
|
|
3. alarm_level - 报警级别字典
|
|
|
|
|
4. handle_status - 处理状态字典
|
|
|
|
|
5. bills_status - 工单状态字典
|
|
|
|
|
6. device_status - 设备状态字典
|
|
|
|
|
|
|
|
|
|
需要创建的统计接口:
|
|
|
|
|
1. getDmsDeviceStatistics() - 设备统计接口
|
|
|
|
|
返回:{ totalCount, runningCount, maintenanceCount, alarmCount, faultCount }
|
|
|
|
|
2. getDmsDeviceMaintenanceStats(machineId) - 设备维护统计接口
|
|
|
|
|
返回:{ plannedCount, temporaryCount, avgInterval, nextMaintenanceDate }
|
|
|
|
|
-->
|
|
|
|
|
<template>
|
|
|
|
|
<div class="dms-machine-ledger">
|
|
|
|
|
<!-- 工厂背景装饰 -->
|
|
|
|
|
@ -107,7 +91,7 @@
|
|
|
|
|
<el-form-item label="设备名称" prop="machineName">
|
|
|
|
|
<el-input v-model="queryParams.machineName" placeholder="请输入设备名称" clearable />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="设备位置" prop="machineLocation">
|
|
|
|
|
<!-- <el-form-item label="设备位置" prop="machineLocation">
|
|
|
|
|
<el-input v-model="queryParams.machineLocation" placeholder="请输入设备位置" clearable />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="设备状态" prop="machineStatus">
|
|
|
|
|
@ -121,7 +105,7 @@
|
|
|
|
|
<el-option v-for="type in deviceTypes" :key="type.deviceTypeId"
|
|
|
|
|
:label="type.deviceTypeName" :value="type.deviceTypeId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form-item>-->
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" icon="Search" @click="handleQuery" class="filter-btn-primary">搜索</el-button>
|
|
|
|
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
|
|
@ -174,7 +158,7 @@
|
|
|
|
|
</div>
|
|
|
|
|
<div class="meta-item">
|
|
|
|
|
<el-icon><Timer /></el-icon>
|
|
|
|
|
<span>运行 {{ calculateRunDays(machine.createTime) }} 天</span>
|
|
|
|
|
<span>建立 {{ calculateRunDays(machine.createTime) }} 天</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@ -201,10 +185,12 @@
|
|
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
|
|
<el-table-column label="设备编号" align="center" prop="machineCode" />
|
|
|
|
|
<el-table-column label="设备名称" align="center" prop="machineName" />
|
|
|
|
|
<el-table-column label="设备类型" align="center" prop="machineType">
|
|
|
|
|
<!-- <el-table-column label="设备类型" align="center" prop="machineType">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ getDeviceTypeName(scope.row.machineType) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>-->
|
|
|
|
|
<el-table-column label="设备类型" align="center" prop="deviceTypeName">
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="设备位置" align="center" prop="machineLocation" />
|
|
|
|
|
<el-table-column label="设备状态" align="center" prop="machineStatus">
|
|
|
|
|
@ -475,7 +461,7 @@
|
|
|
|
|
<el-divider />
|
|
|
|
|
<div class="overview-stats">
|
|
|
|
|
<div class="stat">
|
|
|
|
|
<span class="stat-label">运行天数</span>
|
|
|
|
|
<span class="stat-label">建立天数</span>
|
|
|
|
|
<span class="stat-value">{{ calculateRunDays(selectedMachine.createTime) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat">
|
|
|
|
|
@ -574,7 +560,8 @@
|
|
|
|
|
<el-descriptions :column="1" border>
|
|
|
|
|
<el-descriptions-item label="设备编号">{{ selectedMachine?.machineCode }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="设备名称">{{ selectedMachine?.machineName }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="设备类型">{{ getDeviceTypeName(selectedMachine?.machineType) }}</el-descriptions-item>
|
|
|
|
|
<!-- <el-descriptions-item label="设备类型">{{ getDeviceTypeName(selectedMachine?.machineType) }}</el-descriptions-item>-->
|
|
|
|
|
<el-descriptions-item label="设备类型">{{ selectedMachine?.deviceTypeName }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="设备位置">{{ selectedMachine?.machineLocation || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="设备状态">
|
|
|
|
|
<dict-tag :options="machine_status" :value="String(selectedMachine?.machineStatus ?? '')" />
|
|
|
|
|
@ -599,7 +586,7 @@
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<el-tab-pane label="维护信息" name="maintenance">
|
|
|
|
|
<!-- <el-tab-pane label="维护信息" name="maintenance">
|
|
|
|
|
<div class="detail-section maintenance-section">
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
@ -648,7 +635,41 @@
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tab-pane>-->
|
|
|
|
|
<!-- <el-tab-pane label="报警信息" name="alarm">
|
|
|
|
|
<div class="detail-section">
|
|
|
|
|
<el-card>
|
|
|
|
|
<template #header>
|
|
|
|
|
<span class="card-header-title">报警信息</span>
|
|
|
|
|
</template>
|
|
|
|
|
<el-table :data="alarmList" max-height="400">
|
|
|
|
|
<el-table-column prop="alarmTypeName" label="报警类型" />
|
|
|
|
|
<!– <el-table-column label="报警级别">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="alarm_level" :value="String(scope.row.alarmLevelId ?? '')" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>–>
|
|
|
|
|
<el-table-column prop="alarmLevelName" label="报警级别" />
|
|
|
|
|
<el-table-column prop="alarmContent" label="报警内容" show-overflow-tooltip />
|
|
|
|
|
<el-table-column label="处理状态">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="alarm_status" :value="String(scope.row.alarmStatus ?? '')" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="alarmBeginTime" label="开始时间">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ formatDateTime(scope.row.alarmBeginTime) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="alarmEndTime" label="结束时间">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ formatDateTime(scope.row.alarmEndTime) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</el-card>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>-->
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
@ -689,6 +710,7 @@ import {
|
|
|
|
|
ShoppingCart, CircleCheck, Position, MagicStick, Plus, Edit, Delete
|
|
|
|
|
} from '@element-plus/icons-vue';
|
|
|
|
|
import { getDmsBaseDeviceSupplierList } from '@/api/dms/dmsBaseDeviceSupplier';
|
|
|
|
|
import { getDmsDeviceMaintenanceStats } from '@/api/dms/dmsBillsMaintInstance';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
|
|
|
|
|
@ -705,7 +727,9 @@ const {
|
|
|
|
|
machine_data_type,
|
|
|
|
|
machine_data_encoding,
|
|
|
|
|
mes_class_type,
|
|
|
|
|
mes_instock_type
|
|
|
|
|
mes_instock_type,
|
|
|
|
|
alarm_status,
|
|
|
|
|
dms_inspect_status
|
|
|
|
|
} = toRefs<any>(proxy?.useDict(
|
|
|
|
|
'machine_status',
|
|
|
|
|
'debug_status',
|
|
|
|
|
@ -718,7 +742,9 @@ const {
|
|
|
|
|
'machine_data_type',
|
|
|
|
|
'machine_data_encoding',
|
|
|
|
|
'mes_class_type',
|
|
|
|
|
'mes_instock_type'
|
|
|
|
|
'mes_instock_type',
|
|
|
|
|
'alarm_status',
|
|
|
|
|
'dms_inspect_status'
|
|
|
|
|
));
|
|
|
|
|
// 本页还需要的其它字典(用于详情/统计处标签显示)
|
|
|
|
|
const { maint_type, alarm_level } = toRefs<any>(proxy?.useDict('maint_type', 'alarm_level'));
|
|
|
|
|
@ -737,6 +763,7 @@ const activeTab = ref('basic');
|
|
|
|
|
const lifecycleLoading = ref(false);
|
|
|
|
|
const selectedLifecycleTypes = ref([]);
|
|
|
|
|
const lifecycleEvents = ref([]);
|
|
|
|
|
const alarmList = ref([]);
|
|
|
|
|
// 防抖/竞态控制:仅应用最近一次生命周期数据请求的结果
|
|
|
|
|
const lifecycleRequestId = ref(0);
|
|
|
|
|
const currentTime = ref('');
|
|
|
|
|
@ -764,7 +791,8 @@ const queryParams = ref({
|
|
|
|
|
machineName: undefined,
|
|
|
|
|
machineLocation: undefined,
|
|
|
|
|
machineStatus: undefined,
|
|
|
|
|
machineType: undefined
|
|
|
|
|
machineType: undefined,
|
|
|
|
|
deviceTypeName: undefined,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 表单数据
|
|
|
|
|
@ -781,6 +809,8 @@ const initFormData: ProdBaseMachineInfoForm = {
|
|
|
|
|
remark: undefined,
|
|
|
|
|
photoAddress: undefined,
|
|
|
|
|
ossId: undefined,
|
|
|
|
|
|
|
|
|
|
deviceTypeName: undefined,
|
|
|
|
|
// workshopId: undefined,
|
|
|
|
|
// deviceModeId: undefined,
|
|
|
|
|
// machineIp: undefined,
|
|
|
|
|
@ -1004,7 +1034,7 @@ const formatDateTime = (date) => {
|
|
|
|
|
return proxy.parseTime(date, '{y}-{m}-{d} {h}:{i}');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 计算运行天数
|
|
|
|
|
// 计算建立天数
|
|
|
|
|
const calculateRunDays = (startDate) => {
|
|
|
|
|
if (!startDate) return 0;
|
|
|
|
|
const start = new Date(startDate);
|
|
|
|
|
@ -1198,7 +1228,6 @@ const loadLifecycleData = async () => {
|
|
|
|
|
details: [
|
|
|
|
|
{ label: '计划编号', value: purchase.workOrder },
|
|
|
|
|
{ label: '采购地点', value: purchase.purchasePosition },
|
|
|
|
|
{ label: '采购价格', value: purchase.purchasePrice || '-' },
|
|
|
|
|
{ label: '备注', value: purchase.remark || '-' }
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
@ -1227,7 +1256,7 @@ const loadLifecycleData = async () => {
|
|
|
|
|
tags: ['安装'],
|
|
|
|
|
details: [
|
|
|
|
|
{ label: '安装地点', value: install.installPosition },
|
|
|
|
|
{ label: '状态', value: install.activeFlag, dictOptions: active_flag?.value }
|
|
|
|
|
{ label: '激活状态', value: install.activeFlag, dictOptions: active_flag?.value }
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
@ -1310,7 +1339,7 @@ const loadLifecycleData = async () => {
|
|
|
|
|
{ label: '申请人', value: fault.applyUser },
|
|
|
|
|
{ label: '工单状态', value: fault.billsStatus, dictOptions: bills_status?.value },
|
|
|
|
|
{ label: '故障描述', value: fault.faultDescription || '-' },
|
|
|
|
|
{ label: '备注', value: fault.remark || '-' }
|
|
|
|
|
// { label: '备注', value: fault.remark || '-' }
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
@ -1340,7 +1369,7 @@ const loadLifecycleData = async () => {
|
|
|
|
|
details: [
|
|
|
|
|
{ label: '巡检单号', value: inspect.billsInspectCode },
|
|
|
|
|
{ label: '巡检类型', value: inspect.inspectType === '1' ? '巡检' : '点检' },
|
|
|
|
|
{ label: '巡检状态', value: inspect.inspectStatus || '-' },
|
|
|
|
|
{ label: '巡检状态', value: inspect.inspectStatus, dictOptions: dms_inspect_status?.value},
|
|
|
|
|
{ label: '计划开始时间', value: formatDateTime(inspect.planBeginTime) },
|
|
|
|
|
// { label: '计划结束时间', value: formatDateTime(inspect.planEndTime) }
|
|
|
|
|
]
|
|
|
|
|
@ -1354,23 +1383,23 @@ const loadLifecycleData = async () => {
|
|
|
|
|
|
|
|
|
|
case 'alarm':
|
|
|
|
|
try {
|
|
|
|
|
const res = await getBaseAlarmInfoList({ machineId:machineId });
|
|
|
|
|
const res = await getBaseAlarmInfoList({ deviceId: machineId });
|
|
|
|
|
const alarms = getListData(res);
|
|
|
|
|
if (alarms.length > 0) {
|
|
|
|
|
alarms.slice(0, 10).forEach(alarm => {
|
|
|
|
|
events.push({
|
|
|
|
|
id: `alarm-${alarm.alarmId}`,
|
|
|
|
|
id: `alarm-${alarm.alarmInfoId}`,
|
|
|
|
|
type: 'alarm',
|
|
|
|
|
title: '设备报警',
|
|
|
|
|
description: `报警类型: ${alarm.alarmTypeName || '-'}`,
|
|
|
|
|
time: alarm.alarmTime,
|
|
|
|
|
time: alarm.alarmBeginTime || alarm.handleTime || alarm.createTime,
|
|
|
|
|
icon: markRaw(Notification),
|
|
|
|
|
color: '#a8edea',
|
|
|
|
|
tags: ['报警', alarm.alarmLevelName],
|
|
|
|
|
details: [
|
|
|
|
|
{ label: '报警级别', value: alarm.alarmLevel ?? alarm.alarmLevelName, dictOptions: alarm_level?.value },
|
|
|
|
|
{ label: '报警级别', value: alarm.alarmLevelName },
|
|
|
|
|
{ label: '报警内容', value: alarm.alarmContent },
|
|
|
|
|
{ label: '处理状态', value: alarm.handleStatus, dictOptions: handle_status?.value }
|
|
|
|
|
{ label: '处理状态', value: alarm.alarmStatus, dictOptions: alarm_status?.value }
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
@ -1411,7 +1440,8 @@ const viewDetails = async (machine) => {
|
|
|
|
|
// 加载详情数据
|
|
|
|
|
await Promise.all([
|
|
|
|
|
loadTechnicalParams(machine.machineId),
|
|
|
|
|
loadMaintenanceStats(machine.machineId)
|
|
|
|
|
loadMaintenanceStats(machine.machineId),
|
|
|
|
|
loadAlarmList(machine.machineId)
|
|
|
|
|
]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -1434,7 +1464,7 @@ const loadTechnicalParams = async (machineId) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 加载维护统计
|
|
|
|
|
const loadMaintenanceStats = async (machineId) => {
|
|
|
|
|
/*const loadMaintenanceStats = async (machineId) => {
|
|
|
|
|
try {
|
|
|
|
|
const statsRes = await getDmsDeviceMaintenanceStats({ machineId });
|
|
|
|
|
const statsData = statsRes.data || {};
|
|
|
|
|
@ -1474,6 +1504,19 @@ const loadMaintenanceStats = async (machineId) => {
|
|
|
|
|
maintenanceRecords.value = [];
|
|
|
|
|
proxy?.$modal.msgError('获取维护统计失败');
|
|
|
|
|
}
|
|
|
|
|
};*/
|
|
|
|
|
|
|
|
|
|
// 加载报警列表
|
|
|
|
|
const loadAlarmList = async (machineId) => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getBaseAlarmInfoList({ deviceId: machineId, pageNum: 1, pageSize: 50 });
|
|
|
|
|
const list = (res as any)?.rows ?? (res as any)?.data ?? [];
|
|
|
|
|
alarmList.value = list || [];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取报警列表失败:', error);
|
|
|
|
|
alarmList.value = [];
|
|
|
|
|
proxy?.$modal.msgError('获取报警列表失败');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 加载生命周期类型统计
|
|
|
|
|
@ -1498,7 +1541,7 @@ const loadLifecycleTypes = async () => {
|
|
|
|
|
countMaintInstancesByMachineId(machineId).catch(() => ({ data: 0 })),
|
|
|
|
|
getFaultInstanceCount({ machineId }).catch(() => ({ data: 0 })),
|
|
|
|
|
countInspectInstancesByMachineId(machineId).catch(() => ({ data: 0 })),
|
|
|
|
|
getAlarmInfoCount({ machineId }).catch(() => ({ data: 0 }))
|
|
|
|
|
getAlarmInfoCount({ deviceId: machineId }).catch(() => ({ data: 0 }))
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 更新类型计数
|
|
|
|
|
|