fix: 任务表单补页面加载与提交防抖
This commit is contained in:
+114
-76
@@ -40,7 +40,11 @@ const applicationLoading = ref(false);
|
||||
const appUrlTitles = ref<Record<number, string>>({});
|
||||
const applicationDialogVisible = ref(false);
|
||||
const applicationSaving = ref(false);
|
||||
const deletingApplicationId = ref<number | null>(null);
|
||||
const editingApplicationId = ref<number | null>(null);
|
||||
const pageLoading = ref(false);
|
||||
const submitting = ref(false);
|
||||
const previewLoading = ref(false);
|
||||
const applicationForm = ref<{
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -135,13 +139,19 @@ const editApplication = (item: TaskApplication) => {
|
||||
};
|
||||
|
||||
const removeApplication = async (item: TaskApplication) => {
|
||||
await deleteTaskApplication(item.id);
|
||||
ElMessage.success("应用场景已删除");
|
||||
if (editingApplicationId.value === item.id) {
|
||||
resetApplicationForm();
|
||||
}
|
||||
if (taskNum.value) {
|
||||
await loadApplications(taskNum.value);
|
||||
if (deletingApplicationId.value !== null) return;
|
||||
deletingApplicationId.value = item.id;
|
||||
try {
|
||||
await deleteTaskApplication(item.id);
|
||||
ElMessage.success("应用场景已删除");
|
||||
if (editingApplicationId.value === item.id) {
|
||||
resetApplicationForm();
|
||||
}
|
||||
if (taskNum.value) {
|
||||
await loadApplications(taskNum.value);
|
||||
}
|
||||
} finally {
|
||||
deletingApplicationId.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -168,71 +178,80 @@ const convertMaterialUrls = async () => {
|
||||
materialUrl.value = result;
|
||||
};
|
||||
|
||||
const createTask = () => {
|
||||
convertMaterialUrls().then(() => {
|
||||
request
|
||||
.post("/tasks", {
|
||||
const createTask = async () => {
|
||||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
try {
|
||||
await convertMaterialUrls();
|
||||
const result = await request.post("/tasks", {
|
||||
taskName: taskName.value,
|
||||
taskDescription: taskDescription.value,
|
||||
materialUrl: materialUrl.value,
|
||||
...priority.value,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.code === 200) {
|
||||
ElMessage.success("创建任务成功");
|
||||
router.push({ name: "study" });
|
||||
} else {
|
||||
ElMessage.error("任务创建失败:" + result.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const loadTask = () => {
|
||||
if (taskId !== null) {
|
||||
request.get(`/tasks/${taskId}`, {}).then((result) => {
|
||||
if (result.code === 200) {
|
||||
const data = result.data;
|
||||
taskNum.value = data.taskNum || "";
|
||||
taskName.value = data.taskName;
|
||||
taskDescription.value = data.taskDescription;
|
||||
materialUrl.value = data.materialUrl || "";
|
||||
priority.value = {
|
||||
urgency: data.urgency,
|
||||
importance: data.importance,
|
||||
contentDifficulty: data.contentDifficulty,
|
||||
futureValue: data.futureValue,
|
||||
subjectivePriority: data.subjectivePriority,
|
||||
};
|
||||
if (taskNum.value) {
|
||||
loadApplications(taskNum.value);
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(`任务加载失败:${result.message}`);
|
||||
}
|
||||
});
|
||||
if (result.code === 200) {
|
||||
ElMessage.success("创建任务成功");
|
||||
await router.push({ name: "study" });
|
||||
} else {
|
||||
ElMessage.error("任务创建失败:" + result.message);
|
||||
}
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const updateTask = () => {
|
||||
convertMaterialUrls().then(() => {
|
||||
request
|
||||
.put("/tasks/" + taskId, {
|
||||
const loadTask = async () => {
|
||||
if (taskId === null) return;
|
||||
pageLoading.value = true;
|
||||
try {
|
||||
const result = await request.get(`/tasks/${taskId}`, {});
|
||||
if (result.code === 200) {
|
||||
const data = result.data;
|
||||
taskNum.value = data.taskNum || "";
|
||||
taskName.value = data.taskName;
|
||||
taskDescription.value = data.taskDescription;
|
||||
materialUrl.value = data.materialUrl || "";
|
||||
priority.value = {
|
||||
urgency: data.urgency,
|
||||
importance: data.importance,
|
||||
contentDifficulty: data.contentDifficulty,
|
||||
futureValue: data.futureValue,
|
||||
subjectivePriority: data.subjectivePriority,
|
||||
};
|
||||
if (taskNum.value) {
|
||||
loadApplications(taskNum.value);
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(`任务加载失败:${result.message}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error?.message || "任务加载失败,请重试");
|
||||
} finally {
|
||||
pageLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const updateTask = async () => {
|
||||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
try {
|
||||
await convertMaterialUrls();
|
||||
const result = await request.put("/tasks/" + taskId, {
|
||||
id: taskId,
|
||||
taskName: taskName.value,
|
||||
taskDescription: taskDescription.value,
|
||||
materialUrl: materialUrl.value,
|
||||
...priority.value,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.code === 200) {
|
||||
ElMessage.success("更新任务成功");
|
||||
router.push({ name: "study" });
|
||||
} else {
|
||||
ElMessage.error("任务更新失败:" + result.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (result.code === 200) {
|
||||
ElMessage.success("更新任务成功");
|
||||
await router.push({ name: "study" });
|
||||
} else {
|
||||
ElMessage.error("任务更新失败:" + result.message);
|
||||
}
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const cancelTask = () => {
|
||||
@@ -240,13 +259,14 @@ const cancelTask = () => {
|
||||
router.push({ name: "study" });
|
||||
};
|
||||
|
||||
const submitTask = () => {
|
||||
const submitTask = async () => {
|
||||
if (submitting.value) return;
|
||||
switch (route.name) {
|
||||
case "add-task":
|
||||
createTask();
|
||||
await createTask();
|
||||
break;
|
||||
case "update-task":
|
||||
updateTask();
|
||||
await updateTask();
|
||||
break;
|
||||
default:
|
||||
ElMessage.error("该功能暂不可用,请刷新后重试");
|
||||
@@ -275,18 +295,28 @@ const showPreview = ref(false);
|
||||
const materialPreview = ref("");
|
||||
|
||||
async function previewMaterial() {
|
||||
showPreview.value = true;
|
||||
const raw = materialUrl.value || "";
|
||||
if (!raw.trim()) { materialPreview.value = ""; return; }
|
||||
const titles: Record<string, string> = {};
|
||||
const bareUrls = new Set<string>();
|
||||
raw.replace(/https?:\/\/[^\s)\u3001\uFF09\u300D\u300B<>]+/g, (url) => {
|
||||
bareUrls.add(url.replace(/[.。,,;;!!??)】」』\]]+$/, ""));
|
||||
return url;
|
||||
});
|
||||
const results = await Promise.all([...bareUrls].map(async (u) => ({ u, t: await getUrlTitle(u) })));
|
||||
results.forEach(({ u, t }) => { titles[u] = t; });
|
||||
materialPreview.value = renderMarkdown(raw, titles);
|
||||
if (previewLoading.value) return;
|
||||
previewLoading.value = true;
|
||||
try {
|
||||
const raw = materialUrl.value || "";
|
||||
if (!raw.trim()) {
|
||||
materialPreview.value = "";
|
||||
showPreview.value = true;
|
||||
return;
|
||||
}
|
||||
const titles: Record<string, string> = {};
|
||||
const bareUrls = new Set<string>();
|
||||
raw.replace(/https?:\/\/[^\s)\u3001\uFF09\u300D\u300B<>]+/g, (url) => {
|
||||
bareUrls.add(url.replace(/[.。,,;;!!??)】」』\]]+$/, ""));
|
||||
return url;
|
||||
});
|
||||
const results = await Promise.all([...bareUrls].map(async (u) => ({ u, t: await getUrlTitle(u) })));
|
||||
results.forEach(({ u, t }) => { titles[u] = t; });
|
||||
materialPreview.value = renderMarkdown(raw, titles);
|
||||
showPreview.value = true;
|
||||
} finally {
|
||||
previewLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@@ -306,7 +336,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="task-form-page">
|
||||
<section class="task-form-page" v-loading="pageLoading">
|
||||
<el-form label-position="top" class="surface-card form-shell">
|
||||
<div class="group">
|
||||
<h3>基础信息</h3>
|
||||
@@ -325,6 +355,7 @@ defineExpose({
|
||||
text
|
||||
size="small"
|
||||
type="primary"
|
||||
:loading="previewLoading"
|
||||
@click="previewMaterial()"
|
||||
>预览</el-button>
|
||||
<el-button
|
||||
@@ -402,7 +433,14 @@ defineExpose({
|
||||
</el-link>
|
||||
<div class="application-actions">
|
||||
<el-button text type="primary" size="small" @click="editApplication(item)">编辑</el-button>
|
||||
<el-button text type="danger" size="small" @click="removeApplication(item)">删除</el-button>
|
||||
<el-button
|
||||
text
|
||||
type="danger"
|
||||
size="small"
|
||||
:loading="deletingApplicationId === item.id"
|
||||
:disabled="deletingApplicationId !== null"
|
||||
@click="removeApplication(item)"
|
||||
>删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -435,7 +473,7 @@ defineExpose({
|
||||
</el-dialog>
|
||||
|
||||
<div class="action-row">
|
||||
<el-button type="success" size="large" @click="submitTask">{{ buttonName }}</el-button>
|
||||
<el-button type="success" size="large" :loading="submitting" @click="submitTask">{{ buttonName }}</el-button>
|
||||
<el-button size="large" @click="cancelTask">取消</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
Reference in New Issue
Block a user