feat: 添加退出登录与上传头像的逻辑

This commit is contained in:
fanpeng 2025-06-09 14:37:37 +08:00
parent d38a578c05
commit 056ccd463e
7 changed files with 204 additions and 130 deletions

View File

@ -136,3 +136,12 @@ export function getWebUrlRequest(data) {
data data
}) })
} }
// 退出登录
export function logoutRequest(data) {
return request({
url: '/v3/user/logout',
method: 'POST',
data
})
}

View File

@ -56,9 +56,14 @@
>切换环境</view >切换环境</view
> >
</view> </view>
<!-- #ifdef MP-WEIXIN -->
<label for="changePhone"> <label for="changePhone">
<view class="switch-account">切换账号</view> <view class="switch-account">切换账号</view>
</label> </label>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="switch-account !bg-red-500" @click="logout">退出</view>
<!-- #endif -->
</view> </view>
<view v-else> <view v-else>
<view class="tips">因智能门锁与账号绑定登录为手机号登录</view> <view class="tips">因智能门锁与账号绑定登录为手机号登录</view>
@ -105,7 +110,7 @@
import { useBasicStore } from '@/stores/basic' import { useBasicStore } from '@/stores/basic'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useLockStore } from '@/stores/lock' import { useLockStore } from '@/stores/lock'
import { phoneLoginRequest } from '@/api/user' import { phoneLoginRequest, logoutRequest } from '@/api/user'
import env from '@/config/env' import env from '@/config/env'
import { setStorage, getStorage, removeStorage } from '@/utils/storage' import { setStorage, getStorage, removeStorage } from '@/utils/storage'
import { useNotificationStore } from '@/stores/notification' import { useNotificationStore } from '@/stores/notification'
@ -260,6 +265,25 @@
type type
} }
}) })
},
logout() {
uni.showModal({
title: '提示',
content: '确定退出登录吗?',
success: async res => {
if (res.confirm) {
await logoutRequest()
removeStorage('token')
removeStorage('openid')
removeStorage('userInfo')
removeStorage('lockList')
this.routeJump({
name: 'login',
type: 'reLaunch'
})
}
}
})
} }
} }
} }

View File

@ -168,28 +168,27 @@
} }
.input-email { .input-email {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 616rpx; width: 616rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.button-verify { .button-verify {
margin-top: 48rpx;
height: 108rpx;
width: 265rpx; width: 265rpx;
line-height: 108rpx; height: 108rpx;
border-radius: 16rpx; margin-top: 48rpx;
text-align: center;
font-size: 32rpx;
margin-left: 35rpx; margin-left: 35rpx;
font-size: 32rpx;
background: #63b8af; line-height: 108rpx;
color: #ffffff; color: #ffffff;
text-align: center;
background: #63b8af;
border-radius: 16rpx;
} }
.view-top { .view-top {
@ -198,14 +197,14 @@
} }
.input-verify { .input-verify {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 316rpx; width: 316rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.input-placeholder { .input-placeholder {
@ -216,15 +215,15 @@
} }
.button { .button {
margin-top: 32rpx;
margin-left: 35rpx;
width: 680rpx; width: 680rpx;
height: 96rpx; height: 96rpx;
margin-top: 32rpx;
margin-left: 35rpx;
font-size: 32rpx;
line-height: 96rpx;
color: #ffffff;
text-align: center;
background: #63b8af; background: #63b8af;
border-radius: 16rpx; border-radius: 16rpx;
line-height: 96rpx;
text-align: center;
font-size: 32rpx;
color: #ffffff;
} }
</style> </style>

View File

@ -84,14 +84,14 @@
<style scoped lang="scss"> <style scoped lang="scss">
.input { .input {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 616rpx; width: 616rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.input-placeholder { .input-placeholder {
@ -102,15 +102,15 @@
} }
.button { .button {
margin-top: 32rpx;
margin-left: 35rpx;
width: 680rpx; width: 680rpx;
height: 96rpx; height: 96rpx;
margin-top: 32rpx;
margin-left: 35rpx;
font-size: 32rpx;
line-height: 96rpx;
color: #ffffff;
text-align: center;
background: #63b8af; background: #63b8af;
border-radius: 16rpx; border-radius: 16rpx;
line-height: 96rpx;
text-align: center;
font-size: 32rpx;
color: #ffffff;
} }
</style> </style>

View File

@ -145,14 +145,14 @@
<style scoped lang="scss"> <style scoped lang="scss">
.input { .input {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 616rpx; width: 616rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.input-placeholder { .input-placeholder {
@ -163,23 +163,23 @@
} }
.button { .button {
margin-top: 32rpx;
margin-left: 35rpx;
width: 680rpx; width: 680rpx;
height: 96rpx; height: 96rpx;
margin-top: 32rpx;
margin-left: 35rpx;
font-size: 32rpx;
line-height: 96rpx;
color: #ffffff;
text-align: center;
background: #63b8af; background: #63b8af;
border-radius: 16rpx; border-radius: 16rpx;
line-height: 96rpx;
text-align: center;
font-size: 32rpx;
color: #ffffff;
} }
.text-tips { .text-tips {
text-align: center;
margin-top: 32rpx; margin-top: 32rpx;
font-size: 28rpx; font-size: 28rpx;
color: #9b9b9b; color: #9b9b9b;
text-align: center;
} }
.view-top { .view-top {
@ -188,27 +188,26 @@
} }
.input-verify { .input-verify {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 316rpx; width: 316rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.button-verify { .button-verify {
margin-top: 48rpx;
height: 108rpx;
width: 265rpx; width: 265rpx;
line-height: 108rpx; height: 108rpx;
border-radius: 16rpx; margin-top: 48rpx;
text-align: center;
font-size: 32rpx;
margin-left: 35rpx; margin-left: 35rpx;
font-size: 32rpx;
background: #63b8af; line-height: 108rpx;
color: #ffffff; color: #ffffff;
text-align: center;
background: #63b8af;
border-radius: 16rpx;
} }
</style> </style>

View File

@ -1,6 +1,7 @@
<template> <template>
<view> <view>
<view class="view"> <view class="view">
<!-- #ifdef MP-WEIXIN -->
<label for="avatar"> <label for="avatar">
<view class="view-button"> <view class="view-button">
<view>头像</view> <view>头像</view>
@ -14,6 +15,22 @@
</view> </view>
</view> </view>
</label> </label>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view @click="chooseImage">
<view class="view-button">
<view>头像</view>
<view class="view-button" style="padding: 0">
<image class="avatar" :src="userInfo.headUrl" mode="aspectFill"></image>
<image
class="icon-arrow"
src="https://oss-lock.xhjcn.ltd/mp/icon_arrow.png"
mode="aspectFill"
></image>
</view>
</view>
</view>
<!-- #endif -->
<view class="view-line"></view> <view class="view-line"></view>
<view class="view-button" @click="toUpdateName"> <view class="view-button" @click="toUpdateName">
<view>昵称</view> <view>昵称</view>
@ -146,13 +163,33 @@
} }
this.pending = false this.pending = false
}, },
chooseImage() {
const that = this
uni.chooseImage({
count: 1,
sourceType: ['camera', 'album'],
crop: {
quality: 60,
width: 108,
height: 108
},
success: res => {
const data = res.tempFiles[0]
const list = data.path.split('/')
const filename = list[list.length - 1]
that.uploadRequest({
...data,
filename
})
}
})
},
chooseAvatar(e) { chooseAvatar(e) {
const that = this const that = this
if (that.pending) { if (that.pending) {
return return
} }
that.pending = true that.pending = true
const path = e.detail.avatarUrl const path = e.detail.avatarUrl
const list = path.split('/') const list = path.split('/')
const filename = list[list.length - 1] const filename = list[list.length - 1]
@ -160,58 +197,65 @@
filePath: path, filePath: path,
async success(res) { async success(res) {
const size = res.size const size = res.size
const { code, data } = await getUploadParamsRequest({ that.uploadRequest({
size, size,
module: 'avatar', filename,
userId: that.userInfo.userId, path
filename
}) })
if (code === 0) { }
uni.uploadFile({ })
url: data.uploadUrl, },
filePath: path, async uploadRequest(params) {
name: 'file', const that = this
formData: data.formData, const { code, data } = await getUploadParamsRequest({
async success() { size: params.size,
const { code: updateCode } = await updateUserInfoRequest({ module: 'avatar',
headUrl: data.fileUrl userId: that.userInfo.userId,
}) filename: params.filename
if (updateCode === 0) { })
that.updateUserInfo({ if (code === 0) {
...that.userInfo, uni.uploadFile({
headUrl: data.fileUrl url: data.uploadUrl,
}) filePath: params.path,
uni.showToast({ name: 'file',
title: '头像更新成功', formData: data.formData,
icon: 'none' async success() {
}) const { code: updateCode } = await updateUserInfoRequest({
} else { headUrl: data.fileUrl
uni.showToast({
title: '头像更新失败',
icon: 'none'
})
}
that.pending = false
},
fail(res) {
console.log('上传失败', res)
console.log(data.uploadUrl, path, data.formData)
uni.showToast({
title: '头像更新失败',
icon: 'none'
})
that.pending = false
}
}) })
} else { if (updateCode === 0) {
that.updateUserInfo({
...that.userInfo,
headUrl: data.fileUrl
})
uni.showToast({
title: '头像更新成功',
icon: 'none'
})
} else {
uni.showToast({
title: '头像更新失败',
icon: 'none'
})
}
that.pending = false
},
fail(res) {
console.log('上传失败', res)
uni.showToast({ uni.showToast({
title: '头像更新失败', title: '头像更新失败',
icon: 'none' icon: 'none'
}) })
that.pending = false that.pending = false
} }
} })
}) } else {
uni.showToast({
title: '头像更新失败',
icon: 'none'
})
that.pending = false
}
}, },
toUpdateName() { toUpdateName() {
this.routeJump({ this.routeJump({

View File

@ -122,17 +122,16 @@
} }
.button-verify { .button-verify {
margin-top: 48rpx;
height: 108rpx;
width: 265rpx; width: 265rpx;
line-height: 108rpx; height: 108rpx;
border-radius: 16rpx; margin-top: 48rpx;
text-align: center;
font-size: 32rpx;
margin-left: 35rpx; margin-left: 35rpx;
font-size: 32rpx;
background: #63b8af; line-height: 108rpx;
color: #ffffff; color: #ffffff;
text-align: center;
background: #63b8af;
border-radius: 16rpx;
} }
.view-top { .view-top {
@ -141,14 +140,14 @@
} }
.input { .input {
border-radius: 16rpx;
background: #ffffff;
margin-left: 35rpx;
margin-top: 48rpx;
height: 108rpx;
width: 316rpx; width: 316rpx;
padding-left: 32rpx; height: 108rpx;
padding-right: 32rpx; padding-right: 32rpx;
padding-left: 32rpx;
margin-top: 48rpx;
margin-left: 35rpx;
background: #ffffff;
border-radius: 16rpx;
} }
.input-placeholder { .input-placeholder {
@ -159,15 +158,15 @@
} }
.button { .button {
margin-top: 32rpx;
margin-left: 35rpx;
width: 680rpx; width: 680rpx;
height: 96rpx; height: 96rpx;
margin-top: 32rpx;
margin-left: 35rpx;
font-size: 32rpx;
line-height: 96rpx;
color: #ffffff;
text-align: center;
background: #63b8af; background: #63b8af;
border-radius: 16rpx; border-radius: 16rpx;
line-height: 96rpx;
text-align: center;
font-size: 32rpx;
color: #ffffff;
} }
</style> </style>