diff --git a/src/components/AppBackground.vue b/src/components/AppBackground.vue
index be4c95b..6a31457 100644
--- a/src/components/AppBackground.vue
+++ b/src/components/AppBackground.vue
@@ -63,6 +63,12 @@ const props = defineProps({
src="@/static/app-bg6.png"
mode="widthFix"
/>
+
diff --git a/src/components/training/TrainingDifficultyBadge.vue b/src/components/training/TrainingDifficultyBadge.vue
new file mode 100644
index 0000000..29c0f3e
--- /dev/null
+++ b/src/components/training/TrainingDifficultyBadge.vue
@@ -0,0 +1,327 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ node.label }}
+
+
+
+
+
+
diff --git a/src/components/training/TrainingDifficultyPreviewCard.vue b/src/components/training/TrainingDifficultyPreviewCard.vue
new file mode 100644
index 0000000..3269ac6
--- /dev/null
+++ b/src/components/training/TrainingDifficultyPreviewCard.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+ {{ title }}
+
+ 箭靶划分为3个区域、需5次命中目标
+ 100秒内完成所有射击
+
+
+
+
+
+
diff --git a/src/components/training/TrainingDifficultyStartButton.vue b/src/components/training/TrainingDifficultyStartButton.vue
new file mode 100644
index 0000000..43f3a13
--- /dev/null
+++ b/src/components/training/TrainingDifficultyStartButton.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
diff --git a/src/mock/trainingDifficulty.js b/src/mock/trainingDifficulty.js
new file mode 100644
index 0000000..f6bd42d
--- /dev/null
+++ b/src/mock/trainingDifficulty.js
@@ -0,0 +1,113 @@
+// 难度页当前用于保存“开始训练前上下文”的本地存储 key。
+export const trainingDifficultyStorageKey = "training-selection";
+
+// 当前是页面联调用的模拟数据:
+// 1. 总难度 20 级
+// 2. 已解锁到 Lv3
+// 3. 前三关展示不同完成进度
+const totalDifficultyLevel = 20;
+const mockedUnlockedDifficultyId = "lv3";
+const mockedDifficultyProgressMap = {
+ lv1: 100,
+ lv2: 90,
+ lv3: 70,
+};
+
+const modeList = [
+ {
+ key: "endurance",
+ title: "耐力训练",
+ },
+ {
+ key: "precision",
+ title: "精准训练",
+ },
+ {
+ key: "rhythm",
+ title: "节奏训练",
+ },
+ {
+ key: "basic",
+ title: "基础训练",
+ },
+ {
+ key: "power",
+ title: "力量训练",
+ },
+ {
+ key: "focus",
+ title: "专注训练",
+ },
+];
+
+const createDifficultyId = (level) => `lv${level}`;
+
+const createDifficultyLabel = (level) => `Lv${level}`;
+
+// 根据等级生成模拟文案,方便一次性扩展到更多关卡。
+const createDifficultySummary = (level) => {
+ return [
+ `箭靶划分为${Math.min(1 + Math.floor((level - 1) / 5), 4)}个区域`,
+ `需${4 + level}次命中目标`,
+ `${100 + Math.floor((level - 1) / 2) * 10}秒内完成所有射击`,
+ "需使用20CM全环靶",
+ ];
+};
+
+// 难度页的节点位置已经在页面内统一计算,
+// 这里保留最核心的 id / label 即可,不再维护无效的 left / top / style 字段。
+const createDifficultyNode = (level) => {
+ return {
+ id: createDifficultyId(level),
+ label: createDifficultyLabel(level),
+ };
+};
+
+const createDifficultyDetail = (level) => {
+ const id = createDifficultyId(level);
+ const label = createDifficultyLabel(level);
+
+ return {
+ id,
+ label,
+ title: `${label}难度`,
+ summary: createDifficultySummary(level),
+ startText: "开始",
+ targetPaperType: "20CM全环靶",
+ };
+};
+
+// 所有训练模式当前共用同一套难度定义。
+const sharedDifficultyNodes = Array.from(
+ { length: totalDifficultyLevel },
+ (_, index) => createDifficultyNode(index + 1)
+);
+
+const sharedDifficultyDetails = Object.fromEntries(
+ Array.from({ length: totalDifficultyLevel }, (_, index) => {
+ const detail = createDifficultyDetail(index + 1);
+ return [detail.id, detail];
+ })
+);
+
+const createModeConfig = ({ key, title, reward = null }) => {
+ return {
+ key,
+ title,
+ nodes: sharedDifficultyNodes,
+ details: sharedDifficultyDetails,
+ activeDifficultyId: mockedUnlockedDifficultyId,
+ progressMap: mockedDifficultyProgressMap,
+ reward,
+ };
+};
+
+// 难度页数据源入口:
+// 页面通过 getTrainingDifficultyModeConfig(modeKey) 获取当前模式完整配置。
+export const trainingDifficultyModeMap = Object.fromEntries(
+ modeList.map((mode) => [mode.key, createModeConfig(mode)])
+);
+
+export const getTrainingDifficultyModeConfig = (modeKey) => {
+ return trainingDifficultyModeMap[modeKey] || trainingDifficultyModeMap.precision;
+};
diff --git a/src/pages.json b/src/pages.json
index 4b95d4b..1659b36 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -117,10 +117,13 @@
{
"path": "pages/mine-bow-data"
},
- {
- "path": "pages/training/index"
- }
- ],
+ {
+ "path": "pages/training/difficulty"
+ },
+ {
+ "path": "pages/training/index"
+ }
+ ],
"globalStyle": {
"backgroundColor": "@bgColor",
"backgroundColorBottom": "@bgColorBottom",
diff --git a/src/pages/training/difficulty.vue b/src/pages/training/difficulty.vue
new file mode 100644
index 0000000..2566af8
--- /dev/null
+++ b/src/pages/training/difficulty.vue
@@ -0,0 +1,489 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/training/index.vue b/src/pages/training/index.vue
index 40bef87..802194e 100644
--- a/src/pages/training/index.vue
+++ b/src/pages/training/index.vue
@@ -102,9 +102,8 @@ const openTrainingRecord = () => {
};
const openFeaturedTraining = () => {
- uni.showToast({
- title: `进入${trainingHomeFeatured.title}`,
- icon: "none",
+ uni.navigateTo({
+ url: "/pages/training/difficulty?mode=basic",
});
};
@@ -117,9 +116,8 @@ const openTrainingMode = (item) => {
return;
}
- uni.showToast({
- title: `进入${item.title}`,
- icon: "none",
+ uni.navigateTo({
+ url: `/pages/training/difficulty?mode=${item.key}`,
});
};
diff --git a/src/static/app-bg6.png b/src/static/app-bg6.png
index a492a6a..f443a25 100644
Binary files a/src/static/app-bg6.png and b/src/static/app-bg6.png differ
diff --git a/src/static/app-bg7.png b/src/static/app-bg7.png
new file mode 100644
index 0000000..5e8f9bd
Binary files /dev/null and b/src/static/app-bg7.png differ
diff --git a/src/static/training-difficulty-design/btn.png b/src/static/training-difficulty-design/btn.png
new file mode 100644
index 0000000..c926aaa
Binary files /dev/null and b/src/static/training-difficulty-design/btn.png differ
diff --git a/src/static/training-difficulty-design/jiantou.png b/src/static/training-difficulty-design/jiantou.png
new file mode 100644
index 0000000..f242fa5
Binary files /dev/null and b/src/static/training-difficulty-design/jiantou.png differ
diff --git a/src/static/training-difficulty-design/lock.svg b/src/static/training-difficulty-design/lock.svg
new file mode 100644
index 0000000..7d77123
--- /dev/null
+++ b/src/static/training-difficulty-design/lock.svg
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/src/static/training-difficulty-design/text.png b/src/static/training-difficulty-design/text.png
new file mode 100644
index 0000000..4e5eb9b
Binary files /dev/null and b/src/static/training-difficulty-design/text.png differ
diff --git a/src/static/training-difficulty-design/unlock.svg b/src/static/training-difficulty-design/unlock.svg
new file mode 100644
index 0000000..348bea1
--- /dev/null
+++ b/src/static/training-difficulty-design/unlock.svg
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file