feat: enhance login modal and avatar selection process

- Updated the login modal to include a user agreement section with clickable links to the user agreement and privacy policy.
- Improved button styling and layout for better user experience.
- Refactored avatar selection process to utilize local image paths, enhancing compatibility and reliability across different environments.
- Added utility functions for resolving avatar file paths and selecting images from the gallery or camera.

This update aims to streamline user interactions during login and avatar selection, ensuring a smoother experience.
This commit is contained in:
乘风
2026-05-06 17:21:10 +08:00
parent 5a88e87654
commit c78a0d531f
49 changed files with 5460 additions and 492 deletions

View File

@@ -198,6 +198,108 @@ const toAvatarPath = url => {
return url
}
/**
* chooseAvatar 返回的 avatarUrl 常为 http(s)://tmp/... ,渲染层可用的临时路径,但 wx.uploadFile 需本地文件路径。
* 约定:网络地址先 wx.downloadFile 得到 tempFilePath已是 wxfile:// 则直接上传。
*
* @param {string} avatarUrl
* @returns {Promise<string>}
*/
function resolveChooseAvatarFilePath(avatarUrl) {
return new Promise((resolve, reject) => {
if (!avatarUrl || typeof avatarUrl !== 'string') {
reject(new Error('无效的头像路径'))
return
}
const trimmed = avatarUrl.trim()
if (!trimmed) {
reject(new Error('无效的头像路径'))
return
}
if (trimmed.startsWith('wxfile://')) {
resolve(trimmed)
return
}
if (/^https?:\/\//i.test(trimmed)) {
wx.downloadFile({
url: trimmed,
success: res => {
if (res.statusCode === 200 && res.tempFilePath) resolve(res.tempFilePath)
else {
wx.getImageInfo({
src: trimmed,
success: img => {
if (img.path) resolve(img.path)
else reject(new Error('图片获取失败'))
},
fail: () => reject(new Error('图片获取失败')),
})
}
},
fail: () => {
wx.getImageInfo({
src: trimmed,
success: img => {
if (img.path) resolve(img.path)
else reject(new Error('图片获取失败'))
},
fail: () => reject(new Error('图片获取失败')),
})
},
})
return
}
resolve(trimmed)
})
}
/**
* 相册/相机选头像用本地路径(供 wx.uploadFile避开开发者工具里 chooseAvatar → http://tmp 渲染失败。
* 优先 chooseMedia低版本兜底 chooseImage。
* @returns {Promise<string>}
*/
function pickLocalAvatarImagePath() {
return new Promise((resolve, reject) => {
const fail = err => {
const em = (err && (err.errMsg || err.message)) || ''
const s = String(em)
if (s.includes('cancel') || s.includes('取消')) reject(Object.assign(err || {}, { cancelled: true }))
else reject(err || new Error('选择图片失败'))
}
if (typeof wx.chooseMedia === 'function') {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
sizeType: ['compressed'],
success: res => {
const files = res.tempFiles || []
const p = files[0] && files[0].tempFilePath
if (p) resolve(p)
else reject(new Error('未选择图片'))
},
fail,
})
return
}
if (typeof wx.chooseImage === 'function') {
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: res => {
const arr = res.tempFilePaths || []
if (arr[0]) resolve(arr[0])
else reject(new Error('未选择图片'))
},
fail,
})
return
}
reject(new Error('当前环境不支持选择图片'))
})
}
module.exports = {
formatTime,
formatDate,
@@ -217,5 +319,7 @@ module.exports = {
showLoading,
hideLoading,
showConfirm,
toAvatarPath
toAvatarPath,
resolveChooseAvatarFilePath,
pickLocalAvatarImagePath,
}