diff --git a/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue b/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue index 7c412ba64..6885fe0cf 100644 --- a/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue +++ b/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue @@ -32,6 +32,9 @@ const emit = defineEmits<{ // 当前编辑的时间段 const currentRange = ref<[Dayjs, Dayjs] | null>(null); +// 正在编辑的时间段索引 +const editingIndex = ref(null); + // 内部工作时间段列表 const periods = computed({ get: () => props.modelValue || [], @@ -73,7 +76,7 @@ const templates = [ }, ]; -// 添加时间段 +// 添加或更新时间段 function addPeriod() { if (!currentRange.value) { message.warning('请先选择时间段'); @@ -92,37 +95,85 @@ function addPeriod() { return; } - // 校验:时间段不能重叠 - const hasOverlap = periods.value.some((p) => { - return !(newPeriod.end <= p.start || newPeriod.start >= p.end); - }); + // 如果是编辑模式 + if (editingIndex.value !== null) { + // 校验:时间段不能与其他时间段重叠(排除自己) + const hasOverlap = periods.value.some((p, i) => { + if (i === editingIndex.value) return false; + return !(newPeriod.end <= p.start || newPeriod.start >= p.end); + }); - if (hasOverlap) { - message.error('时间段不能重叠'); - return; + if (hasOverlap) { + message.error('时间段不能重叠'); + return; + } + + // 更新现有时间段 + const newPeriods = [...periods.value]; + newPeriods[editingIndex.value] = newPeriod; + periods.value = newPeriods.sort((a, b) => a.start.localeCompare(b.start)); + message.success('时间段已更新'); + editingIndex.value = null; + } else { + // 校验:时间段不能重叠 + const hasOverlap = periods.value.some((p) => { + return !(newPeriod.end <= p.start || newPeriod.start >= p.end); + }); + + if (hasOverlap) { + message.error('时间段不能重叠'); + return; + } + + // 添加新时间段 + periods.value = [...periods.value, newPeriod].sort((a, b) => + a.start.localeCompare(b.start), + ); + message.success('时间段已添加'); } - periods.value = [...periods.value, newPeriod].sort((a, b) => - a.start.localeCompare(b.start), - ); currentRange.value = null; - message.success('时间段已添加'); +} + +// 编辑时间段 +function editPeriod(index: number) { + const period = periods.value[index]; + currentRange.value = [ + dayjs(period.start, 'HH:mm'), + dayjs(period.end, 'HH:mm'), + ]; + editingIndex.value = index; +} + +// 取消编辑 +function cancelEdit() { + currentRange.value = null; + editingIndex.value = null; } // 删除时间段 function removePeriod(index: number) { periods.value = periods.value.filter((_, i) => i !== index); + // 如果删除的是正在编辑的时间段,取消编辑状态 + if (editingIndex.value === index) { + cancelEdit(); + } else if (editingIndex.value !== null && editingIndex.value > index) { + // 如果删除的时间段在编辑时间段之前,需要调整编辑索引 + editingIndex.value--; + } } // 使用模板 function useTemplate(template: (typeof templates)[0]) { periods.value = template.periods; + cancelEdit(); // 取消编辑状态 message.success(`已应用模板:${template.label}`); } // 清空所有时间段 function clearAll() { periods.value = []; + cancelEdit(); // 取消编辑状态 } // 时间段描述文本 @@ -182,14 +233,17 @@ function getDuration(period: WorkingHourPeriod): string { v-model:value="currentRange" format="HH:mm" :minute-step="30" - placeholder="选择开始和结束时间" + placeholder="["开始时间", "结束时间"]" style="flex: 1" /> + @@ -207,6 +261,7 @@ function getDuration(period: WorkingHourPeriod): string { v-for="(period, index) in periods" :key="index" class="period-card" + :class="{ editing: editingIndex === index }" size="small" >
@@ -219,14 +274,23 @@ function getDuration(period: WorkingHourPeriod): string { {{ getDuration(period) }}
- + + + + @@ -247,6 +311,7 @@ function getDuration(period: WorkingHourPeriod): string {
💡 使用说明