update:新增基础训练入口

This commit is contained in:
2026-05-26 11:38:49 +08:00
parent 2780d1a6df
commit 18afba01ec
4 changed files with 42 additions and 513 deletions

View File

@@ -2,6 +2,7 @@
import { nextTick, onMounted, ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import TargetPicker from "@/components/TargetPicker.vue";
import { getPersonalTrainingAPI } from "@/apis";
const checkedIcon = "../../static/training-home/done.png";
@@ -57,6 +58,7 @@ const createDefaultTrainingData = () => ({
const trainingData = ref(createDefaultTrainingData());
const pageMounted = ref(false);
const showRoutineTargetPicker = ref(false);
const trainingRadarCanvasId = "training-home-radar";
const radarImageWidth = 225;
const radarImageHeight = 224;
@@ -111,10 +113,6 @@ const getTrainingTitleImage = (item = {}) =>
const getTrainingMode = (item = {}) =>
trainingModeRouteMap[item.id] || item.id || "";
const getFeaturedItem = () =>
trainingData.value.training_items.find((item) => item.id === "base") ||
trainingData.value.training_items[0];
const getRadarPoint = (centerX, centerY, radiusX, radiusY, angle) => ({
x: centerX + radiusX * Math.cos(angle),
y: centerY + radiusY * Math.sin(angle),
@@ -243,9 +241,15 @@ const openTrainingItem = (item = {}) => {
});
};
const openFeaturedTraining = () => {
const item = getFeaturedItem();
if (item) openTrainingItem(item);
const openRoutineTraining = () => {
showRoutineTargetPicker.value = true;
};
const handleRoutineTargetConfirm = (target) => {
showRoutineTargetPicker.value = false;
uni.navigateTo({
url: `/pages/practise-one?target=${target}`,
});
};
// 首次进入页面时拉取数据并完成雷达图初始化。
@@ -427,22 +431,22 @@ onShow(async () => {
</view>
</view>
<view class="featured-card" @click="openFeaturedTraining">
<view class="featured-card" @click="openRoutineTraining">
<image
class="featured-card-bg"
src="../../static/training-home/img_22.png"
mode="widthFix"
/>
<view class="featured-card-mask"></view>
<view class="featured-card-copy">
<text class="featured-card-progress">
{{ getLevelText(getFeaturedItem()) }}
</text>
<text class="featured-card-title">常规训练</text>
<text class="featured-card-subtitle">12箭练习</text>
</view>
</view>
<view class="mode-grid">
<view
v-for="item in trainingData.training_items.filter((item) => item.id !== 'base')"
v-for="item in trainingData.training_items.filter((item) => item.id !== 'strength')"
:key="item.id"
class="mode-card"
@click="openTrainingItem(item)"
@@ -466,6 +470,11 @@ onShow(async () => {
</view>
</view>
</view>
<TargetPicker
:show="showRoutineTargetPicker"
:onClose="() => (showRoutineTargetPicker = false)"
:onConfirm="handleRoutineTargetConfirm"
/>
</Container>
</template>
@@ -756,33 +765,47 @@ onShow(async () => {
width: 100%;
height: 150rpx;
margin-top: 70rpx;
border-radius: 16rpx;
overflow: hidden;
}
.featured-card-bg {
width: 100%;
}
.featured-card-mask {
position: absolute;
left: 0;
top: 0;
width: 278rpx;
height: 150rpx;
background: linear-gradient(90deg, #ffdaa0 0%, #f5c580 74%, rgba(245, 197, 128, 0) 100%);
}
.featured-card-copy {
position: absolute;
left: 160rpx;
top: 68rpx;
left: 30rpx;
top: 34rpx;
display: flex;
align-items: center;
flex-direction: column;
}
.featured-card-title {
display: block;
color: #895409;
font-size: 28rpx;
font-size: 34rpx;
font-family: "AlimamaShuHeiTi-Bold", "PingFang SC", sans-serif;
font-weight: 700;
line-height: 32rpx;
line-height: 42rpx;
}
.featured-card-progress {
margin-left: 18rpx;
.featured-card-subtitle {
display: block;
margin-top: 10rpx;
color: #895409;
font-size: 22rpx;
line-height: 32rpx;
opacity: 0.72;
}
.mode-grid {