feat: 复习跳转改为先进入目标页
This commit is contained in:
@@ -1,18 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {
|
||||
getReviewTaskStats,
|
||||
getTaskReview,
|
||||
type ReviewFeedItem,
|
||||
type ReviewTaskStats,
|
||||
} from "@/api/review";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const loading = ref(false);
|
||||
const openingTaskNum = ref("");
|
||||
const tasks = ref<ReviewTaskStats[]>([]);
|
||||
|
||||
const summary = computed(() => ({
|
||||
@@ -40,21 +36,9 @@ const loadTasks = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const openTaskReview = async (row: ReviewTaskStats) => {
|
||||
const openTaskReview = (row: ReviewTaskStats) => {
|
||||
if (!row.taskNum) return;
|
||||
openingTaskNum.value = row.taskNum;
|
||||
try {
|
||||
const res = await getTaskReview(row.taskNum);
|
||||
const items: ReviewFeedItem[] = res?.data || [];
|
||||
const first = items[0];
|
||||
if (!first) {
|
||||
ElMessage.info("该任务暂无可复习内容");
|
||||
return;
|
||||
}
|
||||
router.push(`/review/detail/${first.sourceType.toLowerCase()}/${first.id}`);
|
||||
} finally {
|
||||
openingTaskNum.value = "";
|
||||
}
|
||||
router.push(`/review/detail/task/${encodeURIComponent(row.taskNum)}`);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
@@ -105,7 +89,6 @@ onMounted(() => {
|
||||
text
|
||||
type="success"
|
||||
size="small"
|
||||
:loading="openingTaskNum === row.taskNum"
|
||||
@click="openTaskReview(row)"
|
||||
>
|
||||
查看记录
|
||||
|
||||
@@ -9,34 +9,29 @@ import {
|
||||
} from "@/api/review";
|
||||
import { getSessionDetail } from "@/api/studySessions";
|
||||
import { updateFragments } from "@/api/reportFragments";
|
||||
import { findNode } from "@/api/standardMindMap";
|
||||
import { ElMessage } from "element-plus";
|
||||
import MarkdownRenderer from "@/components/MarkdownRenderer.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
/** 调用 findNode API 匹配标准导图中的最近节点,跳转到回忆页 */
|
||||
const goToRecall = async () => {
|
||||
if (!content.value || !content.value.trim()) {
|
||||
router.push(`/review/recall/${taskNum.value}`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await findNode(taskNum.value, content.value.substring(0, 500));
|
||||
const data = res?.data;
|
||||
if (data?.path) {
|
||||
router.push(`/review/recall/${taskNum.value}?focusPath=${encodeURIComponent(data.path)}`);
|
||||
} else {
|
||||
router.push(`/review/recall/${taskNum.value}`);
|
||||
}
|
||||
} catch {
|
||||
router.push(`/review/recall/${taskNum.value}`);
|
||||
/** 直接进入回忆复习页,节点匹配交给目标页加载后处理 */
|
||||
const goToRecall = () => {
|
||||
const tn = taskNum.value;
|
||||
if (!tn) return;
|
||||
if (content.value && content.value.trim()) {
|
||||
router.push(`/review/recall/${tn}?focusContent=${encodeURIComponent(content.value.substring(0, 500))}`);
|
||||
} else {
|
||||
router.push(`/review/recall/${tn}`);
|
||||
}
|
||||
};
|
||||
|
||||
const contentType = computed(() => route.params.type as string);
|
||||
const contentId = computed(() => Number(route.params.id));
|
||||
const isTaskMode = computed(() => !!route.params.taskNum);
|
||||
const activeType = ref<string | undefined>(undefined);
|
||||
const activeId = ref<number | undefined>(undefined);
|
||||
const contentType = computed(() => isTaskMode.value ? activeType.value : (route.params.type as string));
|
||||
const contentId = computed(() => isTaskMode.value ? activeId.value ?? 0 : Number(route.params.id));
|
||||
const taskModeTaskNum = computed(() => route.params.taskNum as string | undefined);
|
||||
|
||||
const loading = ref(true);
|
||||
const content = ref("");
|
||||
@@ -118,7 +113,19 @@ const loadDetail = async () => {
|
||||
taskNum.value = "";
|
||||
sessionInfo.value = null;
|
||||
taskSessions.value = [];
|
||||
if (isTaskMode.value) {
|
||||
activeType.value = undefined;
|
||||
activeId.value = undefined;
|
||||
}
|
||||
try {
|
||||
if (isTaskMode.value && taskModeTaskNum.value) {
|
||||
const taskRes = await getTaskReview(taskModeTaskNum.value);
|
||||
const items: ReviewFeedItem[] = taskRes?.data || [];
|
||||
const first = items[0];
|
||||
if (!first) return;
|
||||
activeType.value = first.sourceType.toLowerCase();
|
||||
activeId.value = first.id;
|
||||
}
|
||||
let res;
|
||||
if (contentType.value === "report") {
|
||||
res = await getReportDetail(contentId.value);
|
||||
@@ -194,8 +201,12 @@ const saveEdit = async () => {
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [contentType.value, contentId.value],
|
||||
() => [route.params.type, route.params.id, route.params.taskNum],
|
||||
() => {
|
||||
if (!isTaskMode.value) {
|
||||
activeType.value = undefined;
|
||||
activeId.value = undefined;
|
||||
}
|
||||
loadDetail();
|
||||
},
|
||||
{ immediate: true },
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
findNode,
|
||||
getStandardMindMap,
|
||||
regenerateStandardMindMap,
|
||||
recallCompare,
|
||||
@@ -31,6 +32,7 @@ const hasCompared = ref(false);
|
||||
|
||||
// 起点节点选择
|
||||
const focusPath = ref((route.query.focusPath as string) || "");
|
||||
const focusContent = ref((route.query.focusContent as string) || "");
|
||||
const focusConfirmVisible = ref(false);
|
||||
const selectedNodeInfo = ref<{ title: string; path: string; childCount: number } | null>(null);
|
||||
|
||||
@@ -114,6 +116,17 @@ const loadData = async () => {
|
||||
try {
|
||||
const res = await getStandardMindMap(taskNum.value);
|
||||
standard.value = res?.data || null;
|
||||
if (focusContent.value && standard.value) {
|
||||
try {
|
||||
const nodeRes = await findNode(taskNum.value, focusContent.value.substring(0, 500));
|
||||
const data = nodeRes?.data;
|
||||
if (data?.path) {
|
||||
focusPath.value = data.path;
|
||||
}
|
||||
} catch {
|
||||
// 匹配失败时仍可进入回忆页
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
standard.value = null;
|
||||
} finally {
|
||||
@@ -382,7 +395,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="recall-page">
|
||||
<section class="recall-page" v-loading="loading">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="page-header">
|
||||
<h2>回忆复习</h2>
|
||||
|
||||
@@ -87,9 +87,11 @@ const revealRecallContent = async () => {
|
||||
recallCard.value.loadError = "";
|
||||
try {
|
||||
const res = await getTaskReview(fragment.taskNum);
|
||||
const items = (res?.data || []).filter(item => item.sessionNum === fragment.sessionNum);
|
||||
recallCard.value.report = items.find(item => item.sourceType === "REPORT") || null;
|
||||
recallCard.value.fragments = items.filter(item => item.sourceType === "FRAGMENT");
|
||||
const items: ReviewFeedItem[] = (res?.data || []).filter(
|
||||
(item: ReviewFeedItem) => item.sessionNum === fragment.sessionNum,
|
||||
);
|
||||
recallCard.value.report = items.find((item: ReviewFeedItem) => item.sourceType === "REPORT") || null;
|
||||
recallCard.value.fragments = items.filter((item: ReviewFeedItem) => item.sourceType === "FRAGMENT");
|
||||
recallCard.value.revealed = true;
|
||||
} catch {
|
||||
recallCard.value.loadError = "展开对照内容加载失败,请稍后重试";
|
||||
@@ -98,23 +100,16 @@ const revealRecallContent = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 从回忆卡片跳转到回忆复习页(先匹配标准导图节点) */
|
||||
const goToRecallFromCard = async () => {
|
||||
/** 从回忆卡片跳转到回忆复习页,节点匹配交给目标页加载后处理 */
|
||||
const goToRecallFromCard = () => {
|
||||
const fragment = recallCard.value.fragment;
|
||||
if (!fragment) return;
|
||||
recallCard.value.visible = false;
|
||||
const tn = fragment.taskNum;
|
||||
const content = fragment.content || "";
|
||||
if (tn && content) {
|
||||
try {
|
||||
const { findNode } = await import("@/api/standardMindMap");
|
||||
const res = await findNode(tn, content.substring(0, 500));
|
||||
const data = res?.data;
|
||||
if (data?.path) {
|
||||
router.push(`/review/recall/${tn}?focusPath=${encodeURIComponent(data.path)}`);
|
||||
return;
|
||||
}
|
||||
} catch { /* fall through */ }
|
||||
router.push(`/review/recall/${tn}?focusContent=${encodeURIComponent(content)}`);
|
||||
} else if (tn) {
|
||||
router.push(`/review/recall/${tn}`);
|
||||
} else {
|
||||
router.push("/review");
|
||||
|
||||
@@ -27,6 +27,11 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import("@/components/Review.vue"),
|
||||
meta: { requiresAuth: true, title: "复习总览" },
|
||||
},
|
||||
{
|
||||
path: "/review/detail/task/:taskNum",
|
||||
component: () => import("@/components/ReviewDetail.vue"),
|
||||
meta: { requiresAuth: true, title: "复习详情" },
|
||||
},
|
||||
{
|
||||
path: "/review/detail/:type/:id",
|
||||
component: () => import("@/components/ReviewDetail.vue"),
|
||||
|
||||
Reference in New Issue
Block a user