feat: 实现可编辑已有的实验

This commit is contained in:
2025-08-13 16:11:06 +08:00
parent 76342553ad
commit 7a59c29e06
7 changed files with 578 additions and 593 deletions

View File

@@ -62,7 +62,7 @@
<div
v-if="isAdmin"
class="card bg-base-200 shadow-lg hover:shadow-xl transition-all duration-200 cursor-pointer hover:scale-[1.02]"
@click="showCreateModal = true"
@click="() => examEditModalRef?.show()"
>
<div class="card-body flex items-center justify-center text-center">
<div class="text-primary text-6xl mb-4">+</div>
@@ -75,15 +75,26 @@
v-for="exam in exams"
:key="exam.id"
class="card bg-base-200 shadow-lg hover:shadow-xl transition-all duration-200 cursor-pointer hover:scale-[1.02] relative overflow-hidden"
@click="viewExam(exam.id)"
@click="handleCardClicked($event, exam.id)"
>
<div class="card-body">
<div class="flex justify-between items-start mb-4">
<h3 class="card-title text-base-content">{{ exam.name }}</h3>
<span
class="card-title text-sm text-blue-600/50 dark:text-sky-400/50"
>{{ exam.id }}</span
>
<div class="flex flex-row items-center gap-2">
<button
class="btn btn-ghost text-error hover:underline group"
@click="handleEditExamClicked($event, exam.id)"
>
<EditIcon
class="w-4 h-4 transition-transform duration-200 group-hover:scale-110"
/>
编辑
</button>
<span
class="card-title text-sm text-blue-600/50 dark:text-sky-400/50"
>{{ exam.id }}</span
>
</div>
</div>
<!-- 实验标签 -->
@@ -160,8 +171,8 @@
<!-- 创建实验模态框 -->
<ExamEditModal
v-model:show="showCreateModal"
@create-finished="handleCreateExamFinished"
ref="examEditModalRef"
@edit-finished="handleEditExamFinished"
/>
</div>
</template>
@@ -170,36 +181,27 @@
import { ref, onMounted, computed } from "vue";
import { useRoute } from "vue-router";
import { AuthManager } from "@/utils/AuthManager";
import { type ExamSummary, type ExamInfo } from "@/APIClient";
import { type ExamInfo } from "@/APIClient";
import { formatDate } from "@/utils/Common";
import ExamInfoModal from "./ExamInfoModal.vue";
import ExamEditModal from "./ExamEditModal.vue";
import router from "@/router";
import { EditIcon } from "lucide-vue-next";
import { templateRef } from "@vueuse/core";
// 响应式数据
const route = useRoute();
const exams = ref<ExamSummary[]>([]);
const exams = ref<ExamInfo[]>([]);
const selectedExam = ref<ExamInfo | null>(null);
const loading = ref(false);
const error = ref<string>("");
const isAdmin = ref(false);
// Modal
const showCreateModal = ref(false);
const examEditModalRef = templateRef("examEditModalRef");
const showInfoModal = ref(false);
// 方法
const checkAdminStatus = async () => {
console.log("检查管理员权限...");
try {
isAdmin.value = await AuthManager.verifyAdminAuth();
console.log("管理员权限:", isAdmin.value);
} catch (err) {
console.warn("无法验证管理员权限:", err);
isAdmin.value = false;
}
};
const refreshExams = async () => {
async function refreshExams() {
loading.value = true;
error.value = "";
@@ -212,9 +214,9 @@ const refreshExams = async () => {
} finally {
loading.value = false;
}
};
}
const viewExam = async (examId: string) => {
async function viewExam(examId: string) {
try {
const client = AuthManager.createAuthenticatedExamClient();
selectedExam.value = await client.getExam(examId);
@@ -222,16 +224,32 @@ const viewExam = async (examId: string) => {
} catch (err: any) {
error.value = err.message || "获取实验详情失败";
console.error("获取实验详情失败:", err);
showInfoModal.value = false;
}
};
}
async function handleCreateExamFinished() {
async function handleEditExamFinished() {
await refreshExams();
}
async function handleCardClicked(event: MouseEvent, examId: string) {
if (event.target instanceof HTMLButtonElement) return;
await viewExam(examId);
}
async function handleEditExamClicked(event: MouseEvent, examId: string) {
examEditModalRef?.value?.editExam(examId);
}
// 生命周期
onMounted(async () => {
await checkAdminStatus();
const isAuthenticated = await AuthManager.isAuthenticated();
if (!isAuthenticated) {
router.push("/login");
}
isAdmin.value = await AuthManager.verifyAdminAuth();
await refreshExams();
// 处理路由参数如果有examId则自动打开该实验的详情模态框