更新角色管理相关内容
This commit is contained in:
@@ -77,6 +77,68 @@
|
||||
placeholder="补充说明(可选)"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider>提醒设置</el-divider>
|
||||
|
||||
<el-form-item label="开启提醒">
|
||||
<el-switch v-model="form.reminder_enabled" @change="onReminderToggle" />
|
||||
<span class="form-tip">开启后将在「提醒工具」生成一条提醒任务,到点时按渠道通知你</span>
|
||||
</el-form-item>
|
||||
|
||||
<template v-if="form.reminder_enabled">
|
||||
<el-form-item label="提醒时间" prop="reminder_time">
|
||||
<el-date-picker
|
||||
v-model="form.reminder_time"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择提醒时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span class="form-tip"
|
||||
>默认取日程发生时间,可修改;提醒将在"提前提醒分钟"之前开始送达</span
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item label="提醒渠道" prop="remind_channels">
|
||||
<el-checkbox-group v-model="form.remind_channels">
|
||||
<el-checkbox value="SMS">短信</el-checkbox>
|
||||
<el-checkbox value="EMAIL">邮件</el-checkbox>
|
||||
<el-checkbox value="BARK">Bark</el-checkbox>
|
||||
<el-checkbox value="SITE_MSG">站内信</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="提前提醒(分钟)" prop="advance_minutes">
|
||||
<el-input-number
|
||||
v-model="form.advance_minutes"
|
||||
:min="0"
|
||||
:max="1440"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-alert
|
||||
v-if="missingChannels.length"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="reminder-alert"
|
||||
>
|
||||
<template #title>
|
||||
未配置「{{ missingChannels.join("、") }}」的接收方式
|
||||
</template>
|
||||
<div class="alert-body">
|
||||
<span>请先在通知设置中配置对应账号,否则该渠道提醒无法送达。</span>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
@click="saveDraftAndGotoNotify"
|
||||
>去设置并暂存当前日程</el-button
|
||||
>
|
||||
</div>
|
||||
</el-alert>
|
||||
</template>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
@@ -89,8 +151,11 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { createSchedule, updateSchedule } from "@/api/oaSchedule";
|
||||
import { getNotifyConfig } from "@/api/notifyConfig";
|
||||
import { getReminderDetail } from "@/api/reminder";
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@@ -106,10 +171,17 @@ const props = defineProps({
|
||||
defaultDate: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
// 从通知设置页返回时恢复的草稿(含提醒设置)
|
||||
draft: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "saved"]);
|
||||
const emit = defineEmits(["update:modelValue", "saved", "draft-applied"]);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
@@ -137,9 +209,18 @@ const form = reactive({
|
||||
end_time: "",
|
||||
priority: 0,
|
||||
color: colorOptions[0],
|
||||
content: ""
|
||||
content: "",
|
||||
// 提醒绑定
|
||||
reminder_enabled: false,
|
||||
reminder_time: "",
|
||||
remind_channels: [],
|
||||
advance_minutes: 0
|
||||
});
|
||||
|
||||
// 用户通知配置:用于判断所选渠道是否已配置接收账号
|
||||
const notifyConfig = ref({});
|
||||
const notifyLoading = ref(false);
|
||||
|
||||
const rules = {
|
||||
title: [{ required: true, message: "请输入日程标题", trigger: "blur" }],
|
||||
schedule_date: [
|
||||
@@ -149,7 +230,7 @@ const rules = {
|
||||
|
||||
const isEdit = computed(() => !!props.schedule);
|
||||
|
||||
// 打开抽屉时根据编辑对象/默认日期重建表单。
|
||||
// 打开抽屉时根据编辑对象/默认日期/草稿重建表单。
|
||||
// 用 watch 替代 el-drawer 的 @open + destroy-on-close:
|
||||
// open 事件早于抽屉内容挂载,时序不稳定会导致表单控件状态错乱、点击无效。
|
||||
watch(
|
||||
@@ -161,7 +242,112 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
function resetReminderForm() {
|
||||
form.reminder_enabled = false;
|
||||
form.reminder_time = "";
|
||||
form.remind_channels = [];
|
||||
form.advance_minutes = 0;
|
||||
}
|
||||
|
||||
// 由日程日期/时间推算默认提醒时间:全天取 09:00,按时段取开始时间。
|
||||
function defaultReminderTime() {
|
||||
if (!form.schedule_date) {
|
||||
return "";
|
||||
}
|
||||
if (form.all_day) {
|
||||
return `${form.schedule_date} 09:00:00`;
|
||||
}
|
||||
const t = form.start_time || "09:00";
|
||||
return `${form.schedule_date} ${t}:00`;
|
||||
}
|
||||
|
||||
// 日程时间变化时,若提醒已开启且用户未手动填写提醒时间,则同步默认值
|
||||
watch(
|
||||
() => [form.schedule_date, form.all_day, form.start_time],
|
||||
() => {
|
||||
if (form.reminder_enabled && !form.reminder_time) {
|
||||
form.reminder_time = defaultReminderTime();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function onReminderToggle(val) {
|
||||
if (val && !form.reminder_time) {
|
||||
form.reminder_time = defaultReminderTime();
|
||||
}
|
||||
}
|
||||
|
||||
async function loadNotifyConfig() {
|
||||
notifyLoading.value = true;
|
||||
try {
|
||||
const res = await getNotifyConfig();
|
||||
if (res?.code === 200) {
|
||||
notifyConfig.value = res.data || {};
|
||||
}
|
||||
} catch {
|
||||
notifyConfig.value = {};
|
||||
} finally {
|
||||
notifyLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 当前选中渠道中,缺少对应接收账号配置的渠道
|
||||
const missingChannels = computed(() => {
|
||||
if (!form.reminder_enabled) {
|
||||
return [];
|
||||
}
|
||||
const cfg = notifyConfig.value || {};
|
||||
const need = [];
|
||||
for (const ch of form.remind_channels) {
|
||||
if (ch === "EMAIL" && !cfg.email) {
|
||||
need.push("邮件");
|
||||
} else if (ch === "SMS" && !cfg.phone) {
|
||||
need.push("短信");
|
||||
} else if (ch === "BARK" && !cfg.bark_device_key) {
|
||||
need.push("Bark");
|
||||
}
|
||||
// SITE_MSG(站内信)无需额外配置
|
||||
}
|
||||
return need;
|
||||
});
|
||||
|
||||
// 暂存当前填写内容并跳转到通知设置页
|
||||
function saveDraftAndGotoNotify() {
|
||||
const draft = { ...form, schedule_id: undefined };
|
||||
sessionStorage.setItem("oa_schedule_draft", JSON.stringify(draft));
|
||||
ElMessage.info("已暂存当前日程,去设置通知后返回即可继续");
|
||||
router.push("/user/notifyConfig");
|
||||
}
|
||||
|
||||
// 编辑已绑定提醒的日程时,回填提醒设置
|
||||
async function loadReminderForEdit(reminderId) {
|
||||
try {
|
||||
const res = await getReminderDetail(reminderId);
|
||||
if (res?.code === 200 && res.data) {
|
||||
const d = res.data;
|
||||
form.reminder_time = d.schedule_time || defaultReminderTime();
|
||||
form.remind_channels = d.remind_channels || [];
|
||||
form.advance_minutes = d.advance_minutes ?? 0;
|
||||
}
|
||||
} catch {
|
||||
// 读取失败时不阻断编辑,退化为基础默认值
|
||||
form.reminder_time = defaultReminderTime();
|
||||
}
|
||||
}
|
||||
|
||||
function initForm() {
|
||||
// 优先应用从通知设置页返回的草稿
|
||||
if (props.draft) {
|
||||
editingId.value = 0;
|
||||
Object.assign(form, props.draft);
|
||||
if (!form.reminder_time) {
|
||||
form.reminder_time = defaultReminderTime();
|
||||
}
|
||||
emit("draft-applied");
|
||||
loadNotifyConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.schedule) {
|
||||
editingId.value = props.schedule.id;
|
||||
form.title = props.schedule.title;
|
||||
@@ -172,6 +358,13 @@ function initForm() {
|
||||
form.priority = props.schedule.priority || 0;
|
||||
form.color = props.schedule.color || colorOptions[0];
|
||||
form.content = props.schedule.content || "";
|
||||
// 回显已绑定的提醒任务
|
||||
if (props.schedule.reminder_id > 0) {
|
||||
form.reminder_enabled = true;
|
||||
loadReminderForEdit(props.schedule.reminder_id);
|
||||
} else {
|
||||
resetReminderForm();
|
||||
}
|
||||
} else {
|
||||
editingId.value = 0;
|
||||
form.title = "";
|
||||
@@ -182,7 +375,9 @@ function initForm() {
|
||||
form.priority = 0;
|
||||
form.color = colorOptions[0];
|
||||
form.content = "";
|
||||
resetReminderForm();
|
||||
}
|
||||
loadNotifyConfig();
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
@@ -202,6 +397,22 @@ async function handleSave() {
|
||||
}
|
||||
}
|
||||
|
||||
// 开启提醒但所选渠道缺少接收配置:阻断保存,引导先去通知设置
|
||||
if (form.reminder_enabled && missingChannels.value.length) {
|
||||
ElMessage.warning(
|
||||
`请先配置${missingChannels.value.join("、")}的接收方式,或取消该渠道`
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (form.reminder_enabled && !form.reminder_time) {
|
||||
ElMessage.warning("请选择提醒时间");
|
||||
return;
|
||||
}
|
||||
if (form.reminder_enabled && form.remind_channels.length === 0) {
|
||||
ElMessage.warning("请至少选择一个提醒渠道");
|
||||
return;
|
||||
}
|
||||
|
||||
saving.value = true;
|
||||
try {
|
||||
const payload = {
|
||||
@@ -212,7 +423,13 @@ async function handleSave() {
|
||||
end_time: form.all_day ? "" : form.end_time || "",
|
||||
all_day: form.all_day ? 1 : 0,
|
||||
color: form.color,
|
||||
priority: form.priority
|
||||
priority: form.priority,
|
||||
reminder_enabled: !!form.reminder_enabled,
|
||||
reminder_time: form.reminder_enabled ? form.reminder_time : "",
|
||||
remind_channels: form.reminder_enabled ? form.remind_channels : [],
|
||||
advance_minutes: form.reminder_enabled
|
||||
? Number(form.advance_minutes || 0)
|
||||
: 0
|
||||
};
|
||||
const res =
|
||||
isEdit.value
|
||||
@@ -231,7 +448,7 @@ async function handleSave() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="less" scoped>
|
||||
.time-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -272,4 +489,38 @@ async function handleSave() {
|
||||
border-color: #fff;
|
||||
outline: 2px solid #409eff;
|
||||
}
|
||||
|
||||
.form-tip {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.5;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.reminder-alert {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.reminder-alert .alert-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.reminder-alert .alert-body span {
|
||||
font-size: 13px;
|
||||
}
|
||||
// ===== 暗色主题适配 =====
|
||||
html.dark & {
|
||||
.time-sep {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.color-dot.active {
|
||||
border-color: var(--el-bg-color);
|
||||
outline-color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user