feat: 点检报警功能

This commit is contained in:
Zhao Zhao Shen 2025-03-09 19:04:07 +08:00
parent 5493068847
commit c6adf30b68
4 changed files with 100 additions and 32 deletions

View File

@ -39,4 +39,22 @@ export function exportExcel(deviceId, inputTime, shift) {
method: 'get', method: 'get',
responseType: 'arraybuffer' // 关键:设置响应类型为 arraybuffer responseType: 'arraybuffer' // 关键:设置响应类型为 arraybuffer
}); });
}
// 报警相关接口
// 时间点确认点检,不传时间,默认当前时间
export function sharpConfirm(alarmId, confirmTime, checkUser) {
return request({
url: `/Check/sharpConfirm?alarmId=${alarmId}&checkUser=${checkUser}`,
method: 'post'
});
}
// 数据项点检
export function alarmReasonConfirm(data) {
return request({
url: '/Check/AlarmReason',
method: 'post',
data
})
} }

View File

@ -294,7 +294,7 @@
<IxButton Outline class="btnStyle"> 流量{{ productFlowRate }} </IxButton> <IxButton Outline class="btnStyle"> 流量{{ productFlowRate }} </IxButton>
<IxButton Outline class="btnStyle"> 配方{{ formula }} </IxButton> <IxButton Outline class="btnStyle"> 配方{{ formula }} </IxButton>
<IxButton Outline class="btnStyle"> 持续时长{{ duration }} </IxButton> <IxButton Outline class="btnStyle"> 持续时长{{ duration }} </IxButton>
<IxButton Outline id="triggerId"> {{ selectedReason ? '停机原因:' + selectedReason : '请选择停机原因 ▲' }} </IxButton> <IxButton Outline id="triggerId" :disabled="currentStatus !== '停机'"> {{ selectedReason ? '停机原因:' + selectedReason : '请选择停机原因 ▲' }} </IxButton>
<IxDropdown trigger="triggerId" class="drop-down"> <IxDropdown trigger="triggerId" class="drop-down">
<IxDropdownHeader label="停机原因"></IxDropdownHeader> <IxDropdownHeader label="停机原因"></IxDropdownHeader>
<IxDropdownItem v-for="reason in stopReasons" :key="reason" :label="reason" <IxDropdownItem v-for="reason in stopReasons" :key="reason" :label="reason"
@ -422,6 +422,7 @@ const updateAlarmCount = () => {
const updateCurrentInfo = (segment) => { const updateCurrentInfo = (segment) => {
id.value = segment.id; id.value = segment.id;
currentStatus.value = segment.deviceStatus; currentStatus.value = segment.deviceStatus;
console.log("🚀 ~ updateCurrentInfo ~ currentStatus:", currentStatus.value); //
startTimeFormatted.value = formatTime(segment.beginTime); startTimeFormatted.value = formatTime(segment.beginTime);
endTimeFormatted.value = formatTime(segment.endTime); endTimeFormatted.value = formatTime(segment.endTime);
duration.value = segment.duration; duration.value = segment.duration;

View File

@ -51,7 +51,7 @@ const emit = defineEmits(['close', 'submit']);
const handleSubmit = () => { const handleSubmit = () => {
const currentTime = moment().tz(props.timezone).format('HH:mm'); const currentTime = moment().tz(props.timezone).format('HH:mm');
emit('submit', currentTime); emit('submit', currentTime, reason.value);
}; };
</script> </script>

View File

@ -41,8 +41,8 @@
<span class="fixed-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"> <span class="fixed-width" v-for="(hour, index) in hours" :key="hour">
<IxButton :disabled="confirmedHours.includes(hour)" class="custom-button" @click="handleInspection(hour, index)"> <IxButton :disabled="confirmedHours.includes(hour) || hourCheckStatus[hour] !== null" class="custom-button" @click="handleInspection(hour, index)">
{{ confirmedHours.includes(hour) ? confirmedTimes[hour] : '确认' }} {{ hourCheckStatus[hour] !== null ? hourCheckTime[hour] : '确认' }}
</IxButton> </IxButton>
</span> </span>
</div> </div>
@ -65,9 +65,12 @@
<span class="fixed-width">{{ item.reference || '--' }}</span> <span class="fixed-width">{{ item.reference || '--' }}</span>
<span class="fixed-width">{{ item.current }}</span> <!-- 确保这里绑定的是 item.current --> <span class="fixed-width">{{ item.current }}</span> <!-- 确保这里绑定的是 item.current -->
<span class="fixed-width" v-for="hour in hours" :key="hour" <span class="fixed-width" v-for="hour in hours" :key="hour"
:class="{ 'highlight-cell': item.data[hour] < 0.5 }" :class="{
@click="item.data[hour] < 0.5 ? handleInspection(hour, index) : null"> 'highlight-cell': item.data[hour]?.checkStatus === 1,
{{ item.data[hour] || '--' }} 'alarm-cell': item.data[hour]?.checkStatus === 0
}"
@click="item.data[hour]?.checkStatus === 0 ? handleAlarmInspection(hour, index) : null">
{{ item.data[hour]?.value || '--' }}
</span> </span>
</div> </div>
</IxEventListItem> </IxEventListItem>
@ -75,7 +78,7 @@
</div> </div>
</div> </div>
<!-- 点检表单 --> <!-- 点检表单 -->
<InspectionForm v-if="showForm" :itemName="selectedItemName" :itemTime="selectedItemTime" :timezone="timezone" @close="showForm = false" @submit="handleFormSubmit" /> <InspectionForm v-if="showForm" :itemName="selectedItemName" :itemTime="selectedItemTime" :timezone="timezone" @close="showForm = false" @submit="(currentTime, reason) => handleFormSubmit(selectedItemIndex, reason)" />
</div> </div>
</template> </template>
@ -86,7 +89,7 @@ import momentTimezone from 'moment-timezone';
import { ref, computed, getCurrentInstance, onMounted, defineEmits, onUnmounted } from 'vue'; import { ref, computed, getCurrentInstance, onMounted, defineEmits, onUnmounted } from 'vue';
import { IxDatePicker, IxButton, IxDropdownItem, IxEventList, IxEventListItem, IxSelect, IxSelectItem, IxDateInput } from '@siemens/ix-vue'; import { IxDatePicker, IxButton, IxDropdownItem, IxEventList, IxEventListItem, IxSelect, IxSelectItem, IxDateInput } from '@siemens/ix-vue';
import InspectionForm from './InspectionForm.vue'; import InspectionForm from './InspectionForm.vue';
import { getInspectionCurrent, getInspectionData, getCheckParas, getDeviceList, exportExcel } from '@/api/inspection'; import { getInspectionCurrent, getInspectionData, getCheckParas, getDeviceList, exportExcel, sharpConfirm, alarmReasonConfirm } from '@/api/inspection';
const emit = defineEmits(['send-data']); const emit = defineEmits(['send-data']);
@ -118,7 +121,7 @@ const selectedDeviceId = ref(null);
const showForm = ref(false); const showForm = ref(false);
const selectedItemName = ref(''); const selectedItemName = ref('');
const selectedItemTime = ref(''); const selectedItemTime = ref('');
const selectedItemIndex = ref(null); // const selectedItemIndex = ref(null);
const selectedDate = ref(null); const selectedDate = ref(null);
@ -158,18 +161,55 @@ const inspectionItems = ref([]);
const confirmedHours = ref([]); const confirmedHours = ref([]);
const confirmedTimes = ref({}); const confirmedTimes = ref({});
// //
const hourCheckStatus = ref({});
const hourCheckTime = ref({});
const alarmId = ref({});
const formatTime = (time) => {
const date = new Date(time);
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
return `${hours}:${minutes}`;
};
// handleAlarmConfirm
const handleInspection = (hour, index) => { const handleInspection = (hour, index) => {
selectedItemName.value = inspectionItems.value[index].label; selectedItemName.value = inspectionItems.value[index].label;
selectedItemTime.value = hour; selectedItemTime.value = hour;
selectedItemIndex.value = index; //
showConfirmMessage('确认要执行点检操作吗?', async () => {
await sharpConfirm(alarmId.value[hour], 'admin').then(() => {
confirmedHours.value.push(selectedItemTime.value);
confirmedTimes.value[selectedItemTime.value] = moment().tz(timezone).format('HH:mm');
hourCheckStatus.value[hour] = 1; //
hourCheckTime.value[hour] = confirmedTimes.value[selectedItemTime.value]; //
});
}, () => {
showWarningMessage('取消点检操作');
});
};
//
const handleAlarmInspection = (hour, index) => {
selectedItemName.value = inspectionItems.value[index].label;
selectedItemTime.value = hour;
selectedItemIndex.value = index; // selectedItemIndex
showForm.value = true; showForm.value = true;
}; };
// //
const handleFormSubmit = (currentTime) => { const handleFormSubmit = async (index, reason) => {
confirmedHours.value.push(selectedItemTime.value); await alarmReasonConfirm({
console.log("🚀 ~ handleFormSubmit ~ confirmedHours.value:", confirmedHours.value) alarmId: alarmId.value[selectedItemTime.value],
confirmedTimes.value[selectedItemTime.value] = currentTime; checkParamId: inspectionItems.value[index].data[selectedItemTime.value].checkParamId,
alarmReason: reason,
checkUser: 'admin'
}).then(() => {
inspectionItems.value[index].data[selectedItemTime.value].checkStatus = 1; //
inspectionItems.value[index].data[selectedItemTime.value].checkUser = 'admin'; //
inspectionItems.value[index].data[selectedItemTime.value].checkText = '点检正常'; //
});
showForm.value = false; showForm.value = false;
}; };
@ -195,11 +235,6 @@ const showConfirmMessage = (message, onConfirm, onCancel) => {
proxy.$message.confirm(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) => { const handleDateChange = (event) => {
selectedDate.value = event.target.value; selectedDate.value = event.target.value;
@ -225,7 +260,7 @@ const fetchDeviceList = async () => {
const response = await getDeviceList(); const response = await getDeviceList();
if (response.code === 200) { if (response.code === 200) {
deviceList.value = response.data; deviceList.value = response.data;
selectedDeviceId.value = deviceList.value[2].id; // selectedDeviceId.value = deviceList.value[0].id; //
} else { } else {
showWarningMessage('获取设备列表失败!'); showWarningMessage('获取设备列表失败!');
} }
@ -256,7 +291,7 @@ const fetchCurrentValues = async () => {
inspectionItems.value.forEach(item => { inspectionItems.value.forEach(item => {
const param = paramData.find(param => { const param = paramData.find(param => {
return toLowerCaseFirstLetter(param.keyname) === item.name; return param.keyname === item.name;
}); });
if (param) { if (param) {
@ -278,9 +313,7 @@ const fetchCurrentValues = async () => {
const fetchInspectionData = async () => { const fetchInspectionData = async () => {
try { try {
const deviceId = selectedDeviceId.value; // ID const deviceId = selectedDeviceId.value; // ID
// const inputTime = new Date().toISOString(); // globalTime; //
const shiftValue = shift.value; const shiftValue = shift.value;
const statusValue = status.value;
const dateValue = selectedDate.value || currentDate; const dateValue = selectedDate.value || currentDate;
const response = await getInspectionData(deviceId, dateValue, shiftValue); const response = await getInspectionData(deviceId, dateValue, shiftValue);
if (response.data) { if (response.data) {
@ -289,8 +322,12 @@ const fetchInspectionData = async () => {
inspectionData.forEach(record => { inspectionData.forEach(record => {
const recordTime = record.recordTime; const recordTime = record.recordTime;
const data = record.data; const data = record.data;
for (const [name, value] of Object.entries(data)) { hourCheckStatus.value[recordTime] = record.hourCheckStatus;
if (value === -1) continue; // -1 hourCheckTime.value[recordTime] = formatTime(record.hourCheckTime);
alarmId.value[recordTime] = record.alarmId;
for (const [name, valueObj] of Object.entries(data)) {
if (valueObj === null || valueObj.valule === null) continue; // null
if (!itemsMap[name]) { if (!itemsMap[name]) {
itemsMap[name] = { itemsMap[name] = {
name, name,
@ -301,7 +338,15 @@ const fetchInspectionData = async () => {
data: {} data: {}
}; };
} }
itemsMap[name].data[recordTime] = value; itemsMap[name].data[recordTime] = {
value: valueObj.valule,
checkStatus: valueObj.checkStatus,
checkText: valueObj.checkText,
checkParamId: valueObj.checkParamId,
checkUser: valueObj.checkUser
// hourCheckStatus: valueObj.hourCheckStatus,
// hourCheckTime: valueObj.hourCheckTime
};
} }
}); });
inspectionItems.value = Object.values(itemsMap); inspectionItems.value = Object.values(itemsMap);
@ -390,11 +435,7 @@ onMounted(async () => {
// setupAutoUpdate(); // setupAutoUpdate();
// }); // });
}); });
// onUnmounted
// onUnmounted(() => {
// window.removeEventListener('update-history', handleHistoryUpdate);
// window.removeEventListener('reset', handleReset);
// });
onUnmounted(() => { onUnmounted(() => {
if (autoUpdateInterval) { if (autoUpdateInterval) {
clearInterval(autoUpdateInterval); clearInterval(autoUpdateInterval);
@ -448,6 +489,10 @@ onUnmounted(() => {
/* 添加水平滚动条 */ /* 添加水平滚动条 */
} }
.table-container {
display: flex;
}
.table-container { .table-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -557,4 +602,8 @@ onUnmounted(() => {
background-color: orange; background-color: orange;
cursor: pointer; cursor: pointer;
} }
.alarm-cell {
background-color: red;
cursor: pointer;
}
</style> </style>