2025-08-16 09:28:04 +08:00
|
|
|
|
<template>
|
2025-08-16 10:39:19 +08:00
|
|
|
|
<view class="page">
|
|
|
|
|
|
<view class="info">
|
2025-08-20 10:03:06 +08:00
|
|
|
|
<view v-for="(item, index) in userInfoSettings" :key="index" class="info-row" @click="handleItemClick(item)">
|
2025-08-16 10:39:19 +08:00
|
|
|
|
<view class="label">{{ item.label }}</view>
|
2025-08-20 10:03:06 +08:00
|
|
|
|
<view class="value">
|
|
|
|
|
|
<image
|
|
|
|
|
|
v-if="item.type === 'avatar' && item.value"
|
|
|
|
|
|
:src="item.value"
|
|
|
|
|
|
class="avatar-preview"
|
|
|
|
|
|
mode="aspectFill"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<text v-else-if="item.type === 'avatar'">点击设置头像</text>
|
|
|
|
|
|
<text v-else>{{ item.value }}</text>
|
|
|
|
|
|
<text class="arrow">></text>
|
|
|
|
|
|
</view>
|
2025-08-16 10:39:19 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-08-19 16:01:22 +08:00
|
|
|
|
<view class="log-out" @click="handleLogout">退出登录</view>
|
2025-08-16 10:39:19 +08:00
|
|
|
|
</view>
|
2025-08-16 09:28:04 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
2025-08-16 10:39:19 +08:00
|
|
|
|
<script>
|
2025-08-19 16:01:22 +08:00
|
|
|
|
import { userLogout } from '@/api/auth/auth.js'
|
2025-08-20 10:03:06 +08:00
|
|
|
|
import { updateNickName } from '@/api/user/user.js'
|
2025-08-19 16:01:22 +08:00
|
|
|
|
import { clearToken } from '@/utils/request.js'
|
|
|
|
|
|
|
2025-08-16 10:39:19 +08:00
|
|
|
|
export default {
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
userInfoSettings: [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '头像',
|
2025-08-20 10:03:06 +08:00
|
|
|
|
value: '', // 头像URL,从个人中心传递过来
|
2025-08-16 10:39:19 +08:00
|
|
|
|
type: 'avatar',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '昵称',
|
|
|
|
|
|
value: '昵称', // 默认占位文字,实际应为用户昵称
|
|
|
|
|
|
type: 'nickname',
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-08-20 10:03:06 +08:00
|
|
|
|
onLoad() {
|
|
|
|
|
|
console.log('设置页面开始加载...')
|
|
|
|
|
|
console.log('初始userInfoSettings:', this.userInfoSettings)
|
|
|
|
|
|
|
|
|
|
|
|
// 页面加载时获取用户信息
|
|
|
|
|
|
this.loadUserInfo()
|
|
|
|
|
|
|
|
|
|
|
|
console.log('设置页面加载完成')
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
// 页面显示时重新加载用户信息,确保数据最新
|
|
|
|
|
|
this.loadUserInfo()
|
|
|
|
|
|
},
|
2025-08-18 17:34:18 +08:00
|
|
|
|
methods: {
|
2025-08-20 10:03:06 +08:00
|
|
|
|
// 加载用户信息
|
|
|
|
|
|
loadUserInfo() {
|
|
|
|
|
|
console.log('开始加载用户信息...')
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
|
|
|
|
console.log('从本地存储获取的用户信息:', userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
// 检查用户信息是否存在且格式正确
|
|
|
|
|
|
if (!userInfo) {
|
|
|
|
|
|
console.log('本地存储中没有用户信息')
|
|
|
|
|
|
this.setDefaultValues()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof userInfo !== 'object') {
|
|
|
|
|
|
console.log('用户信息格式不正确,不是对象类型')
|
|
|
|
|
|
this.setDefaultValues()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新昵称显示
|
|
|
|
|
|
const nicknameItem = this.userInfoSettings.find(item => item.type === 'nickname')
|
|
|
|
|
|
if (nicknameItem) {
|
|
|
|
|
|
const nickName = userInfo.nickName || userInfo.nickname || '昵称'
|
|
|
|
|
|
nicknameItem.value = nickName
|
|
|
|
|
|
console.log('设置昵称显示:', nickName)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新头像显示
|
|
|
|
|
|
const avatarItem = this.userInfoSettings.find(item => item.type === 'avatar')
|
|
|
|
|
|
if (avatarItem) {
|
|
|
|
|
|
const avatar = userInfo.avatar || ''
|
|
|
|
|
|
avatarItem.value = avatar
|
|
|
|
|
|
console.log('设置头像显示:', avatar)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('用户信息加载成功')
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('加载用户信息时发生错误:', error)
|
|
|
|
|
|
this.setDefaultValues()
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 设置默认值
|
|
|
|
|
|
setDefaultValues() {
|
|
|
|
|
|
console.log('设置默认值...')
|
|
|
|
|
|
|
|
|
|
|
|
const nicknameItem = this.userInfoSettings.find(item => item.type === 'nickname')
|
|
|
|
|
|
if (nicknameItem) {
|
|
|
|
|
|
nicknameItem.value = '昵称'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const avatarItem = this.userInfoSettings.find(item => item.type === 'avatar')
|
|
|
|
|
|
if (avatarItem) {
|
|
|
|
|
|
avatarItem.value = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('默认值设置完成')
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 处理设置项点击
|
|
|
|
|
|
handleItemClick(item) {
|
|
|
|
|
|
if (item.type === 'nickname') {
|
|
|
|
|
|
this.showNicknameInput()
|
|
|
|
|
|
} else if (item.type === 'avatar') {
|
|
|
|
|
|
// 头像修改逻辑可以在这里添加
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '头像修改功能开发中',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 显示昵称输入框
|
|
|
|
|
|
showNicknameInput() {
|
|
|
|
|
|
const currentNickname = this.userInfoSettings.find(item => item.type === 'nickname').value
|
|
|
|
|
|
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: '修改昵称',
|
|
|
|
|
|
content: '请输入新的昵称',
|
|
|
|
|
|
editable: true,
|
|
|
|
|
|
placeholderText: '请输入昵称',
|
|
|
|
|
|
confirmText: '确定',
|
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
|
success: async (res) => {
|
|
|
|
|
|
if (res.confirm && res.content) {
|
|
|
|
|
|
const newNickname = res.content.trim()
|
|
|
|
|
|
if (newNickname) {
|
|
|
|
|
|
await this.updateNickname(newNickname)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '昵称不能为空',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 更新昵称
|
|
|
|
|
|
async updateNickname(newNickname) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
title: '更新中...'
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const response = await updateNickName(newNickname)
|
|
|
|
|
|
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
|
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
|
// 更新本地显示
|
|
|
|
|
|
const nicknameItem = this.userInfoSettings.find(item => item.type === 'nickname')
|
|
|
|
|
|
if (nicknameItem) {
|
|
|
|
|
|
nicknameItem.value = newNickname
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新本地存储的用户信息
|
|
|
|
|
|
try {
|
|
|
|
|
|
const userInfo = uni.getStorageSync('userInfo') || {}
|
|
|
|
|
|
userInfo.nickName = newNickname
|
|
|
|
|
|
uni.setStorageSync('userInfo', userInfo)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('更新本地用户信息失败:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '昵称更新成功',
|
|
|
|
|
|
icon: 'success'
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 通知个人中心页面更新用户信息
|
|
|
|
|
|
try {
|
|
|
|
|
|
const userInfo = uni.getStorageSync('userInfo') || {}
|
|
|
|
|
|
uni.$emit('userInfoUpdated', {
|
|
|
|
|
|
nickName: newNickname,
|
|
|
|
|
|
avatar: userInfo.avatar || ''
|
|
|
|
|
|
})
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取用户信息失败:', error)
|
|
|
|
|
|
uni.$emit('userInfoUpdated', {
|
|
|
|
|
|
nickName: newNickname,
|
|
|
|
|
|
avatar: ''
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error(response.msg || '更新失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
console.error('更新昵称失败:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: error.message || '更新失败',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-08-19 16:01:22 +08:00
|
|
|
|
// 退出登录处理
|
|
|
|
|
|
async handleLogout() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 显示确认对话框
|
|
|
|
|
|
const res = await new Promise((resolve, reject) => {
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: '确认退出',
|
|
|
|
|
|
content: '确定要退出登录吗?',
|
|
|
|
|
|
confirmText: '确定',
|
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
|
success: resolve,
|
|
|
|
|
|
fail: reject
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (!res.confirm) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 调用退出登录API
|
|
|
|
|
|
const response = await userLogout()
|
|
|
|
|
|
|
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
|
// 清除本地token
|
|
|
|
|
|
clearToken()
|
|
|
|
|
|
|
|
|
|
|
|
// 清除用户信息
|
|
|
|
|
|
uni.removeStorageSync('userInfo')
|
|
|
|
|
|
|
|
|
|
|
|
// 显示成功提示
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '退出成功',
|
|
|
|
|
|
icon: 'success',
|
|
|
|
|
|
duration: 1500
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 延迟跳转到登录页
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
uni.reLaunch({
|
|
|
|
|
|
url: '/pages/login/login'
|
|
|
|
|
|
})
|
|
|
|
|
|
}, 1500)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error(response.msg || '退出失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('退出登录失败:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: error.message || '退出失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-18 17:34:18 +08:00
|
|
|
|
},
|
2025-08-16 10:39:19 +08:00
|
|
|
|
}
|
2025-08-16 09:28:04 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2025-08-16 10:39:19 +08:00
|
|
|
|
.page {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
background: #f3f5f6;
|
|
|
|
|
|
|
|
|
|
|
|
.info {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
width: 710rpx;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
margin: 30rpx auto;
|
|
|
|
|
|
|
|
|
|
|
|
//border: solid 1rpx red;
|
|
|
|
|
|
|
|
|
|
|
|
.info-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
border-bottom: solid 1rpx #d8d8d8;
|
|
|
|
|
|
width: 646rpx;
|
|
|
|
|
|
padding: 40rpx 0;
|
|
|
|
|
|
margin: 0 34rpx;
|
2025-08-20 10:03:06 +08:00
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
2025-08-16 10:39:19 +08:00
|
|
|
|
|
|
|
|
|
|
.label {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
color: #3d3d3d;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.value {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
color: #bbbbbb;
|
|
|
|
|
|
font-size: 16px;
|
2025-08-20 10:03:06 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
|
|
|
|
|
|
.avatar-preview {
|
|
|
|
|
|
width: 60rpx;
|
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
|
margin-left: 10rpx;
|
|
|
|
|
|
color: #bbbbbb;
|
|
|
|
|
|
}
|
2025-08-16 10:39:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.log-out {
|
|
|
|
|
|
margin-top: 866rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 98rpx;
|
|
|
|
|
|
color: #f15a04;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
width: 710rpx;
|
|
|
|
|
|
height: 98rpx;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border-radius: 24.5px;
|
2025-08-19 16:01:22 +08:00
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
|
}
|
2025-08-16 10:39:19 +08:00
|
|
|
|
}
|
2025-08-20 10:03:06 +08:00
|
|
|
|
|
|
|
|
|
|
.debug-btn {
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 98rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
width: 710rpx;
|
|
|
|
|
|
height: 98rpx;
|
|
|
|
|
|
background: #e0e0e0;
|
|
|
|
|
|
border-radius: 24.5px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
background: #d0d0d0;
|
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.test-btn {
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 98rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
width: 710rpx;
|
|
|
|
|
|
height: 98rpx;
|
|
|
|
|
|
background: #e0e0e0;
|
|
|
|
|
|
border-radius: 24.5px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
background: #d0d0d0;
|
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.validate-btn {
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 98rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
width: 710rpx;
|
|
|
|
|
|
height: 98rpx;
|
|
|
|
|
|
background: #e0e0e0;
|
|
|
|
|
|
border-radius: 24.5px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
background: #d0d0d0;
|
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-16 10:39:19 +08:00
|
|
|
|
}
|
2025-08-16 09:28:04 +08:00
|
|
|
|
</style>
|