|
|
|
|
@ -7,9 +7,36 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 筛选器容器 -->
|
|
|
|
|
<div class="filters-row">
|
|
|
|
|
<div class="filter-container">
|
|
|
|
|
<span class="filter-label">完成度筛选:</span>
|
|
|
|
|
<el-select v-model="selectedCompletionLevel" @change="onCompletionLevelChange" placeholder="请选择完成度" style="width: 150px">
|
|
|
|
|
<el-option label="全部显示" value="all" />
|
|
|
|
|
<el-option label="0% - 25%" value="low" />
|
|
|
|
|
<el-option label="25% - 75%" value="medium" />
|
|
|
|
|
<el-option label="75% - 100%" value="high" />
|
|
|
|
|
<el-option label="100%" value="full" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="filter-container">
|
|
|
|
|
<span class="filter-label">机台筛选:</span>
|
|
|
|
|
<el-select v-model="selectedEquipment" @change="onEquipmentChange" placeholder="请选择机台" style="width: 200px">
|
|
|
|
|
<el-option label="全部机台" value="all" />
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="equipment in equipmentList"
|
|
|
|
|
:key="equipment"
|
|
|
|
|
:label="equipment"
|
|
|
|
|
:value="equipment"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 调试信息 -->
|
|
|
|
|
<div v-if="!loading" style="margin-bottom: 10px; font-size: 12px; color: #666;">
|
|
|
|
|
调试信息: 获取到 {{ equipmentData.length }} 条设备数据,表格共 {{ tableData.length }} 行
|
|
|
|
|
调试信息: 获取到 {{ equipmentData.length }} 条设备数据,筛选后 {{ filteredEquipmentData.length }} 条,表格共 {{ tableData.length }} 行
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-loading="loading" class="table-wrapper">
|
|
|
|
|
@ -122,29 +149,149 @@ const props = defineProps({
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const equipmentData = ref([])
|
|
|
|
|
|
|
|
|
|
// 机台筛选相关状态
|
|
|
|
|
const selectedEquipment = ref('all')
|
|
|
|
|
|
|
|
|
|
// 完成度筛选相关状态
|
|
|
|
|
const selectedCompletionLevel = ref('all') // 默认显示全部
|
|
|
|
|
|
|
|
|
|
// 当组件加载时,使用父组件传递的数据
|
|
|
|
|
equipmentData.value = props.equipmentData
|
|
|
|
|
|
|
|
|
|
// 计算属性:获取设备列表(用于筛选器)
|
|
|
|
|
const equipmentList = computed(() => {
|
|
|
|
|
// 从设备数据中提取唯一的设备代码
|
|
|
|
|
return [...new Set(equipmentData.value.map(equipment => equipment.equipment_code))].sort();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 计算属性:筛选后的设备数据
|
|
|
|
|
const filteredEquipmentData = computed(() => {
|
|
|
|
|
// 根据选择的机台筛选数据
|
|
|
|
|
if (selectedEquipment.value === 'all') {
|
|
|
|
|
return equipmentData.value;
|
|
|
|
|
} else {
|
|
|
|
|
return equipmentData.value.filter(equipment => equipment.equipment_code === selectedEquipment.value);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 设备代码与轴号的映射表
|
|
|
|
|
const equipmentAxlesMap = {
|
|
|
|
|
'QB001': ['左边', '右边'],
|
|
|
|
|
'QB002': ['左边', '右边'],
|
|
|
|
|
'QB003': ['左边', '右边'],
|
|
|
|
|
'QB004': ['左1', '左2', '左3', '左4', '左5', '右1', '右2', '右3', '右4', '右5'],
|
|
|
|
|
'QB0042': ['左1', '左2', '左3', '左4', '左5', '右1', '右2', '右3', '右4', '右5'],
|
|
|
|
|
'QB005': ['左1', '左2', '左3', '左4', '左5', '左6', '右1', '右2', '右3', '右4', '右5', '右6'],
|
|
|
|
|
'QB007': ['左边', '右边'],
|
|
|
|
|
'QB008': ['左边', '右边'],
|
|
|
|
|
'QB009': ['左边', '右边'],
|
|
|
|
|
'QB010': ['左边', '右边'],
|
|
|
|
|
'QB011': ['左边', '右边'],
|
|
|
|
|
'QB012': ['左边', '右边'],
|
|
|
|
|
'QB013': ['左边', '右边'],
|
|
|
|
|
'QB014': ['左边', '右边'],
|
|
|
|
|
'QB015': ['左边', '右边'],
|
|
|
|
|
'QB016': ['左边', '右边'],
|
|
|
|
|
'QB017': ['左边', '右边'],
|
|
|
|
|
'QB018': ['左1', '左2', '右1', '右2'],
|
|
|
|
|
'QB019': ['左1', '左2', '右1', '右2'],
|
|
|
|
|
'QB020': ['左1', '左2', '右1', '右2'],
|
|
|
|
|
'QB024': ['左1', '左2', '左3', '左4', '右1', '右2', '右3', '右4'],
|
|
|
|
|
'QB025': ['左边', '右边'],
|
|
|
|
|
'QB026': ['左边', '右边'],
|
|
|
|
|
'QB027': ['左边', '右边'],
|
|
|
|
|
'QB028': ['左1', '左2', '右1', '右2'],
|
|
|
|
|
'QB029': ['左边', '右边'],
|
|
|
|
|
'QB030': ['左边', '右边'],
|
|
|
|
|
'QB031': ['左边', '右边'],
|
|
|
|
|
'QB032': ['左边', '右边'],
|
|
|
|
|
'QB033': ['左边', '右边'],
|
|
|
|
|
'QB034': ['左边', '右边']
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 判断是否应该显示轴
|
|
|
|
|
const shouldShowAxle = (degree) => {
|
|
|
|
|
if (!degree) return false;
|
|
|
|
|
|
|
|
|
|
const percentage = degree * 100;
|
|
|
|
|
|
|
|
|
|
switch (selectedCompletionLevel.value) {
|
|
|
|
|
case 'all':
|
|
|
|
|
return true;
|
|
|
|
|
case 'low':
|
|
|
|
|
return percentage >= 0 && percentage < 25;
|
|
|
|
|
case 'medium':
|
|
|
|
|
return percentage >= 25 && percentage < 75;
|
|
|
|
|
case 'high':
|
|
|
|
|
return percentage >= 75 && percentage < 100;
|
|
|
|
|
case 'full':
|
|
|
|
|
return percentage >= 100;
|
|
|
|
|
default:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 计算属性:展开状态记录为表格行数据
|
|
|
|
|
const tableData = computed(() => {
|
|
|
|
|
if (!equipmentData.value.length) return [];
|
|
|
|
|
if (!filteredEquipmentData.value.length) return [];
|
|
|
|
|
|
|
|
|
|
// 展开每个设备的状态记录为表格行
|
|
|
|
|
const rows = [];
|
|
|
|
|
equipmentData.value.forEach(equipment => {
|
|
|
|
|
filteredEquipmentData.value.forEach(equipment => {
|
|
|
|
|
if (equipment.status_records && equipment.status_records.length > 0) {
|
|
|
|
|
equipment.status_records.forEach(record => {
|
|
|
|
|
// 检查完成度是否符合筛选条件
|
|
|
|
|
if (shouldShowAxle(record.degree_of_completion)) {
|
|
|
|
|
rows.push({
|
|
|
|
|
...record,
|
|
|
|
|
equipment_code: equipment.equipment_code
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return rows;
|
|
|
|
|
// 按照设备编号和轴号排序
|
|
|
|
|
return rows.sort((a, b) => {
|
|
|
|
|
// 先按设备编号排序
|
|
|
|
|
const equipmentCompare = a.equipment_code.localeCompare(b.equipment_code);
|
|
|
|
|
if (equipmentCompare !== 0) {
|
|
|
|
|
return equipmentCompare;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果设备编号相同,则按轴号排序
|
|
|
|
|
return sortByAxleNumber(a.axle_number, b.axle_number, a.equipment_code);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 按轴号排序的函数
|
|
|
|
|
const sortByAxleNumber = (axleA, axleB, equipmentCode) => {
|
|
|
|
|
// 获取设备对应的预期轴号列表
|
|
|
|
|
const validAxles = equipmentAxlesMap[equipmentCode] || [];
|
|
|
|
|
|
|
|
|
|
// 获取两个轴号在有效轴号列表中的索引
|
|
|
|
|
const getIndexInValidAxles = (axleNumber) => {
|
|
|
|
|
// 处理复合轴号(如"左1,左2"),取第一个轴号的索引
|
|
|
|
|
const firstAxle = axleNumber ? axleNumber.split(',')[0] : '';
|
|
|
|
|
return validAxles.indexOf(firstAxle);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const aIndex = getIndexInValidAxles(axleA);
|
|
|
|
|
const bIndex = getIndexInValidAxles(axleB);
|
|
|
|
|
|
|
|
|
|
// 如果两个轴号都在有效轴号列表中,按索引排序
|
|
|
|
|
if (aIndex !== -1 && bIndex !== -1) {
|
|
|
|
|
return aIndex - bIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果只有一个在有效轴号列表中,有效轴号排在前
|
|
|
|
|
if (aIndex !== -1) return -1;
|
|
|
|
|
if (bIndex !== -1) return 1;
|
|
|
|
|
|
|
|
|
|
// 如果都不在有效轴号列表中,按字符串排序
|
|
|
|
|
return (axleA || '').localeCompare(axleB || '');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 方法:获取数据
|
|
|
|
|
const fetchData = async () => {
|
|
|
|
|
loading.value = true;
|
|
|
|
|
@ -170,6 +317,16 @@ const refreshData = () => {
|
|
|
|
|
fetchData();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 方法:处理机台筛选变化
|
|
|
|
|
const onEquipmentChange = () => {
|
|
|
|
|
console.log('选择的机台:', selectedEquipment.value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 方法:处理完成度筛选变化
|
|
|
|
|
const onCompletionLevelChange = () => {
|
|
|
|
|
console.log('选择的完成度:', selectedCompletionLevel.value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 方法:格式化日期时间
|
|
|
|
|
const formatDateTime = (dateTimeStr) => {
|
|
|
|
|
if (!dateTimeStr) return '';
|
|
|
|
|
@ -237,6 +394,27 @@ onMounted(() => {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 筛选器行样式 */
|
|
|
|
|
.filters-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 筛选器样式 */
|
|
|
|
|
.filter-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-label {
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-header h3 {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|