fix: 修复甘特图以及自动刷新bug

This commit is contained in:
Zhao Zhao Shen 2025-03-02 19:27:19 +08:00
parent fd2c2f303d
commit 77f356b4f1
3 changed files with 69 additions and 103 deletions

View File

@ -43,6 +43,10 @@ const props = defineProps({
currentRange: { currentRange: {
type: String, type: String,
default: 'all' default: 'all'
},
endTime: {
type: String,
default: null
} }
}) })
@ -74,11 +78,12 @@ const initChart = () => {
} }
// //
const getShiftStartTime = (now) => { const getShiftStartTime = (endTime) => {
const now = endTime ? new Date(endTime) : new Date();
const hour = now.getHours(); const hour = now.getHours();
if (hour >= 7 && hour < 19) { if (hour >= 7 && hour < 19) {
// 8:00 - 20:00 // 8:00 - 20:00
return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 7, 0, 0).getTime(); return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 7, 0, 0).getTime();
} else { } else {
// 19:00 - 7:00 // 19:00 - 7:00
if (hour >= 20) { if (hour >= 20) {
@ -93,32 +98,34 @@ const getShiftStartTime = (now) => {
const updateChart = () => { const updateChart = () => {
const now = new Date(); const now = new Date();
let startTime; let startTime;
let endTime = props.endTime ? new Date(props.endTime).getTime() : now.getTime();
switch (currentRange.value) { switch (currentRange.value) {
case '1h': case '1h':
startTime = now.getTime() - 60 * 60 * 1000; startTime = endTime - 60 * 60 * 1000;
break; break;
case '2h': case '2h':
startTime = now.getTime() - 2 * 60 * 60 * 1000; startTime = endTime - 2 * 60 * 60 * 1000;
break; break;
case 'shift': case 'shift':
// startTime = getShiftStartTime(endTime);
startTime = getShiftStartTime(now);//now.getTime() - 12 * 60 * 60 * 1000;
break; break;
case 'all': case 'all':
default: default:
startTime = props.processData.length > 0 ? new Date(props.processData[0].beginTime).getTime() : now.getTime(); startTime = props.processData.length > 0 ? new Date(props.processData[0].beginTime).getTime() : now.getTime();
break; break;
} }
const filteredData = props.processData.filter(item => { const filteredData = props.processData.filter(item => {
const itemStartTime = new Date(item.beginTime).getTime(); const itemStartTime = new Date(item.beginTime).getTime();
const itemEndTime = new Date(item.endTime).getTime(); const itemEndTime = new Date(item.endTime).getTime();
return itemStartTime >= startTime || itemEndTime >= startTime; return itemStartTime >= startTime || itemEndTime >= startTime;
}); });
mappedData.value = mapDataToTimeline(filteredData, startTime);
mappedData.value = mapDataToTimeline(filteredData, startTime, endTime);
nextTick(() => { nextTick(() => {
generateXTicks(); generateXTicks(startTime, endTime);
generateGaps(); generateGaps(startTime, endTime);
}); });
} }
@ -131,12 +138,11 @@ const formatTime = (timeString) => {
} }
// //
const mapDataToTimeline = (data = props.processData, startTime) => { const mapDataToTimeline = (data, startTime, endTime) => {
return data.map(item => { return data.map(item => {
const beginTime = new Date(item.beginTime); const beginTime = new Date(item.beginTime);
const endTime = new Date(item.endTime);
const adjustedBeginTime = beginTime.getTime() < startTime ? new Date(startTime) : beginTime; const adjustedBeginTime = beginTime.getTime() < startTime ? new Date(startTime) : beginTime;
const adjustedDuration = endTime - adjustedBeginTime; const adjustedDuration = endTime - adjustedBeginTime.getTime();
return { return {
id: item.id, id: item.id,
stopReason: item.stopReason, stopReason: item.stopReason,
@ -218,21 +224,20 @@ const handleChartClick = (data) => {
// //
const getBarStyle = (item) => { const getBarStyle = (item) => {
const startTime = new Date(item.beginTime).getTime() const startTime = new Date(item.beginTime).getTime();
const endTime = new Date(item.endTime).getTime() const endTime = new Date(item.endTime).getTime();
const totalDuration = endTime - startTime const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0;
const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0
let chartStartTime; let chartStartTime;
switch (currentRange.value) { switch (currentRange.value) {
case '1h': case '1h':
chartStartTime = new Date().getTime() - 60 * 60 * 1000; chartStartTime = endTime - 60 * 60 * 1000;
break; break;
case '2h': case '2h':
chartStartTime = new Date().getTime() - 2 * 60 * 60 * 1000; chartStartTime = endTime - 2 * 60 * 60 * 1000;
break; break;
case 'shift': case 'shift':
chartStartTime = getShiftStartTime(new Date());//new Date().getTime() - 12 * 60 * 60 * 1000; chartStartTime = getShiftStartTime(endTime);
break; break;
case 'all': case 'all':
default: default:
@ -240,36 +245,34 @@ const getBarStyle = (item) => {
break; break;
} }
const chartEndTime = new Date().getTime(); // 使 const totalChartDuration = endTime - chartStartTime;
const totalChartDuration = chartEndTime - chartStartTime
const adjustedStartTime = startTime < chartStartTime ? chartStartTime : startTime; const adjustedStartTime = startTime < chartStartTime ? chartStartTime : startTime;
const adjustedDuration = endTime - adjustedStartTime; const adjustedDuration = endTime - adjustedStartTime;
const barWidth = (adjustedDuration / totalChartDuration) * containerWidth const barWidth = (adjustedDuration / totalChartDuration) * containerWidth;
const leftPosition = ((adjustedStartTime - chartStartTime) / totalChartDuration) * containerWidth const leftPosition = ((adjustedStartTime - chartStartTime) / totalChartDuration) * containerWidth;
return { return {
width: `${barWidth / 16}rem`, // px rem width: `${barWidth / 16}rem`, // px rem
backgroundColor: item.itemStyle.color, backgroundColor: item.itemStyle.color,
left: `calc(${leftPosition / 16}rem + 1rem)` // px rem 1rem gap left: `calc(${leftPosition / 16}rem + 1rem)` // px rem 1rem gap
} };
} }
// //
const getGapStyle = (gap) => { const getGapStyle = (gap) => {
const startTime = new Date(gap.startTime).getTime() const startTime = new Date(gap.startTime).getTime()
const endTime = new Date(gap.endTime).getTime() const endTime = new Date(gap.endTime).getTime()
const totalDuration = endTime - startTime
const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0 const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0
let chartStartTime; let chartStartTime;
switch (currentRange.value) { switch (currentRange.value) {
case '1h': case '1h':
chartStartTime = new Date().getTime() - 60 * 60 * 1000; chartStartTime = props.processData.length > 0 ? new Date(props.processData[0].beginTime).getTime() - 60 * 60 * 1000 : now.getTime() - 60 * 60 * 1000;
break; break;
case '2h': case '2h':
chartStartTime = new Date().getTime() - 2 * 60 * 60 * 1000; chartStartTime = props.processData.length > 0 ? new Date(props.processData[0].beginTime).getTime() - 2* 60 * 60 * 1000 : now.getTime() - 2 * 60 * 60 * 1000;
break; break;
case 'shift': case 'shift':
chartStartTime = getShiftStartTime(new Date());//new Date().getTime() - 12 * 60 * 60 * 1000; chartStartTime = getShiftStartTime(props.endTime);//new Date().getTime() - 12 * 60 * 60 * 1000;
break; break;
case 'all': case 'all':
default: default:
@ -277,7 +280,7 @@ const getGapStyle = (gap) => {
break; break;
} }
const chartEndTime = new Date().getTime(); // 使 const chartEndTime = props.endTime ? new Date(props.endTime).getTime() : new Date().getTime(); // 使
const totalChartDuration = chartEndTime - chartStartTime const totalChartDuration = chartEndTime - chartStartTime
const adjustedStartTime = startTime < chartStartTime ? chartStartTime : startTime; const adjustedStartTime = startTime < chartStartTime ? chartStartTime : startTime;
const adjustedDuration = endTime - adjustedStartTime; const adjustedDuration = endTime - adjustedStartTime;
@ -292,36 +295,8 @@ const getGapStyle = (gap) => {
} }
// X // X
const generateXTicks = () => { const generateXTicks = (startTime, endTime) => {
const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0 const containerWidth = ganttChart.value ? ganttChart.value.clientWidth : 0;
let startTime, endTime;
const now = new Date();
if (props.processData.length > 0) {
startTime = new Date(props.processData[0].beginTime).getTime();
} else {
startTime = now.getTime();
}
switch (currentRange.value) {
case '1h':
startTime = now.getTime() - 60 * 60 * 1000;
endTime = now.getTime();
break;
case '2h':
startTime = now.getTime() - 2 * 60 * 60 * 1000;
endTime = now.getTime();
break;
case 'shift':
startTime = getShiftStartTime(now);// now.getTime() - 12 * 60 * 60 * 1000;
endTime = now.getTime();
break;
case 'all':
default:
endTime = now.getTime();
break;
}
const totalDuration = endTime - startTime; const totalDuration = endTime - startTime;
const tickInterval = totalDuration / 10; // 10 const tickInterval = totalDuration / 10; // 10
const ticks = []; const ticks = [];
@ -338,27 +313,8 @@ const generateXTicks = () => {
} }
// //
const generateGaps = () => { const generateGaps = (startTime, endTime) => {
const gapsArray = []; const gapsArray = [];
let startTime;
const now = new Date();
switch (currentRange.value) {
case '1h':
startTime = now.getTime() - 60 * 60 * 1000;
break;
case '2h':
startTime = now.getTime() - 2 * 60 * 60 * 1000;
break;
case 'shift':
startTime = getShiftStartTime(now);//now.getTime() - 12 * 60 * 60 * 1000;
break;
case 'all':
default:
startTime = props.processData.length > 0 ? new Date(props.processData[0].beginTime).getTime() : now.getTime();
break;
}
if (props.processData.length > 0) { if (props.processData.length > 0) {
let previousEndTime = startTime; let previousEndTime = startTime;
for (let i = 0; i < props.processData.length; i++) { for (let i = 0; i < props.processData.length; i++) {
@ -371,11 +327,10 @@ const generateGaps = () => {
} }
previousEndTime = new Date(props.processData[i].endTime).getTime(); previousEndTime = new Date(props.processData[i].endTime).getTime();
} }
const currentTime = new Date().getTime(); if (endTime > previousEndTime) {
if (currentTime > previousEndTime) {
gapsArray.push({ gapsArray.push({
startTime: previousEndTime, startTime: previousEndTime,
endTime: currentTime endTime: endTime
}); });
} }
} }

View File

@ -174,7 +174,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="info-item"> <div class="info-item" style="padding: 1rem 0 0 0;">
<svg width="15" height="15" viewBox="0 0 15 15" class="arrow"> <svg width="15" height="15" viewBox="0 0 15 15" class="arrow">
<polygon points="0,0 15,7.5 0,15" fill="#00FFB9" /> <polygon points="0,0 15,7.5 0,15" fill="#00FFB9" />
</svg> </svg>
@ -220,7 +220,7 @@
</div> </div>
</div> </div>
<div class="block"> <div class="block">
<div class="info-item"> <div class="info-item" style="padding: 0.5rem 0 0 0;">
<svg width="15" height="15" viewBox="0 0 15 15" class="arrow"> <svg width="15" height="15" viewBox="0 0 15 15" class="arrow">
<polygon points="0,0 15,7.5 0,15" fill="#00FFB9" /> <polygon points="0,0 15,7.5 0,15" fill="#00FFB9" />
</svg> </svg>
@ -267,7 +267,7 @@
</div> </div>
</div> </div>
<div class="spacing"></div> <div class="spacing"></div>
<ProcessGanttChart ref="ganttChart" :process-data="formattedProcessData" :current-range="currentRange" <ProcessGanttChart ref="ganttChart" :process-data="formattedProcessData" :current-range="currentRange" :end-time="globalTime"
@segment-click="handleSegmentClick" /> @segment-click="handleSegmentClick" />
</div> </div>
</div> </div>
@ -279,7 +279,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"> {{ 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" @click="handleReasonChange(id, reason)"></IxDropdownItem> <IxDropdownItem v-for="reason in stopReasons" :key="reason" :label="reason" @click="handleReasonChange(id, reason)"></IxDropdownItem>
@ -325,7 +325,7 @@ const juiceTankData = ref({}) // 果汁无菌罐数据
const pulpTankData = ref({}) // const pulpTankData = ref({}) //
const dynamicMixerData = ref({}) // const dynamicMixerData = ref({}) //
const currentTime = ref('') // const currentTime = ref('')
const totalTrafficJuice = ref(0); // const totalTrafficJuice = ref(0); //
const totalTrafficPulp = ref(0); // const totalTrafficPulp = ref(0); //
const progressList = ref([])// const progressList = ref([])//
@ -376,13 +376,13 @@ const mixerStep = ref(''); // 增加 step 字段
const currentRange = ref('all'); // currentRange const currentRange = ref('all'); // currentRange
const ganttChart = ref(null); // ganttChart const ganttChart = ref(null); // ganttChart
const currentTitle = ref('生产进度'); const currentTitle = ref('');
// //
const globalDeviceId = ref(null); const globalDeviceId = ref(null);
const globalTime = ref(moment().tz(timezone).format('YYYY-MM-DD HH:mm')); const globalTime = ref(moment().tz(timezone).format('YYYY-MM-DD HH:mm'));
const isAutoUpdate = ref(true); // const isAutoUpdate = ref(true); //
const deviceType = ref(true); const deviceType = ref(false);
// //
const selectedReason = ref(''); // const selectedReason = ref(''); //
@ -396,7 +396,6 @@ const removeStatus = (id) => {
}; };
const updateCurrentInfo = (segment) => { const updateCurrentInfo = (segment) => {
id.value = segment.id; id.value = segment.id;
currentStatus.value = segment.deviceStatus; currentStatus.value = segment.deviceStatus;
startTimeFormatted.value = formatTime(segment.beginTime); startTimeFormatted.value = formatTime(segment.beginTime);
@ -419,10 +418,6 @@ const changeTimeRange = (range) => {
} }
}; };
const updateTime = () => {
const now = moment();
currentTime.value = now.format('YYYY-MM-DD HH:mm');
}
//#TODO: //#TODO:
// //
const processDataFromAPI = (apiData) => { const processDataFromAPI = (apiData) => {
@ -497,6 +492,7 @@ const updateData = (processedData) => {
// //
if (juiceData.value.deviceId) { if (juiceData.value.deviceId) {
globalDeviceId.value = juiceData.value.deviceId; globalDeviceId.value = juiceData.value.deviceId;
currentTitle.value = juiceData.value.data[0].name;
} }
// //
totalTrafficJuice.value = juiceData.value.totalTraffic; totalTrafficJuice.value = juiceData.value.totalTraffic;
@ -751,8 +747,6 @@ onMounted(async () => {
await fetchData(); await fetchData();
fetchGanttData(); fetchGanttData();
fetchStopReason(); fetchStopReason();
updateTime();
setInterval(updateTime, 1000);
const setupAutoUpdate = () => { const setupAutoUpdate = () => {
if (isAutoUpdate.value) { if (isAutoUpdate.value) {
@ -895,7 +889,7 @@ onUnmounted(() => {
/* 进度条样式 */ /* 进度条样式 */
.progress-bar { .progress-bar {
height: 1rem; height: 1.2rem;
/* 调整高度 */ /* 调整高度 */
background: #000028; background: #000028;
border-radius: 0.5rem; border-radius: 0.5rem;

View File

@ -53,7 +53,8 @@ const appSwitchConfig = {
iconSrc: 'https://www.svgrepo.com/show/530661/genetic-data.svg', iconSrc: 'https://www.svgrepo.com/show/530661/genetic-data.svg',
url: '/#/inspection', url: '/#/inspection',
description: '其他系统描述', description: '其他系统描述',
target: '_blank', target: '_self',
// target: '_blank',
}, },
], ],
}; };
@ -61,6 +62,7 @@ const appSwitchConfig = {
const currentTime = ref(''); const currentTime = ref('');
const showDatetimePicker = ref(false); const showDatetimePicker = ref(false);
const selectedDatetime = ref(''); const selectedDatetime = ref('');
const isAutoUpdate = ref(true);
const updateTime = () => { const updateTime = () => {
const now = new Date(); const now = new Date();
@ -81,6 +83,7 @@ const handleReset = () => {
const event = new CustomEvent('reset'); const event = new CustomEvent('reset');
updateTime(); updateTime();
window.dispatchEvent(event); window.dispatchEvent(event);
isAutoUpdate.value = true; //
}; };
const handleDatetimePickerDone = (event) => { const handleDatetimePickerDone = (event) => {
@ -89,6 +92,7 @@ const handleDatetimePickerDone = (event) => {
// //
console.log('Selected Datetime:', selectedDatetime.value); console.log('Selected Datetime:', selectedDatetime.value);
updateHistory(selectedDatetime.value); updateHistory(selectedDatetime.value);
isAutoUpdate.value = false; //
}; };
const updateHistory = (datetime) => { const updateHistory = (datetime) => {
@ -116,7 +120,10 @@ const updateHistory = (datetime) => {
onMounted(() => { onMounted(() => {
updateTime(); updateTime();
const interval = setInterval(updateTime, 60000); // const interval = setInterval(() => {
if (showDatetimePicker.value || !isAutoUpdate.value) return; //
updateTime();
}, 60000); //
onUnmounted(() => clearInterval(interval)); onUnmounted(() => clearInterval(interval));
}); });
</script> </script>
@ -220,6 +227,7 @@ ix-application {
:deep(ix-datetime-picker){ :deep(ix-datetime-picker){
--theme-menu--background: #23233C; --theme-menu--background: #23233C;
border: 1px solid #fff;
} }
:deep(IxApplication) { :deep(IxApplication) {
@ -242,5 +250,14 @@ ix-application {
:global(.visible) { :global(.visible) {
--theme-modal--background:#23233C !important; --theme-modal--background:#23233C !important;
--theme-color-ghost--selected:#23233C !important;
}
:host .AppEntry.Selected {
border:none !important;
}
:deep(:host .AppEntry.Selected){
border:none !important;
} }
</style> </style>