feat: 前端增加提交功能
This commit is contained in:
parent
2aef180ddb
commit
ca0322137b
|
@ -1,6 +1,7 @@
|
||||||
using DotNext;
|
using DotNext;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
|
using Tapper;
|
||||||
|
|
||||||
namespace Database;
|
namespace Database;
|
||||||
|
|
||||||
|
@ -231,6 +232,7 @@ public class Exam
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 资源类型枚举
|
/// 资源类型枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[TranspilationSource]
|
||||||
public static class ResourceTypes
|
public static class ResourceTypes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { templateRef } from "@vueuse/core";
|
||||||
|
import { File, UploadIcon, XIcon } from "lucide-vue-next";
|
||||||
|
import { isNull } from "mathjs";
|
||||||
|
import { useSlots } from "vue";
|
||||||
|
|
||||||
|
const slots = useSlots();
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
autoUpload?: boolean;
|
||||||
|
closeAfterUpload?: boolean;
|
||||||
|
callback: (files: File[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
autoUpload: false,
|
||||||
|
closeAfterUpload: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputFiles = defineModel<File[] | null>("inputFiles", { default: null });
|
||||||
|
const isShowModal = defineModel<boolean>("isShowModal", { default: false });
|
||||||
|
|
||||||
|
const fileInputRef = templateRef("fileInputRef");
|
||||||
|
|
||||||
|
function handleFileChange(event: Event) {
|
||||||
|
const files = (event.target as HTMLInputElement).files;
|
||||||
|
if (!files) return;
|
||||||
|
inputFiles.value = Array.from(files);
|
||||||
|
|
||||||
|
if (props.autoUpload) handleUpload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileDrop(event: DragEvent) {
|
||||||
|
const files = event.dataTransfer?.files;
|
||||||
|
if (!files) return;
|
||||||
|
inputFiles.value = Array.from(files);
|
||||||
|
|
||||||
|
if (props.autoUpload) handleUpload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpload() {
|
||||||
|
if (!inputFiles.value) return;
|
||||||
|
props.callback(inputFiles.value);
|
||||||
|
if (props.closeAfterUpload) close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
isShowModal.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
isShowModal.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
close,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="isShowModal" class="modal modal-open overflow-hidden">
|
||||||
|
<div class="modal-box overflow-hidden flex flex-col gap-3">
|
||||||
|
<div
|
||||||
|
class="flex justify-between items-center pb-3 border-b border-base-300"
|
||||||
|
>
|
||||||
|
<h2 class="text-2xl font-bold text-base-content">文件上传</h2>
|
||||||
|
<button @click="close" class="btn btn-sm btn-circle btn-ghost">
|
||||||
|
<XIcon class="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="border-2 border-dashed border-base-300 rounded-lg text-center cursor-pointer hover:border-primary hover:bg-primary/5 transition-colors aspect-4/2 flex items-center justify-center"
|
||||||
|
@click="fileInputRef.click()"
|
||||||
|
@dragover.prevent
|
||||||
|
@dragenter.prevent
|
||||||
|
@drop.prevent="handleFileDrop"
|
||||||
|
>
|
||||||
|
<div v-if="slots.content">
|
||||||
|
<slot name="content"></slot>
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex flex-col items-center gap-3">
|
||||||
|
<File class="w-12 h-12 text-base-content opacity-40" />
|
||||||
|
<div class="text-sm text-base-content/70 text-center">
|
||||||
|
<div class="font-medium mb-1">点击或拖拽上传</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex flex-col items-center gap-2">
|
||||||
|
<File class="w-8 h-8 text-success" />
|
||||||
|
<div class="text-xs font-medium text-success text-center">
|
||||||
|
{{ inputFiles?.[0]?.name }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-base-content/50">点击重新选择</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
ref="fileInputRef"
|
||||||
|
@change="handleFileChange"
|
||||||
|
accept=""
|
||||||
|
class="hidden"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
v-if="!autoUpload"
|
||||||
|
class="btn btn-primary btn-sm w-full h-10"
|
||||||
|
@click="handleUpload"
|
||||||
|
:disabled="isNull(inputFiles) || inputFiles.length === 0"
|
||||||
|
>
|
||||||
|
<UploadIcon class="w-6 h-6" />
|
||||||
|
上传
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-backdrop" @click="close"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="postcss" scoped></style>
|
|
@ -14,9 +14,8 @@ const router = createRouter({
|
||||||
{ path: "/login", name: "login", component: AuthView },
|
{ path: "/login", name: "login", component: AuthView },
|
||||||
{ path: "/project", name: "project", component: ProjectView },
|
{ path: "/project", name: "project", component: ProjectView },
|
||||||
{ path: "/test", name: "test", component: TestView },
|
{ path: "/test", name: "test", component: TestView },
|
||||||
{ path: "/user/:page?", name: "user", component: UserView },
|
{ path: "/user/:page*", name: "user", component: UserView },
|
||||||
{ path: "/exam/:examId?", name: "exam", component: ExamView },
|
{ path: "/exam/:page*", name: "exam", component: ExamView },
|
||||||
{ path: "/exam", redirect: "/exam/" },
|
|
||||||
{ path: "/markdown", name: "markdown", component: MarkdownEditor },
|
{ path: "/markdown", name: "markdown", component: MarkdownEditor },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,19 +8,7 @@
|
||||||
{{ mode === "create" ? "新建实验" : "编辑实验" }}
|
{{ mode === "create" ? "新建实验" : "编辑实验" }}
|
||||||
</h2>
|
</h2>
|
||||||
<button @click="close" class="btn btn-sm btn-circle btn-ghost">
|
<button @click="close" class="btn btn-sm btn-circle btn-ghost">
|
||||||
<svg
|
<XIcon class="w-6 h-6" />
|
||||||
class="w-6 h-6"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M6 18L18 6M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -417,11 +405,13 @@ import {
|
||||||
BinaryIcon,
|
BinaryIcon,
|
||||||
FileArchiveIcon,
|
FileArchiveIcon,
|
||||||
FileJsonIcon,
|
FileJsonIcon,
|
||||||
|
XIcon,
|
||||||
} from "lucide-vue-next";
|
} from "lucide-vue-next";
|
||||||
import {
|
import {
|
||||||
ExamClient,
|
ExamClient,
|
||||||
ExamDto,
|
ExamDto,
|
||||||
ResourceClient,
|
ResourceClient,
|
||||||
|
ResourcePurpose,
|
||||||
type FileParameter,
|
type FileParameter,
|
||||||
} from "@/APIClient";
|
} from "@/APIClient";
|
||||||
import { useAlertStore } from "@/components/Alert";
|
import { useAlertStore } from "@/components/Alert";
|
||||||
|
@ -685,7 +675,12 @@ async function uploadExamResources(examId: string) {
|
||||||
data: uploadFiles.value.mdFile,
|
data: uploadFiles.value.mdFile,
|
||||||
fileName: uploadFiles.value.mdFile.name,
|
fileName: uploadFiles.value.mdFile.name,
|
||||||
};
|
};
|
||||||
await client.addResource("doc", "template", examId, mdFileParam);
|
await client.addResource(
|
||||||
|
"doc",
|
||||||
|
ResourcePurpose.Template,
|
||||||
|
examId,
|
||||||
|
mdFileParam,
|
||||||
|
);
|
||||||
console.log("MD文档上传成功");
|
console.log("MD文档上传成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +690,12 @@ async function uploadExamResources(examId: string) {
|
||||||
data: imageFile,
|
data: imageFile,
|
||||||
fileName: imageFile.name,
|
fileName: imageFile.name,
|
||||||
};
|
};
|
||||||
await client.addResource("image", "template", examId, imageFileParam);
|
await client.addResource(
|
||||||
|
"image",
|
||||||
|
ResourcePurpose.Template,
|
||||||
|
examId,
|
||||||
|
imageFileParam,
|
||||||
|
);
|
||||||
console.log("图片上传成功:", imageFile.name);
|
console.log("图片上传成功:", imageFile.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +707,7 @@ async function uploadExamResources(examId: string) {
|
||||||
};
|
};
|
||||||
await client.addResource(
|
await client.addResource(
|
||||||
"bitstream",
|
"bitstream",
|
||||||
"template",
|
ResourcePurpose.Template,
|
||||||
examId,
|
examId,
|
||||||
bitstreamFileParam,
|
bitstreamFileParam,
|
||||||
);
|
);
|
||||||
|
@ -720,7 +720,12 @@ async function uploadExamResources(examId: string) {
|
||||||
data: canvasFile,
|
data: canvasFile,
|
||||||
fileName: canvasFile.name,
|
fileName: canvasFile.name,
|
||||||
};
|
};
|
||||||
await client.addResource("canvas", "template", examId, canvasFileParam);
|
await client.addResource(
|
||||||
|
"canvas",
|
||||||
|
ResourcePurpose.Template,
|
||||||
|
examId,
|
||||||
|
canvasFileParam,
|
||||||
|
);
|
||||||
console.log("画布模板上传成功:", canvasFile.name);
|
console.log("画布模板上传成功:", canvasFile.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,7 +737,7 @@ async function uploadExamResources(examId: string) {
|
||||||
};
|
};
|
||||||
await client.addResource(
|
await client.addResource(
|
||||||
"resource",
|
"resource",
|
||||||
"template",
|
ResourcePurpose.Template,
|
||||||
examId,
|
examId,
|
||||||
resourceFileParam,
|
resourceFileParam,
|
||||||
);
|
);
|
||||||
|
@ -775,6 +780,7 @@ defineExpose({
|
||||||
show,
|
show,
|
||||||
close,
|
close,
|
||||||
editExam,
|
editExam,
|
||||||
|
editExamInfo,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -13,19 +13,7 @@
|
||||||
@click="closeExamDetail"
|
@click="closeExamDetail"
|
||||||
class="btn btn-sm btn-circle btn-ghost"
|
class="btn btn-sm btn-circle btn-ghost"
|
||||||
>
|
>
|
||||||
<svg
|
<XIcon class="w-6 h-6" />
|
||||||
class="w-6 h-6"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M6 18L18 6M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -147,17 +135,18 @@
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-base-content/70">当前状态</span>
|
<span class="text-base-content/70">当前状态</span>
|
||||||
<div class="badge badge-error">未完成</div>
|
<div class="badge badge-error">
|
||||||
</div>
|
{{
|
||||||
|
isUndefined(commitsList) || commitsList.length === 0
|
||||||
<div class="flex justify-between items-center">
|
? "未提交"
|
||||||
<span class="text-base-content/70">批阅状态</span>
|
: "已提交"
|
||||||
<div class="badge badge-ghost">待提交</div>
|
}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-base-content/70">成绩</span>
|
<span class="text-base-content/70">成绩</span>
|
||||||
<span class="text-base-content/50">未评分</span>
|
<div class="badge badge-ghost">未评分</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -167,17 +156,22 @@
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<h4 class="font-medium text-base-content">提交历史</h4>
|
<h4 class="font-medium text-base-content">提交历史</h4>
|
||||||
<div
|
<div
|
||||||
v-if="isUndefined(commitsList)"
|
v-if="isUndefined(commitsList) || commitsList.length === 0"
|
||||||
class="text-sm text-base-content/50 text-center py-4"
|
class="text-sm text-base-content/50 text-center py-4"
|
||||||
>
|
>
|
||||||
暂无提交记录
|
暂无提交记录
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="overflow-y-auto">
|
<div v-else class="overflow-y-auto">
|
||||||
<ul class="steps steps-vertical">
|
<ul class="steps steps-vertical">
|
||||||
<li class="step step-primary">Register</li>
|
<li
|
||||||
<li class="step step-primary">Choose plan</li>
|
class="step"
|
||||||
<li class="step">Purchase</li>
|
:class="{ 'step-primary': _idx === 1 }"
|
||||||
<li class="step">Receive Product</li>
|
v-for="(commit, _idx) in commitsList.slice(0, 3)"
|
||||||
|
>
|
||||||
|
{{ commit.id }} ---
|
||||||
|
{{ commit.uploadTime.toDateString() }}
|
||||||
|
</li>
|
||||||
|
<li class="step" v-if="commitsList.length > 3">......</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -187,58 +181,27 @@
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<button @click="startExam" class="btn btn-primary w-full">
|
<button @click="startExam" class="btn btn-primary w-full">
|
||||||
<svg
|
<Smile class="w-5 h-5" />
|
||||||
class="w-5 h-5 mr-2"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
开始实验
|
开始实验
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button @click="uploadModal?.show" class="btn btn-info w-full">
|
||||||
|
<Upload class="w-5 h-5" />
|
||||||
|
提交实验
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@click="downloadResources"
|
@click="downloadResources"
|
||||||
class="btn btn-outline w-full"
|
class="btn btn-outline w-full"
|
||||||
:disabled="downloadingResources"
|
:disabled="downloadingResources"
|
||||||
>
|
>
|
||||||
<svg
|
<Download class="w-5 h-5" />
|
||||||
class="w-5 h-5 mr-2"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<span v-if="downloadingResources">下载中...</span>
|
<span v-if="downloadingResources">下载中...</span>
|
||||||
<span v-else>下载资源包</span>
|
<span v-else>下载资源包</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="btn btn-outline w-full">
|
<button class="btn btn-outline w-full">
|
||||||
<svg
|
<GitGraph class="w-5 h-5" />
|
||||||
class="w-5 h-5 mr-2"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
查看记录
|
查看记录
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -247,6 +210,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-backdrop" @click="closeExamDetail"></div>
|
<div class="modal-backdrop" @click="closeExamDetail"></div>
|
||||||
|
<UploadModal
|
||||||
|
ref="uploadModal"
|
||||||
|
class="fixed z-auto"
|
||||||
|
:auto-upload="true"
|
||||||
|
:callback="submitExam"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -266,10 +235,16 @@ import { formatDate } from "@/utils/Common";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { watch } from "vue";
|
import { watch } from "vue";
|
||||||
import { isNull, isUndefined } from "lodash";
|
import { isNull, isUndefined } from "lodash";
|
||||||
|
import { Download, GitGraph, Smile, Upload, XIcon } from "lucide-vue-next";
|
||||||
|
import UploadModal from "@/components/UploadModal.vue";
|
||||||
|
import { templateRef } from "@vueuse/core";
|
||||||
|
import { toFileParameter } from "@/utils/Common";
|
||||||
|
|
||||||
const alertStore = useRequiredInjection(useAlertStore);
|
const alertStore = useRequiredInjection(useAlertStore);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const uploadModal = templateRef("uploadModal");
|
||||||
|
|
||||||
const show = defineModel<boolean>("show", {
|
const show = defineModel<boolean>("show", {
|
||||||
default: false,
|
default: false,
|
||||||
});
|
});
|
||||||
|
@ -350,6 +325,24 @@ const startExam = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const submitExam = (files: File[]) => {
|
||||||
|
try {
|
||||||
|
const client = AuthManager.createClient(ResourceClient);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
client.addResource(
|
||||||
|
"compression",
|
||||||
|
ResourcePurpose.Homework,
|
||||||
|
props.selectedExam.id,
|
||||||
|
toFileParameter(file),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
alertStore.error(err.message || "上传资料失败");
|
||||||
|
console.error("上传资料失败:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const closeExamDetail = () => {
|
const closeExamDetail = () => {
|
||||||
show.value = false;
|
show.value = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -191,6 +191,7 @@ import { templateRef } from "@vueuse/core";
|
||||||
import { isArray, isNull } from "lodash";
|
import { isArray, isNull } from "lodash";
|
||||||
import { watch } from "vue";
|
import { watch } from "vue";
|
||||||
import { watchEffect } from "vue";
|
import { watchEffect } from "vue";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -218,13 +219,18 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watch(
|
||||||
if (showEditModal.value) {
|
() => showEditModal.value,
|
||||||
router.replace({ path: `/exam/edit` });
|
() => {
|
||||||
} else {
|
if (showEditModal.value) {
|
||||||
router.replace({ path: `/exam` });
|
router.replace({
|
||||||
}
|
path: `/exam/edit/${examEditModalRef.value?.editExamInfo.id}`,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
router.replace({ path: `/exam` });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
async function refreshExams() {
|
async function refreshExams() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
@ -263,7 +269,8 @@ async function handleCardClicked(event: MouseEvent, examId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleEditExamClicked(event: MouseEvent, examId: string) {
|
async function handleEditExamClicked(event: MouseEvent, examId: string) {
|
||||||
examEditModalRef?.value?.editExam(examId);
|
await examEditModalRef?.value?.editExam(examId);
|
||||||
|
router.replace(`/exam/edit/${examId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
|
@ -278,17 +285,28 @@ onMounted(async () => {
|
||||||
await refreshExams();
|
await refreshExams();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function loadBasicPage(page: string) {
|
||||||
|
if (page === "") return;
|
||||||
|
else if (page === "edit") showEditModal.value = true;
|
||||||
|
else if (page) await viewExam(page);
|
||||||
|
else router.push("/exam");
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 处理路由参数,如果有examId则自动打开该实验的详情模态框
|
// 处理路由参数,如果有examId则自动打开该实验的详情模态框
|
||||||
const examId = route.params.examId as string;
|
const page = route.params.page;
|
||||||
if (examId === "") return;
|
|
||||||
|
|
||||||
if (isArray(examId)) return;
|
if (Array.isArray(page)) {
|
||||||
|
if (page.length == 1) await loadBasicPage(page[0]);
|
||||||
if (examId === "edit") showEditModal.value = true;
|
else if (page.length == 2) {
|
||||||
|
if (page[0] === "edit") {
|
||||||
if (examId) {
|
await examEditModalRef.value?.editExam(page[1]);
|
||||||
await viewExam(examId);
|
} else {
|
||||||
|
router.push("/exam");
|
||||||
|
}
|
||||||
|
} else router.push("/exam");
|
||||||
|
} else {
|
||||||
|
await loadBasicPage(page);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue