- 8 个页面 exercise-card 由 bind:tap 改为 catch:tap,拦截原生 tap 冒泡 避免一次点击被『自定义事件 + 原生冒泡』触发两次, 第二次 e.detail 无 id → navigateTo detail?id=undefined → 404 - 所有 onExercise 顶部加 id 守卫,无 id 直接 return - exercise-card 点击前校验 exercise.id,缺失不触发 - detail onLoad 的 id 为空时直接显示空态,不再发起错误请求
81 lines
2.9 KiB
Plaintext
81 lines
2.9 KiB
Plaintext
<view class="page" style="padding-top: {{statusBarHeight}}px;">
|
||
<view class="topbar">
|
||
<view class="topbar__back" bindtap="onBack">‹</view>
|
||
<view class="topbar__title">智能推荐</view>
|
||
</view>
|
||
|
||
<!-- 步骤 1:选择目标肌群 -->
|
||
<block wx:if="{{step === 1}}">
|
||
<view class="hero2">
|
||
<view class="hero2__eyebrow">SMART MATCH</view>
|
||
<view class="hero2__title">选择你的目标肌群</view>
|
||
<view class="hero2__sub">为你智能匹配最合适动作,并给出训练理由</view>
|
||
</view>
|
||
|
||
<view class="section">
|
||
<view class="group" wx:for="{{bodyGroups}}" wx:key="label" wx:for-item="group">
|
||
<view class="group__label eyebrow">{{group.label}}</view>
|
||
<view class="group__chips">
|
||
<view
|
||
wx:for="{{group.targets}}"
|
||
wx:key="value"
|
||
wx:for-item="t"
|
||
class="tgt {{selectedTarget === t.value ? 'tgt--active' : ''}}"
|
||
data-value="{{t.value}}"
|
||
data-label="{{t.label}}"
|
||
bindtap="onSelectTarget">
|
||
<text>{{t.label}}</text>
|
||
<text class="tgt__count">{{t.count}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="group" wx:if="{{equipments.length}}">
|
||
<view class="group__label eyebrow">器械偏好(可选)</view>
|
||
<view class="group__chips">
|
||
<view
|
||
wx:for="{{equipments}}"
|
||
wx:key="value"
|
||
wx:for-item="eq"
|
||
class="tgt {{selectedEquipment === eq.value ? 'tgt--active' : ''}}"
|
||
data-value="{{eq.value}}"
|
||
bindtap="onSelectEquipment">
|
||
<text>{{eq.label}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="confirm">
|
||
<view class="confirm__bar">
|
||
<text wx:if="{{selectedTargetLabel}}" class="confirm__sel">已选:{{selectedTargetLabel}}</text>
|
||
<text wx:else class="confirm__hint">请选择目标肌群</text>
|
||
</view>
|
||
<view class="cta" bindtap="onConfirm">
|
||
<text>智能匹配动作</text>
|
||
<text class="cta__arrow">›</text>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
|
||
<!-- 步骤 2:结果列表 -->
|
||
<block wx:else>
|
||
<view class="section" style="padding-top: 8rpx;">
|
||
<view class="result-head">
|
||
<text class="result-head__title">为你匹配 · {{selectedTargetLabel}}</text>
|
||
<text class="result-head__count">{{results.length}} 个动作</text>
|
||
</view>
|
||
<view class="rlist" wx:if="{{results.length}}">
|
||
<view class="rlist__item" wx:for="{{results}}" wx:key="id" wx:for-item="item">
|
||
<exercise-card
|
||
exercise="{{item}}"
|
||
score="{{item.score}}"
|
||
reason="{{item.reason}}"
|
||
catch:tap="onExercise" />
|
||
</view>
|
||
</view>
|
||
<view wx:else class="empty">{{ loading ? '匹配中…' : '暂无匹配结果' }}</view>
|
||
</view>
|
||
</block>
|
||
</view>
|