更新小程序开发文档,新增2026-03-03的最佳实践记录,优化个人中心类页面的卡片区边距规范,确保一致性与可用性。调整相关页面以反映最新设计稿,提升用户体验与功能一致性。

This commit is contained in:
Alex-larget
2026-03-04 19:06:06 +08:00
parent 7064f82126
commit 5a5f0087d2
66 changed files with 2555 additions and 1059 deletions

View File

@@ -7,23 +7,15 @@ const app = getApp()
Page({
data: {
statusBarHeight: 44,
authorLoading: true,
author: {
name: '卡若',
avatar: 'K',
title: 'Soul派对房主理人 · 私域运营专家',
bio: '每天早上6点到9点在Soul派对房分享真实的创业故事。专注私域运营与项目变现用"云阿米巴"模式帮助创业者构建可持续的商业体系。本书记录了62个真实商业案例涵盖电商、内容、传统行业等多个领域。',
stats: [
{ label: '商业案例', value: '62' },
{ label: '连续直播', value: '365天' },
{ label: '派对分享', value: '1000+' }
],
// 联系方式已移至后台配置
contact: null,
highlights: [
'5年私域运营经验',
'帮助100+品牌从0到1增长',
'连续创业者,擅长商业模式设计'
]
avatarImg: '/assets/images/author-avatar.png',
title: '',
bio: '',
stats: [],
highlights: []
},
bookInfo: {
title: '一场Soul的创业实验',
@@ -44,22 +36,68 @@ Page({
this.setData({
statusBarHeight: app.globalData.statusBarHeight
})
this.loadAuthor()
this.loadBookStats()
},
async loadAuthor() {
this.setData({ authorLoading: true })
try {
const res = await app.request({ url: '/api/miniprogram/about/author', silent: true })
if (res?.success && res.data) {
const d = res.data
let avatarImg = d.avatarImg || ''
if (avatarImg && !avatarImg.startsWith('http')) {
const base = (app.globalData.baseUrl || '').replace(/\/$/, '')
avatarImg = base ? base + (avatarImg.startsWith('/') ? avatarImg : '/' + avatarImg) : avatarImg
}
this.setData({
author: {
name: d.name || '卡若',
avatar: d.avatar || 'K',
avatarImg: avatarImg || '/assets/images/author-avatar.png',
title: d.title || '',
bio: d.bio || '',
stats: Array.isArray(d.stats) ? d.stats : [
{ label: '商业案例', value: '62' },
{ label: '连续直播', value: '365天' },
{ label: '派对分享', value: '1000+' }
],
highlights: Array.isArray(d.highlights) ? d.highlights : []
},
authorLoading: false
})
} else {
this.setData({ authorLoading: false })
}
} catch (e) {
console.log('[About] 加载作者配置失败,使用默认')
this.setData({ authorLoading: false })
}
},
// 加载书籍统计
// 加载书籍统计(合并到作者统计第一项「商业案例」)
async loadBookStats() {
try {
const res = await app.request('/api/miniprogram/book/stats')
if (res && res.success) {
this.setData({
'bookInfo.totalChapters': res.data?.totalChapters || 62,
'author.stats': [
{ label: '商业案例', value: String(res.data?.totalChapters || 62) },
{ label: '连续直播', value: '365天' },
{ label: '派对分享', value: '1000+' }
]
})
const res = await app.request({ url: '/api/miniprogram/book/stats', silent: true })
if (res?.success && res.data) {
const total = res.data?.totalChapters || 62
this.setData({ 'bookInfo.totalChapters': total })
const stats = this.data.author?.stats || []
const idx = stats.findIndex((s) => s && (s.label === '商业案例' || s.label === '章节'))
if (idx >= 0 && stats[idx]) {
const next = [...stats]
next[idx] = { ...stats[idx], value: String(total) }
this.setData({ 'author.stats': next })
} else if (stats.length === 0) {
this.setData({
'author.stats': [
{ label: '商业案例', value: String(total) },
{ label: '连续直播', value: '365天' },
{ label: '派对分享', value: '1000+' }
]
})
}
}
} catch (e) {
console.log('[About] 加载书籍统计失败,使用默认值')

View File

@@ -8,9 +8,13 @@
<view style="height: {{statusBarHeight + 44}}px;"></view>
<view class="content">
<view wx:if="{{authorLoading}}" class="loading-row">加载中...</view>
<!-- 作者信息卡片 -->
<view class="author-card">
<view class="author-avatar">{{author.avatar}}</view>
<view class="author-card" wx:if="{{!authorLoading}}">
<view class="author-avatar-wrap">
<image wx:if="{{author.avatarImg}}" class="author-avatar-img" src="{{author.avatarImg}}" mode="aspectFill"/>
<view wx:else class="author-avatar">{{author.avatar}}</view>
</view>
<text class="author-name">{{author.name}}</text>
<text class="author-title">{{author.title}}</text>
<text class="author-bio">{{author.bio}}</text>
@@ -33,7 +37,7 @@
</view>
<!-- 书籍信息 -->
<view class="book-info-card" wx:if="{{bookInfo}}">
<view class="book-info-card" wx:if="{{bookInfo && !authorLoading}}">
<text class="card-title">📚 {{bookInfo.title}}</text>
<view class="book-stats">
<view class="book-stat">
@@ -58,7 +62,7 @@
</view>
<!-- 联系方式 - 引导到Soul派对房 -->
<view class="contact-card">
<view class="contact-card" wx:if="{{!authorLoading}}">
<text class="card-title">联系作者</text>
<view class="contact-item">
<text class="contact-icon">🎉</text>

View File

@@ -4,8 +4,11 @@
.nav-title { font-size: 36rpx; font-weight: 600; color: #00CED1; }
.nav-placeholder { width: 72rpx; }
.content { padding: 32rpx; }
.loading-row { text-align: center; color: rgba(255,255,255,0.6); font-size: 28rpx; padding: 48rpx 0; }
.author-card { background: linear-gradient(135deg, #1c1c1e 0%, #2c2c2e 100%); border-radius: 32rpx; padding: 48rpx; text-align: center; margin-bottom: 24rpx; border: 2rpx solid rgba(0,206,209,0.2); }
.author-avatar { width: 160rpx; height: 160rpx; border-radius: 50%; background: linear-gradient(135deg, #00CED1, #20B2AA); display: flex; align-items: center; justify-content: center; margin: 0 auto 24rpx; font-size: 64rpx; color: #fff; font-weight: 700; border: 4rpx solid rgba(0,206,209,0.3); }
.author-avatar-wrap { width: 160rpx; height: 160rpx; margin: 0 auto 24rpx; overflow: hidden; border-radius: 50%; border: 4rpx solid rgba(0,206,209,0.3); flex-shrink: 0; }
.author-avatar-img { width: 100%; height: 100%; display: block; }
.author-avatar { width: 100%; height: 100%; border-radius: 50%; background: linear-gradient(135deg, #00CED1, #20B2AA); display: flex; align-items: center; justify-content: center; font-size: 64rpx; color: #fff; font-weight: 700; }
.author-name { font-size: 40rpx; font-weight: 700; color: #fff; display: block; margin-bottom: 8rpx; }
.author-title { font-size: 26rpx; color: #00CED1; display: block; margin-bottom: 24rpx; }
.author-bio { font-size: 26rpx; color: rgba(255,255,255,0.7); line-height: 1.8; display: block; margin-bottom: 32rpx; }