feat(aiot): 工作时间段增加编辑功能
- 添加时间段编辑功能,点击编辑按钮可修改时间 - 快捷模板生成的时间段现在可以编辑调整 - 编辑模式下显示保存和取消按钮 - 正在编辑的时间段高亮显示 - 改进 TimePicker 提示文本,更清晰易用 - 删除、清空、切换模板时自动取消编辑状态 - 更新使用说明,添加编辑功能提示 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,9 @@ const emit = defineEmits<{
|
||||
// 当前编辑的时间段
|
||||
const currentRange = ref<[Dayjs, Dayjs] | null>(null);
|
||||
|
||||
// 正在编辑的时间段索引
|
||||
const editingIndex = ref<number | null>(null);
|
||||
|
||||
// 内部工作时间段列表
|
||||
const periods = computed<WorkingHourPeriod[]>({
|
||||
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"
|
||||
/>
|
||||
<Button v-if="editingIndex !== null" @click="cancelEdit">
|
||||
取消
|
||||
</Button>
|
||||
<Button type="primary" @click="addPeriod">
|
||||
<template #icon>
|
||||
<span>➕</span>
|
||||
<span>{{ editingIndex !== null ? '💾' : '➕' }}</span>
|
||||
</template>
|
||||
添加
|
||||
{{ editingIndex !== null ? '保存' : '添加' }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<div class="period-content">
|
||||
@@ -219,14 +274,23 @@ function getDuration(period: WorkingHourPeriod): string {
|
||||
{{ getDuration(period) }}
|
||||
</Tag>
|
||||
</div>
|
||||
<Button
|
||||
size="small"
|
||||
type="text"
|
||||
danger
|
||||
@click="removePeriod(index)"
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
<Space>
|
||||
<Button
|
||||
size="small"
|
||||
type="text"
|
||||
@click="editPeriod(index)"
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
type="text"
|
||||
danger
|
||||
@click="removePeriod(index)"
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -247,6 +311,7 @@ function getDuration(period: WorkingHourPeriod): string {
|
||||
<div class="help-title">💡 使用说明</div>
|
||||
<ul class="help-list">
|
||||
<li>工作时间段为空表示24小时监控</li>
|
||||
<li>点击快捷模板后可继续编辑调整时间</li>
|
||||
<li>时间段不能重叠,系统会自动校验</li>
|
||||
<li>支持跨天时间段(如 16:00-08:00)</li>
|
||||
<li>可添加多个不连续的时间段</li>
|
||||
@@ -357,6 +422,12 @@ function getDuration(period: WorkingHourPeriod): string {
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.period-card.editing {
|
||||
border-color: #1890ff;
|
||||
background-color: #e6f4ff;
|
||||
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
.period-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
Reference in New Issue
Block a user