cola-web/src/views/Inspection/index.vue

561 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="inspection-container">
<div class="header">
<div class="header_left">
<!-- 日期输入框 -->
<IxDateInput label="日期" name="date" :value="currentDate" class="input-spacing" @dateChange="handleDateChange">
</IxDateInput>
<!-- 班次选择框 -->
<IxSelect Outline id="triggerId" v-model="shift" label="班次" hideListHeader="true" class="input-spacing" @valueChange="handleShiftChange">
<IxSelectItem icon="sun" label="白班" value="0"></IxSelectItem>
<IxSelectItem icon="moon" label="晚班" value="1"></IxSelectItem>
</IxSelect>
<!-- 状态选择框 -->
<IxSelect Outline id="statusSelect" v-model="status" label="状态" hideListHeader="true" class="input-spacing">
<IxSelectItem icon="sun" label="全部" value="0"></IxSelectItem>
<IxSelectItem icon="sun" label="正常" value="1"></IxSelectItem>
<IxSelectItem label="报警" value="2"></IxSelectItem>
</IxSelect>
<!-- 查询按钮 -->
<IxButton @click="handleSearch" class="input-spacing btn-style"> 查询 </IxButton>
<!-- 导出按钮 -->
<IxButton class="input-spacing btn-style" @click="handleExport"> 导出全部 </IxButton>
</div>
<div class="header_right">
<!-- 设备列表按钮 -->
<span v-for="(item, index) in deviceList" :key="item.id">
<IxButton :outline="selectedDeviceId !== item.id" class="btn-style" @click="handleDeviceListChange(item.id)">
{{ item.name }}
</IxButton>
</span>
</div>
</div>
<div class="inspection-table">
<div class="table-container">
<!-- 表头部分 -->
<div class="table-row fixed-row">
<span class="fixed-width title-width"></span>
<span class="fixed-width"></span>
<span class="fixed-width"></span>
<span class="fixed-width"></span>
<span class="fixed-width" v-for="(hour, index) in hours" :key="hour">
<IxButton :disabled="confirmedHours.includes(hour)" class="custom-button" @click="handleInspection(hour, index)">
{{ confirmedHours.includes(hour) ? confirmedTimes[hour] : '确认' }}
</IxButton>
</span>
</div>
<div class="table-row-1 fixed-row">
<span class="header-row title-width">点检项目</span>
<span class="header-row">单位</span>
<span class="header-row">参考值</span>
<span class="header-row">当前值</span>
<span class="header-row" v-for="hour in hours" :key="hour"
:style="{ backgroundColor: getDeviceNameById(selectedDeviceId) === '灌注机' ? '#00FFB9' : '#00E4FF', color: '#000028' }">
{{ hour }}
</span>
</div>
<!-- 点检项目列表 -->
<IxEventList>
<IxEventListItem v-for="(item, index) in inspectionItems" :key="index" color="color-success" class="testbg">
<div class="table-row">
<span class="fixed-width title-width">{{ item.label }}</span>
<span class="fixed-width">{{ item.unit || '--' }}</span>
<span class="fixed-width">{{ item.reference || '--' }}</span>
<span class="fixed-width">{{ item.current }}</span> <!-- 确保这里绑定的是 item.current -->
<span class="fixed-width" v-for="hour in hours" :key="hour"
:class="{ 'highlight-cell': item.data[hour] < 0.5 }"
@click="item.data[hour] < 0.5 ? handleInspection(hour, index) : null">
{{ item.data[hour] || '--' }}
</span>
</div>
</IxEventListItem>
</IxEventList>
</div>
</div>
<!-- 点检表单 -->
<InspectionForm v-if="showForm" :itemName="selectedItemName" :itemTime="selectedItemTime" :timezone="timezone" @close="showForm = false" @submit="handleFormSubmit" />
</div>
</template>
<script setup>
// 引入必要的库和组件
import moment from 'moment';
import momentTimezone from 'moment-timezone';
import { ref, computed, getCurrentInstance, onMounted, defineEmits, onUnmounted } from 'vue';
import { IxDatePicker, IxButton, IxDropdownItem, IxEventList, IxEventListItem, IxSelect, IxSelectItem, IxDateInput } from '@siemens/ix-vue';
import InspectionForm from './InspectionForm.vue';
import { getInspectionCurrent, getInspectionData, getCheckParas, getDeviceList, exportExcel } from '@/api/inspection';
const emit = defineEmits(['send-data']);
// 设置为您期望的时区,比如 "Asia/Shanghai"
const timezone = 'Asia/Shanghai';
// 全局响应式变量
const globalTime = ref(moment().tz(timezone).format('YYYY-MM-DD HH:mm'));
const isAutoUpdate = ref(true); // 是否自动更新
const sendDataToParent = () => {
emit('send-data', 'SIEMENS MIS 1.0 无菌产线点检界面', 'other-app');
};
// 获取当前时间的小时数
const currentHour = new Date().getHours();
// 根据当前时间确定默认班次
const defaultShift = currentHour >= 7 && currentHour < 19 ? '0' : '1'; // 早班为0晚班为1
// 定义响应式变量
const shift = ref(defaultShift); // 设置默认班次
const status = ref('0'); // 确保 status 变量已定义
// 设备列表
const deviceList = ref([]);
const selectedDeviceId = ref(null);
const showForm = ref(false);
const selectedItemName = ref('');
const selectedItemTime = ref('');
const selectedItemIndex = ref(null); // 添加索引变量
const selectedDate = ref(null);
const formatDate = (date) => {
const d = new Date(date);
const year = d.getFullYear();
const month = (d.getMonth() + 1).toString().padStart(2, '0');
const day = d.getDate().toString().padStart(2, '0');
return `${year}/${month}/${day}`;
};
const currentDate = formatDate(new Date());
// 计算当前班次的时间段
const hours = computed(() => {
const shiftValue = shift.value;
const hours = [];
if (shiftValue === '0') {
for (let i = 7; i <= 18; i++) {
hours.push(`${i < 10 ? '0' : ''}${i}:00`); // 白班 07:00-18:00
}
} else {
for (let i = 19; i <= 23; i++) {
hours.push(`${i}:00`); // 晚班 19:00-23:00
}
for (let i = 0; i <= 6; i++) {
hours.push(`${i < 10 ? '0' : ''}${i}:00`); // 晚班 00:00-06:00
}
}
return hours;
});
// JSON 数据
const data = ref({});
const inspectionItems = ref([]);
const confirmedHours = ref([]);
const confirmedTimes = ref({});
// 点检按钮点击事件
const handleInspection = (hour, index) => {
selectedItemName.value = inspectionItems.value[index].label;
selectedItemTime.value = hour;
showForm.value = true;
};
// 点检表单提交事件
const handleFormSubmit = (currentTime) => {
confirmedHours.value.push(selectedItemTime.value);
console.log("🚀 ~ handleFormSubmit ~ confirmedHours.value:", confirmedHours.value)
confirmedTimes.value[selectedItemTime.value] = currentTime;
showForm.value = false;
};
const { proxy } = getCurrentInstance();
const showInfoMessage = (message) => {
proxy.$message.info(message);
};
const showInfoMessageWithAction = (message, action) => {
proxy.$message.$confirm(message, action);
};
const showDangerMessage = (message) => {
proxy.$message.danger(message);
};
const showWarningMessage = (message) => {
proxy.$message.warning(message);
};
const showConfirmMessage = (message, onConfirm, onCancel) => {
proxy.$message.confirm(message, onConfirm, onCancel);
};
const toLowerCaseFirstLetter = (str) => {
if (!str) return str;
return str.charAt(0).toLowerCase() + str.slice(1);
}
// 日期变化处理函数
const handleDateChange = (event) => {
selectedDate.value = event.target.value;
};
// 班次变化处理函数
const handleShiftChange = (event) => {
shift.value = event.detail;
fetchInspectionData();
fetchCurrentValues();
};
// 切换设备
const handleDeviceListChange = (id) => {
selectedDeviceId.value = id;
fetchInspectionData();
fetchCurrentValues();
};
// 获取设备列表
const fetchDeviceList = async () => {
try {
const response = await getDeviceList();
if (response.code === 200) {
deviceList.value = response.data;
selectedDeviceId.value = deviceList.value[2].id; // 默认选中第一个设备
} else {
showWarningMessage('获取设备列表失败!');
}
} catch (error) {
console.error('Error fetching device list:', error);
}
};
// 获取当前值、参考值、单位等信息
const fetchCurrentValues = async () => {
try {
const deviceId = selectedDeviceId.value; // 根据实际情况设置设备ID
const dateValue = selectedDate.value || currentDate;
const response = await getInspectionCurrent(deviceId, dateValue);
const params = await getCheckParas(deviceId, dateValue);
if (response.data) {
const currentValues = response.data.data;
inspectionItems.value.forEach(item => {
item.current = currentValues[item.name] || '--';
});
} else {
showWarningMessage('获取当前设备当前值失败!');
}
if (params.data) {
const paramData = params.data;
inspectionItems.value.forEach(item => {
const param = paramData.find(param => {
return toLowerCaseFirstLetter(param.keyname) === item.name;
});
if (param) {
item.label = param.projectDescription;
item.reference = param.referenceValue;
item.unit = param.unit;
}
});
} else {
showWarningMessage('获取设备具体信息失败!');
}
} catch (error) {
console.error('Error fetching current values:', error);
}
};
// 获取点检数据
const fetchInspectionData = async () => {
try {
const deviceId = selectedDeviceId.value; // 根据实际情况设置设备ID
// const inputTime = new Date().toISOString(); // globalTime; // 获取当前时间
const shiftValue = shift.value;
const statusValue = status.value;
const dateValue = selectedDate.value || currentDate;
const response = await getInspectionData(deviceId, dateValue, shiftValue);
if (response.data) {
const inspectionData = response.data;
const itemsMap = {};
inspectionData.forEach(record => {
const recordTime = record.recordTime;
const data = record.data;
for (const [name, value] of Object.entries(data)) {
if (value === -1) continue; // 过滤掉值为 -1 的属性
if (!itemsMap[name]) {
itemsMap[name] = {
name,
label: name, // 可以根据需要调整label的值
reference: 0,
current: 0,
unit: '', // 添加单位字段
data: {}
};
}
itemsMap[name].data[recordTime] = value;
}
});
inspectionItems.value = Object.values(itemsMap);
} else {
showWarningMessage('获取点检数据失败!');
}
} catch (error) {
console.error('Error fetching inspection data:', error);
}
};
// 查询接口数据
const handleSearch = () => {
fetchInspectionData();
fetchCurrentValues();
};
const handleExport = () => {
showInfoMessage('导出全部');
exportExcel(selectedDeviceId.value, selectedDate.value || currentDate, shift.value)
.then((response) => {
if (response) {
// 有数据的处理
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'inspection_data.xlsx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
showInfoMessage('导出成功');
} else {
// 没有数据的处理
showWarningMessage('没有可导出的数据');
}
})
.catch((error) => {
console.error('导出 Excel 失败:', error);
showDangerMessage('导出 Excel 失败,请稍后重试');
});
};
// 通过设备ID获取设备名称
const getDeviceNameById = (id) => {
const device = deviceList.value.find(device => device.id === id);
return device ? device.name : '';
};
let autoUpdateInterval = null;
onMounted(async () => {
await fetchDeviceList();
fetchCurrentValues();
fetchInspectionData();
sendDataToParent();
const setupAutoUpdate = () => {
if (isAutoUpdate.value) {
autoUpdateInterval = setInterval(() => {
fetchCurrentValues();
fetchInspectionData();
}, 60000); // 每分钟刷新一次接口
} else if (autoUpdateInterval) {
clearInterval(autoUpdateInterval);
autoUpdateInterval = null;
}
};
setupAutoUpdate();
// 监听 update-history 事件
// window.addEventListener('update-history', (event) => {
// isAutoUpdate.value = false;
// selectedDate.value = event.detail;
// fetchCurrentValues();
// fetchInspectionData();
// setupAutoUpdate();
// });
// 监听 reset 事件
// window.addEventListener('reset', (event) => {
// isAutoUpdate.value = true;
// selectedDate.value = moment().tz(timezone).format('YYYY-MM-DD HH:mm');
// fetchCurrentValues();
// fetchInspectionData();
// setupAutoUpdate();
// });
});
// 在 onUnmounted 中添加
// onUnmounted(() => {
// window.removeEventListener('update-history', handleHistoryUpdate);
// window.removeEventListener('reset', handleReset);
// });
onUnmounted(() => {
if (autoUpdateInterval) {
clearInterval(autoUpdateInterval);
}
});
</script>
<style scoped>
/* 样式定义 */
.inspection-container {
width: calc(100% + 1.5rem);
margin: 0 -1.5rem 0 0 !important;
height: 100vh;
/* 修改为100vh使其高度铺满整个视口 */
background-color: #000028;
color: white;
font-size: 1.2rem;
/* 调大全局字体大小 */
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
height: 10%;
}
.header_left {
display: flex;
align-items: center;
width: 70%;
/* 设置宽度,确保三个搜索框都能正常显示 */
font-size: 1rem;
/* 调大左侧头部字体大小 */
}
.header_right {
display: flex;
align-items: center;
gap: 10px;
/* 添加间距 */
font-size: 1rem;
/* 调大右侧头部字体大小 */
}
.inspection-table {
width: 100%;
height: 90%;
/* 修改为90%,使其高度铺满剩余部分 */
overflow-x: auto;
/* 添加水平滚动条 */
}
.table-container {
display: flex;
flex-direction: column;
min-width: 100%;
/* 确保表格宽度至少为容器宽度 */
overflow-x: auto;
/* 添加水平滚动条 */
}
.table-row {
display: flex;
justify-content: space-between;
/* padding: 10px;
border-bottom: 1px solid #ccc; */
flex: 1;
/* 使每一行铺满 */
}
.table-row-1 {
height: 100%;
display: flex;
justify-content: space-around;
align-items: center;
flex: 1;
padding: 0 0 0 0.5rem;
}
.fixed-width {
width: 6.5rem;
/* 设置固定宽度 */
height: 2.5rem;
text-align: center;
/* 居中对齐 */
font-size: 1rem;
/* 调大固定宽度元素字体大小 */
display: flex;
align-items: center;
justify-content: center;
}
.header-row {
display: flex;
width: 6.5rem;
height: 2.5rem;
background-color: #23233C;
justify-content: center;
align-items: center;
font-size: 1rem;
margin: 0 0 0.5rem 0;
}
.title-width {
width: 15rem;
}
.btn-style {
margin: 1.8rem 0.5rem 0 0;
}
.testbg {
/* 这里是因为它tm组件里的还用的好像是webcomponent但是tmd不对外提供修改的东西好在有个css颜色变量可以修改 */
--theme-event-item--background: #23233C;
/* --theme-event-item--background--hover: blue; */
}
.testbg1 {
--theme-event-item--background: #000028;
}
/**如果要改按钮的颜色,那么上面就不要用 :style 改成用 :class 来设置这个总没问题吧然后再f12看按钮有哪些颜色变量 */
/* 定义按钮颜色的 CSS 类 */
.custom-button {
--theme-btn-primary--background: #FFA849;
--theme-btn-primary--background--hover: #FFA849;
}
.drop-down {
width: calc(25% - 1.25rem);
background-color: #23233C;
}
:deep(ix-date-input) {
--theme-menu--background: #23233C;
padding-left: 1rem;
}
.search-label {
margin-right: 10px;
margin-left: 20px;
color: white;
font-size: 1rem;
}
.input-spacing {
margin-right: 1rem;
--theme-color-2: #23233C;
}
.fixed-row {
position: sticky;
top: 0;
background-color: inherit;
z-index: 1;
}
.highlight-cell {
background-color: orange;
cursor: pointer;
}
</style>