feat(fe): 其余 8 页 + 三个薄组件套用新设计语言

页面:
- record:3×3 emoji 九宫格(184rpx 高、全站最大的点击块)换成图标 + 4 色分类,
  和首页的 8 宫格合并成同一套 .quick-grid,此前它俩是同一个东西的两个副本
- record/plan/community:三套横向切换全部换成 seg-tabs
- record/plan/community/report/learn:砍掉与 nav-bar 重复的 46rpx 大标题,
  每页白赚约 130rpx 首屏
- 时间轴图标改按 HealthRecord.Type 取(9 值枚举,可靠),老数据里的 emoji
  只作兜底;写库的 icon 字段一个字符没动
- profile:设置行加分类图标 + 右侧箭头换图标
- community/report:主操作改深色 CTA,btn-primary 继续留给弹层的「保存」
- 6 套空态写法统一成 .empty

组件:
- nav-bar 的 ‹ 和 fab 的 "AI" 文字换成图标;fab 从蓝渐变改深色,
  和全站唯一主 CTA 的语义对齐
- pet-switch 的「+」换图标;宠物自己的 emoji 是用户数据,保留

pt-icon 开了 virtualHost,组件标签上的 class 不生效,需要定位的地方
(profile 行图标、箭头)都用外层 view 包了一层。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-29 10:54:18 +08:00
parent c076968b2c
commit 2fd25e26ef
36 changed files with 305 additions and 291 deletions
+2 -1
View File
@@ -67,8 +67,9 @@ Page({
toastErr(e);
});
},
// 来自 seg-tabs 的 change 事件
switchFeedTab(e) {
this.setData({ feedIdx: e.currentTarget.dataset.index });
this.setData({ feedIdx: Number(e.detail.index) });
this.loadPosts();
},
likePost(e) {
+3 -1
View File
@@ -2,6 +2,8 @@
"usingComponents": {
"nav-bar": "/components/nav-bar/nav-bar",
"bottom-sheet": "/components/bottom-sheet/bottom-sheet",
"fab": "/components/fab/fab"
"fab": "/components/fab/fab",
"pt-icon": "/components/pt-icon/index",
"seg-tabs": "/components/seg-tabs/index"
}
}
+7 -15
View File
@@ -5,18 +5,10 @@ module.exports.isUrl = function (s) { return s && s.indexOf('http') === 0; }
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body">
<view class="page-title">
<view class="pt-h2">宠友圈</view>
<view class="pt-p">和宠友交流、晒宠、求助与经验分享。</view>
</view>
<scroll-view class="feed-tabs" scroll-x="true" enhanced="{{true}}" show-scrollbar="{{false}}">
<view wx:for="{{feedTabs}}" wx:key="*this"
class="feed-tab {{feedIdx === index ? 'active' : ''}}" data-index="{{index}}" bindtap="switchFeedTab">{{item}}</view>
</scroll-view>
<seg-tabs items="{{feedTabs}}" current="{{feedIdx}}" bind:change="switchFeedTab"></seg-tabs>
<view class="compose-card">
<button class="btn btn-primary btn-block" bindtap="openSheet" data-type="createPost"> 发布图文</button>
<button class="btn btn-dark btn-block" bindtap="openSheet" data-type="createPost"><pt-icon name="plus" size="{{30}}"></pt-icon>发布图文</button>
</view>
<view wx:for="{{posts}}" wx:key="id" class="post-card" bindlongpress="onLongPressPost" data-index="{{index}}">
@@ -35,17 +27,17 @@ module.exports.isUrl = function (s) { return s && s.indexOf('http') === 0; }
</block>
</view>
<view class="post-actions">
<view class="pa-btn {{item.liked ? 'liked' : ''}}" data-index="{{index}}" bindtap="likePost">{{item.liked ? '♥' : '♡'}} {{item.like_count}}</view>
<view class="pa-btn" data-id="{{item.id}}" bindtap="openComments">💬 {{item.comment_count}}</view>
<button class="pa-btn pa-share" open-type="share" data-content="{{item.content}}">分享</button>
<view class="pa-btn {{item.liked ? 'liked' : ''}}" data-index="{{index}}" bindtap="likePost"><pt-icon name="{{item.liked ? 'like-on' : 'like'}}" size="{{30}}"></pt-icon>{{item.like_count}}</view>
<view class="pa-btn" data-id="{{item.id}}" bindtap="openComments"><pt-icon name="comment" size="{{30}}"></pt-icon>{{item.comment_count}}</view>
<button class="pa-btn pa-share" open-type="share" data-content="{{item.content}}"><pt-icon name="share" size="{{30}}"></pt-icon>分享</button>
</view>
</view>
<view wx:if="{{loadErr}}" class="empty-hint">
<view wx:if="{{loadErr}}" class="empty lg">
{{loadErr}}
<view class="retry-btn" bindtap="loadPosts">点击重试</view>
</view>
<view wx:elif="{{loaded && posts.length === 0}}" class="empty-hint">
<view wx:elif="{{loaded && posts.length === 0}}" class="empty lg">
{{feedTabs[feedIdx] === '关注' ? '还没有关注的人,去「推荐」里关注几个宠友吧 🐾' : '还没有帖子,来发第一条吧 🐾'}}
</view>
</view>
+30 -36
View File
@@ -1,50 +1,44 @@
.feed-tabs{white-space:nowrap;padding:0 0 24rpx}
.feed-tab{
display:inline-block;border:1rpx solid var(--line);background:#fff;border-radius:999rpx;
height:68rpx;line-height:68rpx;padding:0 26rpx;color:var(--muted);font-size:26rpx;font-weight:900;
box-shadow:0 12rpx 32rpx rgba(70,48,25,.05);margin-right:16rpx;
}
.feed-tab.active{color:var(--primary-dark);background:#FFF4E4;border-color:#FFD39A}
.compose-card{margin-bottom:var(--sp-4)}
.compose-card{margin-bottom:28rpx}
.post-card{background:#fff;border-radius:48rpx;box-shadow:var(--shadow);padding:30rpx;margin-bottom:28rpx}
.post-head{display:flex;align-items:center;gap:20rpx;margin-bottom:22rpx}
.post-card{background:#fff;border-radius:var(--r-lg);box-shadow:var(--sd-1);padding:var(--sp-4);margin-bottom:var(--sp-4)}
.post-head{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.post-avatar{
width:84rpx;height:84rpx;border-radius:32rpx;background:#FFF0D8;
display:flex;align-items:center;justify-content:center;font-size:44rpx;flex:none;
width:80rpx;height:80rpx;border-radius:var(--r-sm);background:var(--primary-soft);
display:flex;align-items:center;justify-content:center;font-size:40rpx;flex:none;
}
.post-user{flex:1}
.pu-b{font-size:28rpx;display:block;font-weight:700}
.ai-tag{display:inline-block;margin-left:10rpx;padding:0 10rpx;border-radius:8rpx;background:#EAF0FF;color:#3B6BE5;font-size:20rpx;font-weight:700;vertical-align:1rpx}
.pu-s{font-size:24rpx;color:var(--muted)}
.post-content{font-size:28rpx;line-height:1.62;color:#443D37;margin-bottom:24rpx}
.post-user{flex:1;min-width:0}
.pu-b{font-size:var(--fs-md);display:block;font-weight:var(--fw-b)}
.ai-tag{
display:inline-block;margin-left:var(--sp-1);padding:0 var(--sp-1);border-radius:var(--r-xs);
background:var(--blue-soft);color:var(--blue-ink);font-size:var(--fs-cap);font-weight:var(--fw-b);vertical-align:1rpx;
}
.pu-s{font-size:var(--fs-sm);color:var(--muted)}
.post-content{font-size:var(--fs-md);line-height:1.62;color:var(--text-2);margin-bottom:var(--sp-3)}
.photo-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12rpx;margin-bottom:24rpx}
.photo-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-1);margin-bottom:var(--sp-3)}
.photo-tile{
aspect-ratio:1;border-radius:32rpx;background:linear-gradient(135deg,#FFE6BA,#FFF8ED);
display:flex;align-items:center;justify-content:center;font-size:60rpx;
aspect-ratio:1;border-radius:var(--r-sm);background:var(--primary-soft);
display:flex;align-items:center;justify-content:center;font-size:56rpx;
}
.post-actions{display:flex;justify-content:space-around;border-top:1rpx solid var(--line);padding-top:20rpx}
.pa-btn{color:var(--muted);font-weight:900;font-size:26rpx}
.pa-btn.liked{color:var(--red)}
.empty-hint{text-align:center;color:var(--muted);font-size:26rpx;padding:80rpx 0}
/* 页面不自身滚动,改由 page-scroll 承载滚动(隐藏滚动条)*/
/* 帖子分享按钮:用微信原生 open-type=share,需抹掉 button 默认外观 */
.pa-share{
background:transparent;border:none;padding:0;margin:0;line-height:inherit;
font-size:26rpx;font-weight:900;color:var(--muted);
.post-actions{display:flex;justify-content:space-around;border-top:1rpx solid var(--line);padding-top:var(--sp-3)}
.pa-btn{
display:flex;align-items:center;gap:var(--sp-1);
color:var(--muted);font-weight:var(--fw-b);font-size:var(--fs-sm);
}
.pa-btn.liked{color:var(--red-ink)}
/* 分享用微信原生 open-type=share,得抹掉 button 默认外观 */
.pa-share{background:transparent;border:none;padding:0;margin:0;line-height:inherit;height:auto}
.pa-share::after{border:none}
/* 关注按钮 */
.follow-btn{
flex:none;font-size:22rpx;font-weight:700;padding:6rpx 18rpx;border-radius:999rpx;
color:var(--primary-dark);background:#FFF2DC;border:1rpx solid #FFD39A;
flex:none;font-size:var(--fs-cap);font-weight:var(--fw-b);padding:6rpx var(--sp-3);border-radius:var(--r-full);
color:var(--primary-dark);background:var(--primary-soft);border:1rpx solid var(--primary-line);
}
.follow-btn.on{color:var(--muted);background:#F4F1EC;border-color:var(--line)}
.retry-btn{margin-top:20rpx;display:inline-block;padding:12rpx 36rpx;border-radius:999rpx;background:#FFF2DC;color:var(--primary-dark);font-weight:700;font-size:26rpx}
.retry-btn{
margin-top:var(--sp-3);display:inline-block;padding:var(--sp-2) var(--sp-6);border-radius:var(--r-full);
background:var(--primary-soft);color:var(--primary-dark);font-weight:var(--fw-b);font-size:var(--fs-sm);
}