增加日程提醒
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<el-drawer v-model="visible" :title="isEdit ? '编辑日程' : '新建日程'" size="460px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||||
<el-form-item label="日程标题" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
placeholder="请输入日程标题"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日程日期" prop="schedule_date">
|
||||
<el-date-picker
|
||||
v-model="form.schedule_date"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="全天">
|
||||
<el-switch
|
||||
v-model="form.all_day"
|
||||
active-text="全天"
|
||||
inactive-text="按时段"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!form.all_day" label="时间段">
|
||||
<div class="time-range">
|
||||
<el-time-select
|
||||
v-model="form.start_time"
|
||||
start="00:00"
|
||||
step="00:15"
|
||||
end="23:45"
|
||||
placeholder="开始时间"
|
||||
class="time-input"
|
||||
/>
|
||||
<span class="time-sep">至</span>
|
||||
<el-time-select
|
||||
v-model="form.end_time"
|
||||
start="00:00"
|
||||
step="00:15"
|
||||
end="23:45"
|
||||
placeholder="结束(可选)"
|
||||
class="time-input"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="优先级">
|
||||
<el-radio-group v-model="form.priority">
|
||||
<el-radio-button :value="0">普通</el-radio-button>
|
||||
<el-radio-button :value="1">重要</el-radio-button>
|
||||
<el-radio-button :value="2">紧急</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签颜色">
|
||||
<div class="color-options">
|
||||
<span
|
||||
v-for="c in colorOptions"
|
||||
:key="c"
|
||||
class="color-dot"
|
||||
:class="{ active: form.color === c }"
|
||||
:style="{ background: c }"
|
||||
@click="form.color = c"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.content"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
maxlength="2000"
|
||||
show-word-limit
|
||||
placeholder="补充说明(可选)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="handleSave"
|
||||
>保存</el-button
|
||||
>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { createSchedule, updateSchedule } from "@/api/oaSchedule";
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 编辑时传入的日程对象;null 表示新建
|
||||
schedule: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
// 新建时预填的日期(YYYY-MM-DD)
|
||||
defaultDate: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "saved"]);
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: value => emit("update:modelValue", value)
|
||||
});
|
||||
|
||||
const colorOptions = [
|
||||
"#409EFF",
|
||||
"#0AD18E",
|
||||
"#F5A623",
|
||||
"#F56C6C",
|
||||
"#9B6DF3",
|
||||
"#909399"
|
||||
];
|
||||
|
||||
const formRef = ref(null);
|
||||
const saving = ref(false);
|
||||
const editingId = ref(0);
|
||||
|
||||
const form = reactive({
|
||||
title: "",
|
||||
schedule_date: "",
|
||||
all_day: true,
|
||||
start_time: "",
|
||||
end_time: "",
|
||||
priority: 0,
|
||||
color: colorOptions[0],
|
||||
content: ""
|
||||
});
|
||||
|
||||
const rules = {
|
||||
title: [{ required: true, message: "请输入日程标题", trigger: "blur" }],
|
||||
schedule_date: [
|
||||
{ required: true, message: "请选择日程日期", trigger: "change" }
|
||||
]
|
||||
};
|
||||
|
||||
const isEdit = computed(() => !!props.schedule);
|
||||
|
||||
// 打开抽屉时根据编辑对象/默认日期重建表单。
|
||||
// 用 watch 替代 el-drawer 的 @open + destroy-on-close:
|
||||
// open 事件早于抽屉内容挂载,时序不稳定会导致表单控件状态错乱、点击无效。
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
open => {
|
||||
if (open) {
|
||||
initForm();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function initForm() {
|
||||
if (props.schedule) {
|
||||
editingId.value = props.schedule.id;
|
||||
form.title = props.schedule.title;
|
||||
form.schedule_date = props.schedule.schedule_date;
|
||||
form.all_day = props.schedule.all_day === 1;
|
||||
form.start_time = props.schedule.start_time || "";
|
||||
form.end_time = props.schedule.end_time || "";
|
||||
form.priority = props.schedule.priority || 0;
|
||||
form.color = props.schedule.color || colorOptions[0];
|
||||
form.content = props.schedule.content || "";
|
||||
} else {
|
||||
editingId.value = 0;
|
||||
form.title = "";
|
||||
form.schedule_date = props.defaultDate || "";
|
||||
form.all_day = true;
|
||||
form.start_time = "";
|
||||
form.end_time = "";
|
||||
form.priority = 0;
|
||||
form.color = colorOptions[0];
|
||||
form.content = "";
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
try {
|
||||
await formRef.value.validate();
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (!form.all_day) {
|
||||
if (!form.start_time) {
|
||||
ElMessage.warning("请选择开始时间");
|
||||
return;
|
||||
}
|
||||
if (form.end_time && form.end_time < form.start_time) {
|
||||
ElMessage.warning("结束时间不能早于开始时间");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saving.value = true;
|
||||
try {
|
||||
const payload = {
|
||||
title: form.title.trim(),
|
||||
content: form.content,
|
||||
schedule_date: form.schedule_date,
|
||||
start_time: form.all_day ? "" : form.start_time,
|
||||
end_time: form.all_day ? "" : form.end_time || "",
|
||||
all_day: form.all_day ? 1 : 0,
|
||||
color: form.color,
|
||||
priority: form.priority
|
||||
};
|
||||
const res =
|
||||
isEdit.value
|
||||
? await updateSchedule(editingId.value, payload)
|
||||
: await createSchedule(payload);
|
||||
if (res?.code === 200) {
|
||||
ElMessage.success(isEdit.value ? "日程已更新" : "日程已创建");
|
||||
emit("saved");
|
||||
visible.value = false;
|
||||
} else {
|
||||
ElMessage.error(res?.msg || "保存失败");
|
||||
}
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.time-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.time-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.time-sep {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.color-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.color-dot {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
|
||||
.color-dot:hover {
|
||||
transform: scale(1.12);
|
||||
}
|
||||
|
||||
.color-dot.active {
|
||||
border-color: #fff;
|
||||
outline: 2px solid #409eff;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user