feat(ui): Phase 1 UI/动画优化实现

- 肺部健康可视化组件(SVG肺部+呼吸动画+气泡效果)
- 打卡多巴胺反馈动画(成功弹窗+震动反馈)
- 悬浮记录按钮(右下角FAB+呼吸动画)
- 空状态优化(演示数据预览+引导文案)
- 记录模式空状态视觉升级
- 统计页面空状态统一

参考: docs/PRD-UI-Animation-Optimization.md
This commit is contained in:
nepiedg
2026-04-13 14:00:36 +08:00
parent ec87a9fc55
commit 7ef21ad39d
4 changed files with 1063 additions and 70 deletions
+68 -7
View File
@@ -55,7 +55,13 @@
</view>
</view>
<view v-else class="empty-block">
<text class="empty-text">暂无趋势数据</text>
<view class="empty-visual empty-visual-trend">
<text class="empty-visual-glyph">7</text>
</view>
<view class="empty-copy">
<text class="empty-title">暂无趋势数据</text>
<text class="empty-text">完成今天的记录后这里会开始展示最近 7 天的波动节奏</text>
</view>
</view>
</view>
@@ -80,7 +86,13 @@
</view>
</view>
<view v-else class="empty-block empty-block-dashed">
<text class="empty-text">完善基础信息后解锁节省金额</text>
<view class="empty-visual empty-visual-money">
<text class="empty-visual-glyph">¥</text>
</view>
<view class="empty-copy">
<text class="empty-title">节省金额待解锁</text>
<text class="empty-text">完善基础信息后系统会自动换算每少抽一支烟省下的金额</text>
</view>
</view>
<view v-if="moneyAvailable" class="metric-chips">
@@ -118,7 +130,13 @@
</view>
</view>
<view v-else class="empty-block empty-block-dashed">
<text class="empty-text">暂无健康数据记录一次后解锁</text>
<view class="empty-visual empty-visual-health">
<text class="empty-visual-glyph"></text>
</view>
<view class="empty-copy">
<text class="empty-title">暂无健康数据</text>
<text class="empty-text">完成一次记录后这里会开始生成无烟时长和恢复节点</text>
</view>
</view>
<view v-if="healthItems.length > 0" class="health-list">
<view v-for="(item, index) in healthItems" :key="index" class="health-item">
@@ -790,12 +808,12 @@ onShareAppMessage(() => {
/* ── 空状态 ── */
.empty-block {
padding: 32rpx;
border-radius: 16rpx;
background: rgba(52, 200, 160, 0.04);
padding: 28rpx 24rpx;
border-radius: 20rpx;
background: rgba(52, 200, 160, 0.05);
display: flex;
align-items: center;
justify-content: center;
gap: 18rpx;
}
.empty-block-dashed {
@@ -803,8 +821,51 @@ onShareAppMessage(() => {
background: transparent;
}
.empty-visual {
width: 78rpx;
height: 78rpx;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.8);
}
.empty-visual-trend {
background: linear-gradient(180deg, rgba(52, 200, 160, 0.16) 0%, rgba(52, 200, 160, 0.08) 100%);
}
.empty-visual-money {
background: linear-gradient(180deg, rgba(251, 191, 36, 0.18) 0%, rgba(245, 158, 11, 0.08) 100%);
}
.empty-visual-health {
background: linear-gradient(180deg, rgba(52, 200, 160, 0.18) 0%, rgba(59, 130, 246, 0.08) 100%);
}
.empty-visual-glyph {
font-size: 28rpx;
font-weight: 800;
color: #0D3D2E;
}
.empty-copy {
flex: 1;
min-width: 0;
}
.empty-title {
display: block;
font-size: 24rpx;
font-weight: 700;
color: #0D3D2E;
margin-bottom: 6rpx;
}
.empty-text {
font-size: 24rpx;
line-height: 1.6;
color: #7aA898;
}