fix: 点检修改

This commit is contained in:
Zhao Zhao Shen 2025-03-04 23:50:11 +08:00
parent 8b9813c901
commit ca99c0ff68
4 changed files with 169 additions and 61 deletions

View File

@ -24,7 +24,7 @@
<div class="block">
<div class="flex-row">
<h2 class="juice-title">果肉调配</h2>
<span class="flow-label">果肉流量{{ totalTrafficPulp }}</span>
<span class="flow-label">累计流量{{ totalTrafficPulp }}</span>
</div>
<div class="spacing"></div>
<div v-for="item in innerProgressList" :key="item.name" class="juice-item"
@ -55,7 +55,7 @@
</div>
<div class="info-row">
<span class="info-label">当前状态</span>
<span class="info-value">{{ processForm_uht.status }}</span>
<span class="info-value">{{ processForm_uht.deviceStatus }}</span>
</div>
<div class="info-row">
<span class="info-label">当前步骤</span>
@ -106,7 +106,7 @@
</div>
<div class="info-row">
<span class="info-label">当前状态</span>
<span class="info-value">{{ processForm_pulp.status }}</span>
<span class="info-value">{{ processForm_pulp.deviceStatus }}</span>
</div>
<div class="info-row">
<span class="info-label">当前步骤</span>
@ -315,8 +315,6 @@ import momentTimezone from 'moment-timezone';
import { ref, onMounted, getCurrentInstance, onUnmounted, defineEmits } from 'vue'
import { IxChip, IxButton, IxDropdown, IxDropdownItem, IxDropdownHeader, IxDivider, IxTabItem, IxTabs } from '@siemens/ix-vue'; // Chip
import { getCurrentReport, getHistoryReport, getGanttData, getStopReason, setStopReason } from '@/api/dashboard.js';
import GradientProgressBar from '@/components/GradientProgressBar.vue'
import ProcessStatusBar from '@/components/ProcessStatusBar.vue'
import ProcessGanttChart from '@/components/ProcessGanttChart.vue'
const emit = defineEmits(['send-data']);
@ -476,6 +474,28 @@ const getStatusColor = (status) => {
const processHistoryDataFromAPI = processDataFromAPI; // processDataFromAPI
const getDataByName = (data, name) => {
const filteredData = data.filter(item => item.name === name);
if (filteredData.length === 0) {
return {
name,
deviceId: null,
totalTraffic: 0,
data: []
};
}
const mergedData = filteredData.map(item => ({
...item.data,
deviceId: item.deviceId // deviceId
}));
return {
name,
deviceId: filteredData[0].deviceId,
totalTraffic: mergedData.reduce((acc, item) => acc + (item.weight || 0), 0),
data: mergedData
};
};
const getUHTDataByName = (data, name) => {
const filteredData = data.filter(item => item.name === name);
if (filteredData.length === 0) {
return {
@ -501,10 +521,10 @@ const updateData = (processedData) => {
juiceData.value = getDataByName(processedData, "果汁调配");
pulpData.value = getDataByName(processedData, "果肉调配");
uhtData.value = getDataByName(processedData, "果汁杀菌");
pulpUHTData.value = getDataByName(processedData, "果肉杀菌");
juiceTankData.value = getDataByName(processedData, "果汁无菌罐");
pulpTankData.value = getDataByName(processedData, "果肉无菌罐");
dynamicMixerData.value = getDataByName(processedData, "动态混合器");
pulpUHTData.value = getUHTDataByName(processedData, "果肉杀菌");
juiceTankData.value = getUHTDataByName(processedData, "果汁无菌罐");
pulpTankData.value = getUHTDataByName(processedData, "果肉无菌罐");
dynamicMixerData.value = getUHTDataByName(processedData, "动态混合器");
//
if (juiceData.value.deviceId) {
@ -512,8 +532,8 @@ const updateData = (processedData) => {
currentTitle.value = juiceData.value.data[0].name;
}
//
totalTrafficJuice.value = juiceData.value.totalTraffic;
totalTrafficPulp.value = pulpData.value.totalTraffic;
totalTrafficJuice.value = juiceData.value.totalTraffic.toFixed(2);
totalTrafficPulp.value = pulpData.value.totalTraffic.toFixed(2);
if (juiceData.value.data.length > 0) {
progressList.value = juiceData.value.data.map(item => ({
@ -539,7 +559,7 @@ const updateData = (processedData) => {
name: uhtData.value.name,
formula: uhtData.value.data[0].formula,
totalTraffic: uhtData.value.totalTraffic,
status: uhtData.value.data[0].status,
deviceStatus: uhtData.value.data[0].deviceStatus,
productFlowRate: uhtData.value.data[0].productFlowRate,
mixerStep: uhtData.value.data[0].mixerStep,
temperature: uhtData.value.data[0].temperature
@ -550,7 +570,7 @@ const updateData = (processedData) => {
name: pulpUHTData.value.name,
formula: pulpUHTData.value.data[0].formula,
totalTraffic: pulpUHTData.value.totalTraffic,
status: pulpUHTData.value.data[0].status,
deviceStatus: pulpUHTData.value.data[0].deviceStatus,
productFlowRate: pulpUHTData.value.data[0].productFlowRate,
mixerStep: pulpUHTData.value.data[0].mixerStep,
temperature: pulpUHTData.value.data[0].temperature
@ -583,8 +603,7 @@ const updateData = (processedData) => {
productFlowRate: dynamicMixerData.value.data[0].productFlowRate
};
}
if (processedData !== undefined) showInfoMessage("数据刷新成功!");
else showWarningMessage("未查询到历史数据!");
if (processedData === undefined) showWarningMessage("未查询到主数据!");
};
//
@ -639,9 +658,9 @@ const processGanttDataResponse = (response) => {
if (ganttChart.value && ganttChart.value.updateChart) {
ganttChart.value.updateChart();
}
showInfoMessage('' + ganttData.length + ' 条数据已刷新!');
// showInfoMessage('' + ganttData.length + ' ');
} else {
showWarningMessage('未查询到数据!');
showWarningMessage('未查询到甘特图数据!');
processData.value = [];
formattedProcessData.value = [];
if (ganttChart.value && ganttChart.value.updateChart) {

View File

@ -10,27 +10,31 @@
<div class="item-chip-container">
<p>{{ itemName }}</p>
<IxChip class="chip" background="#FF2640" chip-color="#000028" variant="custom">
09:00 超出上下限
{{ itemTime }} 超出上下限
</IxChip>
</div>
<label for="reason">请输入原因</label>
<textarea id="reason" v-model="reason"></textarea>
</div>
<div class="form-footer">
<IxButton type="submit">提交</IxButton>
<!-- <IxButton type="submit">提交</IxButton> -->
<IxButton Outline @click="resetForm">重置</IxButton>
<IxButton Outline @click="$emit('close')">关闭</IxButton>
<IxButton @click="handleSubmit">提交</IxButton>
</div>
</form>
</div>
</template>
<script setup>
import { ref, defineProps } from 'vue';
import { ref, defineProps, defineEmits } from 'vue';
import { IxButton, IxChip } from '@siemens/ix-vue';
import moment from 'moment-timezone';
const props = defineProps({
itemName: String
itemName: String,
itemTime: String,
timezone: String,
});
const reason = ref('');
@ -42,6 +46,13 @@ const submitForm = () => {
const resetForm = () => {
reason.value = '';
};
const emit = defineEmits(['close', 'submit']);
const handleSubmit = () => {
const currentTime = moment().tz(props.timezone).format('HH:mm');
emit('submit', currentTime);
};
</script>
<style scoped>

View File

@ -2,24 +2,32 @@
<div class="inspection-container">
<div class="header">
<div class="header_left">
<IxDateInput label="日期" name="date" helper-text="选择日期" :value="currentDate" class="input-spacing" @dateChange="handleDateChange">
<!-- 日期输入框 -->
<IxDateInput label="日期" name="date" helper-text="选择日期" :value="currentDate" class="input-spacing"
@dateChange="handleDateChange">
</IxDateInput>
<IxSelect Outline id="triggerId" v-model="shift" label="班次" helperText="选择班次" class="input-spacing" @valueChange="handleShiftChange">
<!-- 班次选择框 -->
<IxSelect Outline id="triggerId" v-model="shift" label="班次" helperText="选择班次" 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="状态" Placeholder="状态" helperText="选择状态"
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"> 查询 </IxButton>
<!-- 导出按钮 -->
<IxButton class="input-spacing"> 导出全部 </IxButton>
</div>
<div class="header_right">
<!-- 设备列表按钮 -->
<span v-for="(item, index) in deviceList" :key="item.id">
<IxButton :outline="selectedDeviceId !== item.id" @click="handleDeviceListChange(item.id)">
{{ item.name }}
@ -29,14 +37,16 @@
</div>
<div class="inspection-table">
<div class="table-container">
<!-- 表头部分移到 IxEventList 外面 -->
<!-- 表头部分 -->
<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 class="custom-button" @click="handleInspection(index)"> 确认 </IxButton>
<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">
@ -45,11 +55,11 @@
<span class="header-row">参考值</span>
<span class="header-row">当前值</span>
<span class="header-row" v-for="hour in hours" :key="hour"
:style="{ backgroundColor: '#00FFB9', color: '#000028' }">
:style="{ backgroundColor: getDeviceNameById(selectedDeviceId) === '灌注机' ? '#00FFB9' : '#00E4FF', color: '#000028' }">
{{ hour }}
</span>
</div>
<!-- IxEventList 保持不变 -->
<!-- 点检项目列表 -->
<IxEventList>
<IxEventListItem v-for="(item, index) in inspectionItems" :key="index" color="color-success"
class="testbg">
@ -66,11 +76,13 @@
</IxEventList>
</div>
</div>
<InspectionForm v-if="showForm" :itemName="selectedItemName" @close="showForm = false" />
<!-- 点检表单 -->
<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';
@ -88,7 +100,7 @@ const globalTime = ref(moment().tz(timezone).format('YYYY-MM-DD HH:mm'));
const isAutoUpdate = ref(true); //
const sendDataToParent = () => {
emit('send-data', '点检界面', 'other-app');
emit('send-data', 'SIEMENS MIS 1.0 无菌产线点检界面', 'other-app');
};
//
@ -107,6 +119,9 @@ 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) => {
@ -142,40 +157,59 @@ const hours = computed(() => {
const data = ref({});
const inspectionItems = ref([]);
const confirmedHours = ref([]);
const confirmedTimes = ref({});
//
const handleInspection = (index) => {
selectedItemName.value = inspectionItems.value[index].name;
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 = (index) => {
proxy.$message.info(index + '数据写入成功!');
const showInfoMessage = (message) => {
proxy.$message.info(message);
};
const showDangerMessage = (index) => {
proxy.$message.danger(index + '数据未成功写入!');
const showInfoMessageWithAction = (message, action) => {
proxy.$message.$confirm(message, action);
};
const showWarningMessage = (index) => {
proxy.$message.warning(index + '数据写入异常!');
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);
if (!str) return str;
return str.charAt(0).toLowerCase() + str.slice(1);
}
//
const handleDateChange = (event) => {
selectedDate.value = event.target.value;
console.log("🚀 ~ handleDateChange ~ selectedDate.value:", selectedDate.value)
};
//
const handleShiftChange = (event) => {
shift.value = event.detail;
console.log("🚀 ~ handleShiftChange ~ shift.value:", shift.value)
fetchInspectionData();
fetchCurrentValues();
};
@ -194,6 +228,8 @@ const fetchDeviceList = async () => {
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);
@ -205,33 +241,36 @@ const fetchCurrentValues = async () => {
try {
const deviceId = selectedDeviceId.value; // ID
const dateValue = selectedDate.value || currentDate;
// const inputTime = selectedDate.value; //new Date().toISOString(); //
const response = await getInspectionCurrent(deviceId, dateValue);
const params = await getCheckParas(deviceId, dateValue);
if (response.code === 200) {
if (response.data) {
const currentValues = response.data.data;
inspectionItems.value.forEach(item => {
item.current = currentValues[item.name] || '--';
});
} else {
showWarningMessage('获取当前设备当前值失败!');
}
if (params.code === 200) {
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);
}
@ -246,7 +285,7 @@ const fetchInspectionData = async () => {
const statusValue = status.value;
const dateValue = selectedDate.value || currentDate;
const response = await getInspectionData(deviceId, dateValue, shiftValue);
if (response.code === 200) {
if (response.data) {
const inspectionData = response.data;
const itemsMap = {};
inspectionData.forEach(record => {
@ -268,6 +307,8 @@ const fetchInspectionData = async () => {
}
});
inspectionItems.value = Object.values(itemsMap);
} else {
showWarningMessage('获取点检数据失败!');
}
} catch (error) {
console.error('Error fetching inspection data:', error);
@ -280,6 +321,12 @@ const handleSearch = () => {
fetchCurrentValues();
};
// ID
const getDeviceNameById = (id) => {
const device = deviceList.value.find(device => device.id === id);
return device ? device.name : '';
};
let autoUpdateInterval = null;
onMounted(async () => {
@ -315,8 +362,8 @@ onMounted(async () => {
window.addEventListener('reset', (event) => {
isAutoUpdate.value = true;
selectedDate.value = moment().tz(timezone).format('YYYY-MM-DD HH:mm');
// fetchData();
// fetchGanttData();
fetchCurrentValues();
fetchInspectionData();
setupAutoUpdate();
});
});
@ -329,6 +376,7 @@ onUnmounted(() => {
</script>
<style scoped>
/* 样式定义 */
.inspection-container {
width: calc(100% + 1.5rem);
margin: 0 -1.5rem 0 0 !important;

View File

@ -14,10 +14,11 @@
<router-view @update-history="updateHistory" @reset="reset" @send-data="handleDataFromChild"></router-view>
</IxContent>
<!-- 添加遮罩层和 IxDatetimePicker 组件 -->
<!-- 添加遮罩层和日期选择器组件 -->
<div v-if="showDatetimePicker" class="overlay" @click="closeDatetimePicker"></div>
<div v-if="showDatetimePicker" class="datetime-picker-container">
<IxDatetimePicker range="false" showSeconds="false" show-time-reference="true" @done="handleDatetimePickerDone" />
<IxDatetimePicker v-if="appSwitchConfig.currentAppId === 'mis-app'" range="false" showSeconds="false" show-time-reference="true" @done="handleDatetimePickerDone" />
<IxDatePicker v-else range="false" @dateChange="handleDatePickerDone" style="--theme-menu--background: '#232323'"/>
<button class="close-button" @click="closeDatetimePicker">关闭</button>
</div>
</IxApplication>
@ -33,6 +34,7 @@ import {
IxDropdownItem,
IxIconButton,
IxDatetimePicker,
IxDatePicker,
} from '@siemens/ix-vue';
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { useRoute } from 'vue-router';
@ -93,13 +95,19 @@ const handleReset = () => {
const handleDatetimePickerDone = (event) => {
selectedDatetime.value = event.detail;
showDatetimePicker.value = false;
//
console.log('Selected Datetime:', selectedDatetime.value);
updateHistory(selectedDatetime.value);
updateHistoryWithTime(selectedDatetime.value);
isAutoUpdate.value = false; //
};
const updateHistory = (datetime) => {
const handleDatePickerDone = (event) => {
selectedDatetime.value = event.detail;
showDatetimePicker.value = false;
updateHistoryWithDate(selectedDatetime.value);
isAutoUpdate.value = false; //
};
const updateHistoryWithTime = (datetime) => {
console.log("🚀 ~ updateHistoryWithTime ~ datetime:", datetime)
// datetime YYYY-MM-DD HH:mm:ss
const parsedDate = new Date(datetime.replace(/-/g, '/'));
if (isNaN(parsedDate.getTime())) {
@ -114,7 +122,7 @@ const updateHistory = (datetime) => {
const seconds = String(parsedDate.getSeconds()).padStart(2, '0');
const formattedDatetime = `${year}-${month}-${day} ${hours}:${minutes}`;
// getHistory
console.log("🚀 ~ updateHistory ~ formattedDatetime:", formattedDatetime)
console.log("🚀 ~ updateHistoryWithTime ~ formattedDatetime:", formattedDatetime)
const event = new CustomEvent('update-history', { detail: formattedDatetime });
currentTime.value = formattedDatetime;
@ -122,6 +130,28 @@ const updateHistory = (datetime) => {
window.dispatchEvent(event);
};
const updateHistoryWithDate = (date) => {
console.log("🚀 ~ updateHistoryWithDate ~ date:", date)
// date YYYY-MM-DD
const { from } = date;
const parsedDate = new Date(from);
if (isNaN(parsedDate.getTime())) {
console.error('Invalid date format:', from);
return;
}
const year = parsedDate.getFullYear();
const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
const day = String(parsedDate.getDate()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
// getHistory
console.log("🚀 ~ updateHistoryWithDate ~ formattedDate:", formattedDate)
const event = new CustomEvent('update-history', { detail: formattedDate });
currentTime.value = formattedDate;
window.dispatchEvent(event);
};
const handleDataFromChild = (data, name) => {
appName.value = data;
appSwitchConfig.currentAppId = name;
@ -211,7 +241,7 @@ ix-application {
color: #fff !important;
font-size: 1.2rem !important;
/* 调大应用名称字体大小 */
font-weight: normal !important;
font-weight: normal !重要;
display: flex;
align-items: center;
}
@ -283,6 +313,6 @@ ix-application {
:global(.visible) {
--theme-modal--background:#23233C !important;
/* --theme-color-ghost--selected:#23233C !important; */
/* --theme-color-ghost--selected:#23233C !重要; */
}
</style>