更新小程序开发文档,新增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

@@ -21,7 +21,6 @@ Page({
{ title: '链接资源', desc: '深度私域资源池', icon: '🔗' },
{ title: '专属VIP标识', desc: '金色尊享光圈', icon: '✓' }
],
profile: { vipName: '', vipProject: '', vipContact: '', vipAvatar: '', vipBio: '' },
purchasing: false
},
@@ -49,62 +48,10 @@ Page({
expireDateStr: expStr,
price: d.price || 1980
})
if (d.isVip) this.loadProfile(userId)
}
} catch (e) { console.log('[VIP] 加载失败', e) }
},
async loadProfile(userId) {
try {
const res = await app.request(`/api/miniprogram/vip/profile?userId=${userId}`)
if (res?.success) {
const p = res.data
// 头像若为相对路径则补全
if (p.vipAvatar && !p.vipAvatar.startsWith('http')) {
p.vipAvatar = app.globalData.baseUrl.replace(/\/$/, '') + (p.vipAvatar.startsWith('/') ? p.vipAvatar : '/' + p.vipAvatar)
}
this.setData({ profile: p })
}
} catch (e) { console.log('[VIP] 资料加载失败', e) }
},
async onChooseVipAvatar() {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: async (res) => {
const tempPath = res.tempFiles[0].tempFilePath
wx.showLoading({ title: '上传中...', mask: true })
try {
const uploadRes = await new Promise((resolve, reject) => {
wx.uploadFile({
url: app.globalData.baseUrl + '/api/miniprogram/upload',
filePath: tempPath,
name: 'file',
formData: { folder: 'avatars' },
success: (r) => {
try {
const d = JSON.parse(r.data)
d.success ? resolve(d) : reject(new Error(d.error || '上传失败'))
} catch { reject(new Error('解析失败')) }
},
fail: reject
})
})
const path = uploadRes.url || uploadRes.data?.url || ''
const avatarUrl = path.startsWith('http') ? path : (app.globalData.baseUrl.replace(/\/$/, '') + (path.startsWith('/') ? path : '/' + path))
this.setData({ 'profile.vipAvatar': avatarUrl })
wx.hideLoading()
wx.showToast({ title: '头像已更新', icon: 'success' })
} catch (e) {
wx.hideLoading()
wx.showToast({ title: e.message || '上传失败', icon: 'none' })
}
}
})
},
async handlePurchase() {
let userId = app.globalData.userInfo?.id
let openId = app.globalData.openId || app.globalData.userInfo?.open_id
@@ -156,24 +103,6 @@ Page({
} finally { this.setData({ purchasing: false }) }
},
onVipNameInput(e) { this.setData({ 'profile.vipName': e.detail.value }) },
onVipProjectInput(e) { this.setData({ 'profile.vipProject': e.detail.value }) },
onVipContactInput(e) { this.setData({ 'profile.vipContact': e.detail.value }) },
onVipBioInput(e) { this.setData({ 'profile.vipBio': e.detail.value }) },
async saveProfile() {
const userId = app.globalData.userInfo?.id
if (!userId) return
const p = this.data.profile
try {
const res = await app.request('/api/miniprogram/vip/profile', {
method: 'POST', data: { userId, vipName: p.vipName, vipProject: p.vipProject, vipContact: p.vipContact, vipAvatar: p.vipAvatar, vipBio: p.vipBio }
})
if (res?.success) wx.showToast({ title: '资料已保存', icon: 'success' })
else wx.showToast({ title: res?.error || '保存失败', icon: 'none' })
} catch (e) { wx.showToast({ title: '保存失败', icon: 'none' }) }
},
goBack() { wx.navigateBack() },
onShareAppMessage() {

View File

@@ -8,14 +8,10 @@
<view class="nav-placeholder-r"></view>
</view>
<view style="height: {{statusBarHeight + 44}}px;"></view>
<!-- 会员宣传区 - 设计稿 premium 卡片 -->
<!-- 会员宣传区(已去掉 VIP PREMIUM 标签) -->
<view class="vip-hero {{isVip ? 'vip-hero-active' : ''}}">
<text class="vip-hero-tag">VIP PREMIUM</text>
<text class="vip-hero-title">
加入卡若的
<text class="gold">创业派对</text>
会员
</text>
<view class="vip-hero-title">加入卡若的</view>
<view class="vip-hero-title gold">创业派对 会员</view>
<text class="vip-hero-sub" wx:if="{{isVip}}">有效期至 {{expireDateStr}}(剩余{{daysRemaining}}天)</text>
<text class="vip-hero-sub" wx:else>一次加入 尊享终身陪伴与成长</text>
</view>
@@ -54,47 +50,6 @@
{{purchasing ? "处理中..." : "¥" + price + "/年 加入创业派对"}}
</view>
</view>
<view class="bottom-spacer" wx:if="{{!isVip}}"></view>
<!-- VIP资料填写仅VIP可见 -->
<view class="profile-card" wx:if="{{isVip}}">
<text class="profile-title">会员资料(展示在创业老板排行)</text>
<view class="avatar-row">
<view class="avatar-label">头像</view>
<view class="avatar-slot" bindtap="onChooseVipAvatar">
<image wx:if="{{profile.vipAvatar}}" class="avatar-img" src="{{profile.vipAvatar}}" mode="aspectFill"/>
<view wx:else class="avatar-placeholder">
<text class="avatar-add">+</text>
<text class="avatar-hint">上传头像</text>
</view>
</view>
</view>
<view class="form-group">
<text class="form-label">姓名</text>
<view class="form-input">
<input type="nickname" placeholder="您的真实姓名" placeholder-class="form-placeholder" value="{{profile.vipName}}" bindinput="onVipNameInput" />
</view>
</view>
<view class="form-group">
<text class="form-label">项目名称</text>
<view class="form-input">
<input placeholder="您的项目/公司名称" placeholder-class="form-placeholder" value="{{profile.vipProject}}" bindinput="onVipProjectInput" />
</view>
</view>
<view class="form-group">
<text class="form-label">联系方式</text>
<view class="form-input">
<input placeholder="微信号或手机号" placeholder-class="form-placeholder" value="{{profile.vipContact}}" bindinput="onVipContactInput" />
</view>
</view>
<view class="form-group">
<text class="form-label">一句话简介</text>
<view class="form-input">
<input placeholder="简要描述您的业务" placeholder-class="form-placeholder" value="{{profile.vipBio}}" bindinput="onVipBioInput" />
</view>
</view>
<view class="save-btn-wrap">
<button class="save-btn" bindtap="saveProfile">保存资料</button>
</view>
</view>
<view class="bottom-space"></view>
</view>

View File

@@ -8,7 +8,7 @@
.vip-hero { margin: 24rpx; padding: 48rpx 32rpx; border-radius: 24rpx; background: linear-gradient(135deg, rgba(0,206,209,0.08), rgba(255,215,0,0.06)); border: 1rpx solid rgba(0,206,209,0.2); }
.vip-hero-active { border-color: rgba(255,215,0,0.4); background: linear-gradient(135deg, rgba(255,215,0,0.15), rgba(0,206,209,0.08)); }
.vip-hero-tag { display: inline-block; background: rgba(0,206,209,0.15); color: #00CED1; font-size: 22rpx; padding: 6rpx 16rpx; border-radius: 16rpx; margin-bottom: 20rpx; }
.vip-hero-title { display: block; font-size: 44rpx; font-weight: bold; color: #fff; margin-top: 12rpx; }
.vip-hero-title { display: block; font-size: 44rpx; font-weight: bold; color: #fff; }
.gold { color: #FFD700; }
.vip-hero-sub { display: block; font-size: 24rpx; color: rgba(255,255,255,0.5); margin-top: 12rpx; }