feat: 登录的时候上传头像和微信名
This commit is contained in:
parent
0baa476aee
commit
c25e4ed02c
@ -40,10 +40,19 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="auth-title">申请获取以下权限</view>
|
<view class="auth-title">申请获取以下权限</view>
|
||||||
<view class="auth-subtitle">获得你的公开信息(昵称、头像等)</view>
|
<view class="auth-subtitle">获得你的公开信息(昵称、头像、手机号等)</view>
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<view class="login-btn">
|
||||||
|
<button class="button" open-type="getPhoneNumber" @getphonenumber="handleLoginWithPhone" @click="clickPhoneNumber" :class="{ disabled }">
|
||||||
|
一键登录
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
<view class="login-btn">
|
<view class="login-btn">
|
||||||
<view class="button" :class="{ disabled }" @click="handleLogin()">一键登录</view>
|
<view class="button" :class="{ disabled }" @click="handleLogin()">一键登录</view>
|
||||||
</view>
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
<view class="no-login-btn">
|
<view class="no-login-btn">
|
||||||
<view class="button" @click="handleCancel()">暂不登录</view>
|
<view class="button" @click="handleCancel()">暂不登录</view>
|
||||||
</view>
|
</view>
|
||||||
@ -53,10 +62,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import * as LoginApi from '@/api/login'
|
|
||||||
import * as UploadApi from '@/api/upload'
|
|
||||||
import AvatarImage from '@/components/avatar-image'
|
import AvatarImage from '@/components/avatar-image'
|
||||||
import * as Verify from '@/utils/verify'
|
import * as Verify from '@/utils/verify'
|
||||||
|
import * as OrderApi from '@/api/order'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -74,17 +82,66 @@
|
|||||||
tempFile: undefined,
|
tempFile: undefined,
|
||||||
// 表单数据
|
// 表单数据
|
||||||
form: {
|
form: {
|
||||||
avatarId: null,
|
|
||||||
nickName: ''
|
nickName: ''
|
||||||
},
|
},
|
||||||
|
// 手机号加密数据
|
||||||
|
phoneEncryptedData: '',
|
||||||
|
phoneIv: '',
|
||||||
|
// 微信小程序登录凭证 (code)
|
||||||
|
// 提交到后端,用于换取openid
|
||||||
|
code: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// 一键登录按钮点击事件
|
// 一键登录按钮点击事件(非微信小程序环境)
|
||||||
handleLogin() {
|
handleLogin() {
|
||||||
this.onAuthSuccess({})
|
this.onAuthSuccess({})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 按钮点击事件: 获取微信手机号按钮
|
||||||
|
// 实现目的: 在getphonenumber事件触发之前获取微信登录code
|
||||||
|
// 因为如果在getphonenumber事件中获取code的话,提交到后端的encryptedData会存在解密不了的情况
|
||||||
|
async clickPhoneNumber() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (!this.disabled) {
|
||||||
|
this.code = await this.getCode()
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
// 微信小程序一键登录(带手机号授权)
|
||||||
|
async handleLoginWithPhone({ detail }) {
|
||||||
|
const app = this
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 处理手机号授权
|
||||||
|
if (detail.errMsg === 'getPhoneNumber:ok') {
|
||||||
|
// 获取手机号成功
|
||||||
|
app.phoneEncryptedData = detail.encryptedData
|
||||||
|
app.phoneIv = detail.iv
|
||||||
|
console.log('获取手机号成功', {
|
||||||
|
hasEncryptedData: !!detail.encryptedData,
|
||||||
|
hasIv: !!detail.iv,
|
||||||
|
hasCode: !!app.code
|
||||||
|
})
|
||||||
|
|
||||||
|
// 准备用户信息数据,包含手机号加密信息
|
||||||
|
let userInfo = {
|
||||||
|
phoneEncryptedData: detail.encryptedData,
|
||||||
|
phoneIv: detail.iv,
|
||||||
|
nickName: '',
|
||||||
|
avatarUrl: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行登录,将手机号信息传递给后端
|
||||||
|
app.onAuthSuccess(userInfo)
|
||||||
|
} else {
|
||||||
|
// 用户拒绝授权手机号
|
||||||
|
console.log('用户拒绝授权手机号', detail)
|
||||||
|
app.$toast('为了更好的体验,请授权手机号再登录')
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
// 授权成功事件
|
// 授权成功事件
|
||||||
// 这里分为两个逻辑:
|
// 这里分为两个逻辑:
|
||||||
// 1.将code和userInfo提交到后端,如果存在该用户 则实现自动登录,无需再填写手机号
|
// 1.将code和userInfo提交到后端,如果存在该用户 则实现自动登录,无需再填写手机号
|
||||||
@ -92,22 +149,51 @@
|
|||||||
// 3.如果后端报错了, 则显示错误信息
|
// 3.如果后端报错了, 则显示错误信息
|
||||||
async onAuthSuccess(userInfo) {
|
async onAuthSuccess(userInfo) {
|
||||||
const app = this
|
const app = this
|
||||||
|
// 如果还没有获取code,则获取code
|
||||||
// 提交到后端
|
// 提交到后端
|
||||||
const code = await app.getCode()
|
if (!app.code) {
|
||||||
store.dispatch('LoginMpWx', { code })
|
app.code = await app.getCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备登录数据,包含手机号、昵称和头像信息
|
||||||
|
const loginData = {
|
||||||
|
code: app.code,
|
||||||
|
phoneEncryptedData: userInfo.phoneEncryptedData || '',
|
||||||
|
phoneIv: userInfo.phoneIv || '',
|
||||||
|
nickName: userInfo.nickName || '',
|
||||||
|
avatarUrl: userInfo.avatarUrl || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('登录数据:', {
|
||||||
|
hasCode: !!loginData.code,
|
||||||
|
hasPhoneNumber: !!(loginData.phoneEncryptedData && loginData.phoneIv),
|
||||||
|
nickName: loginData.nickName,
|
||||||
|
hasAvatar: !!(loginData.avatarUrl)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 按钮禁用
|
||||||
|
app.disabled = true
|
||||||
|
|
||||||
|
store.dispatch('LoginMpWx', loginData)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
// 一键登录成功
|
app.disabled = false
|
||||||
app.$toast('登录成功')
|
if (!result.data.buyer.avatarUrl) {
|
||||||
// 相应全局事件订阅: 刷新上级页面数据
|
app.isPersonal = true
|
||||||
uni.$emit('syncRefresh', true)
|
} else {
|
||||||
// 跳转回原页面
|
app.$toast('登录成功')
|
||||||
setTimeout(() => app.onNavigateBack(), 2000)
|
uni.$emit('syncRefresh', true)
|
||||||
|
setTimeout(() => app.onNavigateBack(), 2000)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
const resultData = err.result.data
|
const resultData = err.result?.data || {}
|
||||||
// 判断还需绑定手机号
|
// 判断还需绑定手机号
|
||||||
if (resultData.isBindMobile) {
|
if (resultData.isBindMobile) {
|
||||||
app.onEmitSuccess(userInfo)
|
app.onEmitSuccess(userInfo)
|
||||||
|
} else {
|
||||||
|
// 其他错误,恢复按钮状态
|
||||||
|
app.disabled = false
|
||||||
|
app.code = '' // 重置code,下次重新获取
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -145,8 +231,64 @@
|
|||||||
onChooseAvatar({ detail }) {
|
onChooseAvatar({ detail }) {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
const app = this
|
const app = this
|
||||||
app.avatarUrl = detail.avatarUrl
|
console.log('onChooseAvatar', detail)
|
||||||
app.tempFile = { path: app.avatarUrl }
|
|
||||||
|
// chooseAvatar 返回的临时文件路径在开发者工具中可能无法直接访问
|
||||||
|
// 需要将临时文件保存到小程序文件系统中
|
||||||
|
const tempFilePath = detail.avatarUrl
|
||||||
|
|
||||||
|
// 先显示临时路径(用于预览)
|
||||||
|
app.avatarUrl = tempFilePath
|
||||||
|
|
||||||
|
// 将临时文件保存到小程序文件系统
|
||||||
|
// uni.saveFile 会将临时文件保存到小程序的文件系统中,返回一个可用的文件路径
|
||||||
|
uni.saveFile({
|
||||||
|
tempFilePath: tempFilePath,
|
||||||
|
success: (res) => {
|
||||||
|
// 保存成功,使用保存后的文件路径
|
||||||
|
const savedFilePath = res.savedFilePath
|
||||||
|
console.log('头像文件保存成功', savedFilePath)
|
||||||
|
app.avatarUrl = savedFilePath
|
||||||
|
app.tempFile = { path: savedFilePath }
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('头像文件保存失败', err)
|
||||||
|
// 如果保存失败,尝试使用文件系统管理器复制文件
|
||||||
|
// 在开发者工具中,临时文件可能无法访问,但真机上通常可以直接使用
|
||||||
|
try {
|
||||||
|
const fs = wx.getFileSystemManager()
|
||||||
|
// 使用小程序的用户数据目录(如果可用)
|
||||||
|
const userDataPath = wx.env && wx.env.USER_DATA_PATH
|
||||||
|
if (userDataPath) {
|
||||||
|
const timestamp = Date.now()
|
||||||
|
const random = Math.random().toString(36).substring(2, 8)
|
||||||
|
const destPath = `${userDataPath}/avatar_${timestamp}_${random}.jpg`
|
||||||
|
|
||||||
|
fs.copyFile({
|
||||||
|
srcPath: tempFilePath,
|
||||||
|
destPath: destPath,
|
||||||
|
success: (copyRes) => {
|
||||||
|
console.log('头像文件复制成功', destPath)
|
||||||
|
app.avatarUrl = destPath
|
||||||
|
app.tempFile = { path: destPath }
|
||||||
|
},
|
||||||
|
fail: (copyErr) => {
|
||||||
|
console.error('头像文件复制也失败', copyErr)
|
||||||
|
// 最后尝试直接使用临时路径(真机上通常可用)
|
||||||
|
app.tempFile = { path: tempFilePath }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 如果无法获取文件目录,直接使用临时路径(真机上通常可用)
|
||||||
|
app.tempFile = { path: tempFilePath }
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('文件处理异常', e)
|
||||||
|
// 最后尝试直接使用临时路径(真机上通常可用)
|
||||||
|
app.tempFile = { path: tempFilePath }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -168,9 +310,9 @@
|
|||||||
// 上传图片
|
// 上传图片
|
||||||
uploadFile() {
|
uploadFile() {
|
||||||
const app = this
|
const app = this
|
||||||
return UploadApi.image([app.tempFile], false)
|
return OrderApi.apiUploadFile([app.tempFile])
|
||||||
.then(fileIds => {
|
.then(res => {
|
||||||
app.form.avatarId = fileIds[0]
|
app.form.avatarUrl = res[0].data[0].url
|
||||||
app.tempFile = null
|
app.tempFile = null
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@ -199,7 +341,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 提交到后端
|
// 提交到后端
|
||||||
app.onAuthSuccess({ nickName: app.form.nickName, avatarId: app.form.avatarId })
|
app.onAuthSuccess({ nickName: app.form.nickName, avatarUrl: app.form.avatarUrl })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 将oauth提交给父级
|
// 将oauth提交给父级
|
||||||
@ -350,11 +492,19 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 86rpx;
|
||||||
|
|
||||||
// 禁用按钮
|
// 禁用按钮
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 微信小程序button组件样式重置
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user