更新输入框边距规范,增加资源对接弹窗的布局修正,确保在小程序开发中避免文字贴边问题。补充相关口诀以提升开发一致性,并在经验清单中记录最新最佳实践。调整项目索引以反映最新进展,增强文档的可用性与可追溯性。
This commit is contained in:
@@ -58,6 +58,9 @@ Page({
|
||||
showNicknameModal: false,
|
||||
editingNickname: '',
|
||||
|
||||
// 头像弹窗(含 chooseAvatar 按钮,必须用户点击才可获取微信头像)
|
||||
showAvatarModal: false,
|
||||
|
||||
// 手机/微信号弹窗(stitch_soul comprehensive_profile_editor_v1_2)
|
||||
showContactModal: false,
|
||||
contactPhone: '',
|
||||
@@ -290,11 +293,11 @@ Page({
|
||||
wx.showToast({ title: '已刷新', icon: 'success' })
|
||||
},
|
||||
|
||||
// 微信原生获取头像(button open-type="chooseAvatar" 回调)
|
||||
// 微信原生获取头像(button open-type="chooseAvatar" 回调,真正获取微信头像)
|
||||
async onChooseAvatar(e) {
|
||||
const tempAvatarUrl = e.detail.avatarUrl
|
||||
const tempAvatarUrl = e.detail?.avatarUrl
|
||||
this.setData({ showAvatarModal: false })
|
||||
if (!tempAvatarUrl) return
|
||||
|
||||
wx.showLoading({ title: '上传中...', mask: true })
|
||||
|
||||
try {
|
||||
@@ -659,32 +662,59 @@ Page({
|
||||
} catch (e) { console.log('[My] VIP查询失败', e) }
|
||||
},
|
||||
|
||||
// 头像点击:已登录弹出选项(改头像/进VIP)
|
||||
// 头像点击:已登录弹出选项(微信头像 / 相册 / VIP)
|
||||
onAvatarTap() {
|
||||
if (!this.data.isLoggedIn) { this.showLogin(); return }
|
||||
wx.showActionSheet({
|
||||
itemList: ['获取微信头像', '开通/管理VIP'],
|
||||
itemList: ['获取微信头像', '从相册选择', '开通/管理VIP'],
|
||||
success: (res) => {
|
||||
if (res.tapIndex === 0) this.chooseAvatarFallback()
|
||||
if (res.tapIndex === 1) this.goToVip()
|
||||
if (res.tapIndex === 0) this.setData({ showAvatarModal: true })
|
||||
if (res.tapIndex === 1) this.chooseAvatarFromAlbum()
|
||||
if (res.tapIndex === 2) this.goToVip()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
chooseAvatarFallback() {
|
||||
closeAvatarModal() {
|
||||
this.setData({ showAvatarModal: false })
|
||||
},
|
||||
|
||||
// 从相册/相机选择(自定义图片)
|
||||
chooseAvatarFromAlbum() {
|
||||
wx.chooseMedia({
|
||||
count: 1, mediaType: ['image'], sourceType: ['album', 'camera'],
|
||||
success: async (res) => {
|
||||
const tempPath = res.tempFiles[0].tempFilePath
|
||||
const userInfo = this.data.userInfo
|
||||
userInfo.avatar = tempPath
|
||||
this.setData({ userInfo })
|
||||
app.globalData.userInfo = userInfo
|
||||
wx.setStorageSync('userInfo', userInfo)
|
||||
wx.showLoading({ title: '上传中...', mask: true })
|
||||
try {
|
||||
await app.request('/api/miniprogram/user/update', { method: 'POST', data: { userId: userInfo.id, avatar: tempPath } })
|
||||
} catch (e) { console.log('头像同步失败', e) }
|
||||
wx.showToast({ title: '头像已更新', icon: 'success' })
|
||||
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 data = JSON.parse(r.data)
|
||||
data.success ? resolve(data) : reject(new Error(data.error || '上传失败'))
|
||||
} catch (e) { reject(new Error('解析失败')) }
|
||||
},
|
||||
fail: (e) => reject(e)
|
||||
})
|
||||
})
|
||||
const avatarUrl = app.globalData.baseUrl + uploadRes.data.url
|
||||
const userInfo = this.data.userInfo
|
||||
userInfo.avatar = avatarUrl
|
||||
this.setData({ userInfo })
|
||||
app.globalData.userInfo = userInfo
|
||||
wx.setStorageSync('userInfo', userInfo)
|
||||
await app.request('/api/miniprogram/user/update', { method: 'POST', data: { userId: userInfo.id, avatar: avatarUrl } })
|
||||
wx.hideLoading()
|
||||
wx.showToast({ title: '头像已更新', icon: 'success' })
|
||||
} catch (e) {
|
||||
wx.hideLoading()
|
||||
wx.showToast({ title: e.message || '上传失败,请重试', icon: 'none' })
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -186,6 +186,17 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 头像弹窗:必须点击 button 才能获取微信头像(隐私规范) -->
|
||||
<view class="modal-overlay" wx:if="{{showAvatarModal}}" bindtap="closeAvatarModal">
|
||||
<view class="modal-content avatar-modal" catchtap="stopPropagation">
|
||||
<view class="modal-close" bindtap="closeAvatarModal">✕</view>
|
||||
<text class="avatar-modal-title">获取微信头像</text>
|
||||
<text class="avatar-modal-desc">点击下方按钮使用你的微信头像</text>
|
||||
<button class="btn-choose-avatar" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">使用微信头像</button>
|
||||
<view class="avatar-modal-cancel" bindtap="closeAvatarModal">取消</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改昵称弹窗 -->
|
||||
<view class="modal-overlay" wx:if="{{showNicknameModal}}" bindtap="closeNicknameModal">
|
||||
<view class="modal-content nickname-modal" catchtap="stopPropagation">
|
||||
|
||||
@@ -3,14 +3,20 @@
|
||||
* 设计稿:primary #4FD1C5, vip-gold #C8A146, card-dark #1A1A1A, card-inner #252525
|
||||
*/
|
||||
|
||||
.page { min-height: 100vh; background: #121212; padding-bottom: 220rpx; }
|
||||
/* 真机适配:底部留足 TabBar + 安全区,避免「我的订单」被遮挡 */
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: #121212;
|
||||
padding-bottom: calc(220rpx + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
/* ===== 导航栏 ===== */
|
||||
/* ===== 导航栏(避让右上角系统胶囊) ===== */
|
||||
.nav-bar {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||||
background: rgba(18,18,18,0.9); backdrop-filter: blur(8rpx);
|
||||
display: flex; align-items: center;
|
||||
min-height: 44px; padding: 0 32rpx;
|
||||
min-height: 44px;
|
||||
padding: 0 200rpx 0 32rpx; /* 右侧 200rpx 避让真机右上角胶囊 */
|
||||
border-bottom: 1rpx solid rgba(255,255,255,0.05);
|
||||
}
|
||||
.nav-title { font-size: 40rpx; font-weight: bold; color: #4FD1C5; }
|
||||
@@ -155,6 +161,18 @@
|
||||
.agree-link { color: #4FD1C5; text-decoration: underline; padding: 0 4rpx; }
|
||||
.btn-wechat-disabled { opacity: 0.6; }
|
||||
|
||||
/* 头像弹窗 */
|
||||
.avatar-modal .avatar-modal-title { display: block; font-size: 36rpx; font-weight: bold; color: #fff; text-align: center; margin-bottom: 16rpx; }
|
||||
.avatar-modal .avatar-modal-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.6); text-align: center; margin-bottom: 32rpx; }
|
||||
.avatar-modal .btn-choose-avatar {
|
||||
width: 100%; height: 88rpx; margin: 0 0 24rpx 0; padding: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: #4FD1C5; color: #000; font-size: 30rpx; font-weight: 600;
|
||||
border-radius: 44rpx; border: none;
|
||||
}
|
||||
.avatar-modal .btn-choose-avatar::after { border: none; }
|
||||
.avatar-modal .avatar-modal-cancel { display: block; text-align: center; font-size: 28rpx; color: rgba(255,255,255,0.5); padding: 16rpx; }
|
||||
|
||||
/* 手机/微信号弹窗 */
|
||||
.contact-modal-overlay { background: rgba(0,0,0,0.85); backdrop-filter: blur(8rpx); }
|
||||
.contact-modal { width: 90%; max-width: 600rpx; background: #1A1A1A; border-radius: 48rpx; padding: 48rpx 40rpx; border: 1rpx solid rgba(255,255,255,0.1); }
|
||||
@@ -181,4 +199,5 @@
|
||||
.modal-btn-cancel { background: rgba(255,255,255,0.1); color: #fff; }
|
||||
.modal-btn-confirm { background: #4FD1C5; color: #000; font-weight: 600; }
|
||||
|
||||
.bottom-space { height: 80rpx; }
|
||||
/* 底部留白:配合 page padding-bottom,避免内容被 TabBar 遮挡 */
|
||||
.bottom-space { height: calc(80rpx + env(safe-area-inset-bottom, 0px)); }
|
||||
|
||||
Reference in New Issue
Block a user