- 建立 Lucide 子集 iconfont(49 字形),全站 emoji 替换为 fc-icon 组件 - 重塑 Design Token(冷中性近黑底 + Volt 荧光绿 #B6F24E),消除硬编码颜色 - 首页登录后个性化:我的计划 / 我的收藏 / 今日推荐(纯前端复用现有 API) - 后端 DEFAULT_EMOJI→Lucide 名,PALETTE 对齐 Kinetic Dark 语义色板 - 修复 person-standing 缺失字形;14 个官方组合 seed emoji 全部映射到现有字形
81 lines
3.2 KiB
Plaintext
81 lines
3.2 KiB
Plaintext
<view class="page" wx:if="{{exercise}}">
|
||
<navbar title="{{exercise.displayName || exercise.name}}" show-back />
|
||
|
||
<view class="favbtn" style="top: {{favTop}}px; right: {{favRight}}px;" bindtap="onToggleFav">
|
||
<fc-icon name="heart" size="44" color="{{favorited ? 'var(--accent)' : 'var(--text-3)'}}" />
|
||
</view>
|
||
|
||
<view class="hero">
|
||
<image
|
||
wx:if="{{heroSrc && !heroError}}"
|
||
class="hero__img"
|
||
src="{{heroSrc}}"
|
||
mode="aspectFill"
|
||
lazy-load="true"
|
||
binderror="onHeroError" />
|
||
<view wx:else class="hero__ph"><fc-icon name="dumbbell" size="72" color="var(--text-3)" /></view>
|
||
<!-- 上层叠一个动图播放器:Canvas 逐帧播放 GIF(微信 image 不播 GIF) -->
|
||
<gif-player wx:if="{{heroGif}}" class="hero__gif" src="{{heroGif}}" />
|
||
</view>
|
||
|
||
<view class="body section">
|
||
<view class="name">{{exercise.displayName || exercise.name}}</view>
|
||
|
||
<view class="metas">
|
||
<view class="meta"><view class="meta__k">部位</view><view class="meta__v">{{exercise.bodyPartLabel}}</view></view>
|
||
<view class="meta"><view class="meta__k">器械</view><view class="meta__v">{{exercise.equipmentLabel}}</view></view>
|
||
<view class="meta"><view class="meta__k">目标</view><view class="meta__v gold-text">{{exercise.targetLabel}}</view></view>
|
||
<view class="meta"><view class="meta__k">类型</view><view class="meta__v">{{exercise.typeLabel}}</view></view>
|
||
</view>
|
||
|
||
<view class="block" wx:if="{{exercise.muscleGroupLabel}}">
|
||
<view class="block__h eyebrow">主要肌群</view>
|
||
<view class="chips">
|
||
<text class="tag tag--gold">{{exercise.muscleGroupLabel}}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="block" wx:if="{{exercise.secondaryMusclesLabels.length}}">
|
||
<view class="block__h eyebrow">协同肌群</view>
|
||
<view class="chips">
|
||
<text wx:for="{{exercise.secondaryMusclesLabels}}" wx:key="*this" class="tag">{{item}}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="block" wx:if="{{exercise.instructionSteps.zh.length}}">
|
||
<view class="block__h eyebrow">动作步骤</view>
|
||
<view class="steps">
|
||
<view class="step" wx:for="{{exercise.instructionSteps.zh}}" wx:key="index">
|
||
<view class="step__n">{{index + 1}}</view>
|
||
<view class="step__t">{{item}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="block" wx:if="{{exercise.instructions.zh}}">
|
||
<view class="block__h eyebrow">要点提示</view>
|
||
<view class="tips">{{exercise.instructions.zh}}</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="section" wx:if="{{related.length}}">
|
||
<view class="block__h eyebrow">相关推荐</view>
|
||
<scroll-view scroll-x class="hscroll">
|
||
<view class="hscroll__item" wx:for="{{related}}" wx:key="id">
|
||
<exercise-card exercise="{{item}}" compact catch:tap="onExercise" />
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<view class="addbar">
|
||
<view class="cta" bindtap="onAdd">{{ planId ? '加入该计划' : '加入计划' }}</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view wx:else class="empty-page">
|
||
<view class="topbar" style="padding-top: {{statusBarHeight}}px;">
|
||
<view class="topbar__back" bindtap="onBack">‹</view>
|
||
</view>
|
||
<view class="empty">{{ loading ? '加载中…' : '未找到该动作' }}</view>
|
||
</view>
|