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