update:优化个人训练
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
startPractiseAPI,
|
||||
endPractiseAPI,
|
||||
getPractiseAPI,
|
||||
getTrainingDifficultyListAPI,
|
||||
} from "@/apis";
|
||||
import {
|
||||
connectMatchWebSocket,
|
||||
@@ -52,6 +53,7 @@ const defaultTargetType = 1;
|
||||
const total = ref(defaultTotal);
|
||||
const practiseResult = ref({});
|
||||
const practiceEndSnapshot = ref({});
|
||||
const hasNextDifficulty = ref(false);
|
||||
const practiseId = ref("");
|
||||
const showGuide = ref(false);
|
||||
const tips = ref("");
|
||||
@@ -64,7 +66,6 @@ const visiblePrecisionTarget = ref({
|
||||
randomRingArea: 0,
|
||||
});
|
||||
const trainingDifficultyStorageKey = "training-selection";
|
||||
const trainingDifficultyRefreshEvent = "training-difficulty-refresh";
|
||||
const useHighlightTest = ref(false);
|
||||
const highlightTestState = ref({
|
||||
blocks: 8,
|
||||
@@ -87,6 +88,8 @@ let stopPracticeTask = null;
|
||||
let practiceSyncTimer = null;
|
||||
let waitingPracticeSync = false;
|
||||
let shotPresentationGeneration = 0;
|
||||
let nextDifficultyRequest = null;
|
||||
let nextDifficultyRequestGeneration = 0;
|
||||
const audioWaiters = new Set();
|
||||
const shotEffectWaiters = new Map();
|
||||
const PRACTICE_SYNC_TIMEOUT_MS = 5000;
|
||||
@@ -152,6 +155,63 @@ const currentDifficultyLevel = computed(
|
||||
getPositiveInteger(trainingParams.value.difficulty)
|
||||
);
|
||||
|
||||
const resetNextDifficultyState = () => {
|
||||
nextDifficultyRequestGeneration += 1;
|
||||
nextDifficultyRequest = null;
|
||||
hasNextDifficulty.value = false;
|
||||
};
|
||||
|
||||
const loadNextDifficultyState = (result = {}) => {
|
||||
const requestGeneration = ++nextDifficultyRequestGeneration;
|
||||
const currentLevel =
|
||||
getPositiveInteger(result.difficultyLevel) ||
|
||||
getPositiveInteger(result.difficulty_level) ||
|
||||
currentDifficultyLevel.value;
|
||||
const currentTrainingType = result.trainingType || trainingType.value;
|
||||
|
||||
hasNextDifficulty.value = false;
|
||||
if (!currentTrainingType || !currentLevel) {
|
||||
nextDifficultyRequest = Promise.resolve(false);
|
||||
return nextDifficultyRequest;
|
||||
}
|
||||
|
||||
nextDifficultyRequest = getTrainingDifficultyListAPI(currentTrainingType)
|
||||
.then((difficultyResult) => {
|
||||
const levels = Array.isArray(difficultyResult?.list)
|
||||
? difficultyResult.list
|
||||
.filter(
|
||||
(item) => !item?.type || item.type === currentTrainingType
|
||||
)
|
||||
.map((item) => getPositiveInteger(item?.difficulty))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
const maxLevel = Math.max(0, ...levels);
|
||||
const highestCompletedLevel = getPositiveInteger(
|
||||
difficultyResult?.user_levels?.[currentTrainingType]
|
||||
);
|
||||
const latestUnlockedLevel = Math.min(
|
||||
highestCompletedLevel + 1,
|
||||
maxLevel
|
||||
);
|
||||
const canAdvance =
|
||||
currentLevel < maxLevel && latestUnlockedLevel > currentLevel;
|
||||
|
||||
if (requestGeneration === nextDifficultyRequestGeneration) {
|
||||
hasNextDifficulty.value = canAdvance;
|
||||
}
|
||||
return canAdvance;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("training next difficulty load failed", error);
|
||||
if (requestGeneration === nextDifficultyRequestGeneration) {
|
||||
hasNextDifficulty.value = false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return nextDifficultyRequest;
|
||||
};
|
||||
|
||||
// time_limit 缺失或非正数都表示整局不限时。
|
||||
const timeLimit = computed(() => getPositiveInteger(practiceInfo.value.timeLimit));
|
||||
const hasTimeLimit = computed(() => timeLimit.value > 0);
|
||||
@@ -1007,11 +1067,13 @@ const onOver = async () => {
|
||||
|
||||
try {
|
||||
const apiResult = (await getPractiseAPI(practiseId.value)) || {};
|
||||
await (nextDifficultyRequest || loadNextDifficultyState(apiResult));
|
||||
if (!enterPracticeResult(mergePracticeResult(apiResult))) {
|
||||
pageStage.value = pageStages.DISTANCE;
|
||||
}
|
||||
} catch (error) {
|
||||
if (Object.keys(practiceEndSnapshot.value).length > 0) {
|
||||
await (nextDifficultyRequest || loadNextDifficultyState(practiceEndSnapshot.value));
|
||||
enterPracticeResult(mergePracticeResult());
|
||||
return;
|
||||
}
|
||||
@@ -1067,6 +1129,7 @@ async function onReceiveMessage(msg) {
|
||||
}
|
||||
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
|
||||
practiceEndSnapshot.value = createPracticeEndSnapshot(msg);
|
||||
void loadNextDifficultyState(practiceEndSnapshot.value);
|
||||
if (
|
||||
trainingType.value === "base" &&
|
||||
Number(msg.status) === 3 &&
|
||||
@@ -1093,7 +1156,6 @@ function onComplete() {
|
||||
invalidateShotPresentations();
|
||||
clearPracticeRuntimeContext();
|
||||
closePracticeConnection("training-practice-complete");
|
||||
uni.$emit(trainingDifficultyRefreshEvent);
|
||||
uni.navigateBack();
|
||||
}
|
||||
|
||||
@@ -1102,6 +1164,7 @@ async function onRetry() {
|
||||
setPracticeAppHideResumable(false);
|
||||
clearHighlightTestTimer();
|
||||
useHighlightTest.value = false;
|
||||
resetNextDifficultyState();
|
||||
practiseId.value = "";
|
||||
serverAddr.value = "";
|
||||
practiseResult.value = {};
|
||||
@@ -1332,6 +1395,7 @@ onBeforeUnmount(() => {
|
||||
:onRetry="onRetry"
|
||||
:trainingType="trainingType"
|
||||
:difficultyLevel="currentDifficultyLevel"
|
||||
:hasNextDifficulty="hasNextDifficulty"
|
||||
:result="practiseResult"
|
||||
/>
|
||||
<canvas class="share-canvas" id="shareCanvas" type="2d"></canvas>
|
||||
|
||||
Reference in New Issue
Block a user