update:对接个人训练改版

This commit is contained in:
2026-07-23 09:44:58 +08:00
parent a78ab1daeb
commit 3c5754b3fd
64 changed files with 1769 additions and 488 deletions
+84 -9
View File
@@ -5,7 +5,11 @@ import Container from "@/components/Container.vue";
import TrainingDifficultyBadge from "./components/TrainingDifficultyBadge.vue";
import TrainingDifficultyPreviewCard from "./components/TrainingDifficultyPreviewCard.vue";
import TrainingDifficultyStartButton from "./components/TrainingDifficultyStartButton.vue";
import { getTrainingDifficultyListAPI } from "@/apis";
import {
createPractiseV2API,
endPractiseAPI,
getTrainingDifficultyListAPI,
} from "@/apis";
// 难度页接口数据源:
// 1. 接口:GET /training/difficulty/list?type=base/endurance/precision/rhythm
@@ -236,6 +240,7 @@ const nodesScrollTop = ref(0);
const nodesScrollWithAnimation = ref(false);
const routeOptions = ref({});
const needRefreshProgress = ref(false);
const creatingPractice = ref(false);
const difficultyProgressMap = computed(() => {
return pageConfig.value?.progressMap || {};
@@ -574,7 +579,6 @@ const createPracticeQuery = (difficulty) => {
difficulty: difficulty.level,
recordId: difficulty.recordId,
arrows: toNumber(difficulty.arrows, 12),
time: toNumber(difficulty.time_limit, 120) || 120,
target: defaultTargetType,
};
const typedQueryMap = {
@@ -610,7 +614,7 @@ const createPracticeUrl = (difficulty) => {
return `/pages/training/practise-one${query ? `?${query}` : ""}`;
};
const saveTrainingContext = () => {
const saveTrainingContext = (practice = {}) => {
const difficulty = selectedDifficulty.value;
if (!difficulty.id) {
@@ -624,9 +628,32 @@ const saveTrainingContext = () => {
difficultyLabel: difficulty.label,
targetType: defaultTargetType,
targetPaperType: difficulty.targetPaperType,
practiceId: practice.id || "",
serverAddr: practice.serverAddr || "",
createdAt: practice.id ? Date.now() : 0,
});
};
const navigateToPractice = (url) => {
return new Promise((resolve, reject) => {
uni.navigateTo({
url,
success: resolve,
fail: reject,
});
});
};
const stopCreatedPractice = async (id) => {
if (!id) return;
try {
await endPractiseAPI(id);
} catch (error) {
console.error("training practice cleanup failed", error);
}
};
const handleSelectDifficulty = (node) => {
if (!node?.id) {
return;
@@ -650,15 +677,63 @@ const handleSelectDifficulty = (node) => {
});
};
const handleStart = () => {
if (!selectedDifficulty.value.id) {
const handleStart = async () => {
if (!selectedDifficulty.value.id || creatingPractice.value) {
return;
}
saveTrainingContext();
uni.navigateTo({
url: createPracticeUrl(selectedDifficulty.value),
const trainingType = pageConfig.value.key || defaultTrainingType;
const difficultyLevel = selectedDifficulty.value.level;
let createdPracticeId = "";
creatingPractice.value = true;
uni.showLoading({
title: "训练创建中",
mask: true,
});
try {
// 先由业务接口创建训练和比赛服,再把连接上下文交给目标页。
const result = await createPractiseV2API(trainingType, difficultyLevel);
createdPracticeId = result?.id || "";
if (!createdPracticeId) {
saveTrainingContext();
uni.showToast({
title: "训练创建失败,请重试",
icon: "none",
});
return;
}
if (!String(result?.serverAddr || "").trim()) {
await stopCreatedPractice(createdPracticeId);
saveTrainingContext();
uni.showToast({
title: "练习连接信息异常,请重试",
icon: "none",
});
return;
}
saveTrainingContext(result);
await navigateToPractice(createPracticeUrl(selectedDifficulty.value));
createdPracticeId = "";
} catch (error) {
await stopCreatedPractice(createdPracticeId);
saveTrainingContext();
console.error("training practice create failed", error);
if (String(error?.errMsg || "").includes("navigateTo")) {
uni.showToast({
title: "进入训练失败,请重试",
icon: "none",
});
}
} finally {
uni.hideLoading();
creatingPractice.value = false;
}
};
const markProgressRefresh = () => {
@@ -709,7 +784,7 @@ onUnload(() => {
v-for="connector in difficultyConnectors"
:key="connector.id"
class="difficulty-page__connector"
src="../../static/training-difficulty-design/jiantou.png"
src="./static/training-difficulty-design/jiantou.png"
mode="aspectFit"
:style="connector"
/>