update:优化个人训练

This commit is contained in:
2026-07-27 16:38:53 +08:00
parent c5618fb60b
commit e6f11d3684
6 changed files with 221 additions and 48 deletions
+22 -23
View File
@@ -1,6 +1,6 @@
<script setup>
import { computed, nextTick, ref } from "vue";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import { onHide, onLoad, onShow } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import TrainingDifficultyBadge from "./components/TrainingDifficultyBadge.vue";
import TrainingDifficultyPreviewCard from "./components/TrainingDifficultyPreviewCard.vue";
@@ -15,7 +15,6 @@ import {
// 1. 接口:GET /training/difficulty/list?type=base/endurance/precision/rhythm
// 2. 当前进度:接口 user_levels / list.completed,路由参数可覆盖选中难度
const trainingDifficultyStorageKey = "training-selection";
const trainingDifficultyRefreshEvent = "training-difficulty-refresh";
const defaultTrainingType = "precision";
const defaultUnlockedDifficultyId = "lv1";
const trainingTypeMetaMap = {
@@ -239,8 +238,9 @@ const selectedDifficultyId = ref(defaultUnlockedDifficultyId);
const nodesScrollTop = ref(0);
const nodesScrollWithAnimation = ref(false);
const routeOptions = ref({});
const needRefreshProgress = ref(false);
const shouldRefreshOnShow = ref(false);
const creatingPractice = ref(false);
let pageStateRequestGeneration = 0;
const difficultyProgressMap = computed(() => {
return pageConfig.value?.progressMap || {};
@@ -533,6 +533,7 @@ const applyPageState = (options = {}, config) => {
};
const initPageState = async (options = {}, refreshOptions = {}) => {
const requestGeneration = ++pageStateRequestGeneration;
const { keepCurrent = false } = refreshOptions;
const trainingType = resolveTrainingType(options.mode);
const fallbackConfig = createEmptyModeConfig(trainingType);
@@ -543,11 +544,19 @@ const initPageState = async (options = {}, refreshOptions = {}) => {
try {
const result = await getTrainingDifficultyListAPI(trainingType);
if (requestGeneration !== pageStateRequestGeneration) {
return;
}
applyPageState(
options,
normalizeTrainingDifficultyConfig(result, trainingType)
);
} catch (error) {
if (requestGeneration !== pageStateRequestGeneration) {
return;
}
console.log("training difficulty load failed", error);
if (!keepCurrent) {
applyPageState(options, fallbackConfig);
@@ -687,10 +696,6 @@ const handleStart = async () => {
let createdPracticeId = "";
creatingPractice.value = true;
uni.showLoading({
title: "训练创建中",
mask: true,
});
try {
// 先由业务接口创建训练和比赛服,再把连接上下文交给目标页。
@@ -731,35 +736,27 @@ const handleStart = async () => {
});
}
} finally {
uni.hideLoading();
creatingPractice.value = false;
}
};
const markProgressRefresh = () => {
needRefreshProgress.value = true;
};
onLoad((options = {}) => {
routeOptions.value = { ...options };
uni.$on(trainingDifficultyRefreshEvent, markProgressRefresh);
initPageState(options);
void initPageState(options);
});
onHide(() => {
shouldRefreshOnShow.value = true;
});
onShow(() => {
if (!needRefreshProgress.value) {
return;
}
if (!shouldRefreshOnShow.value) return;
needRefreshProgress.value = false;
initPageState(routeOptions.value, {
shouldRefreshOnShow.value = false;
void initPageState(routeOptions.value, {
keepCurrent: true,
});
});
onUnload(() => {
uni.$off(trainingDifficultyRefreshEvent, markProgressRefresh);
});
</script>
<template>
@@ -768,6 +765,8 @@ onUnload(() => {
:bgType="8"
bgColor="#1c1c23"
:scroll="false"
:loading="creatingPractice"
loadingText="训练创建中..."
>
<view class="difficulty-page">
<view class="difficulty-page__nodes">