feature: modify profile
This commit is contained in:
352
src/pages/my/profile.vue
Normal file
352
src/pages/my/profile.vue
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
<route lang="jsonc" type="page">
|
||||||
|
{
|
||||||
|
"layout": "default",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { IUserResult } from '@/api/types/user'
|
||||||
|
import { updateUserInfo } from '@/api/user'
|
||||||
|
import { toast } from '@/utils/toast'
|
||||||
|
import { router } from '@/utils/tools'
|
||||||
|
import { uploadFileUrl, useUpload } from '@/utils/uploadFile'
|
||||||
|
import defaultAvatarImg from './img/头像.png'
|
||||||
|
|
||||||
|
const OSS = inject('OSS')
|
||||||
|
const navbarHeight = inject('navbarHeight')
|
||||||
|
|
||||||
|
// 本地图片资源
|
||||||
|
const defaultAvatar = defaultAvatarImg as string
|
||||||
|
|
||||||
|
// 用户信息相关
|
||||||
|
const user = ref<IUserResult>({
|
||||||
|
id: 0,
|
||||||
|
sn: 0,
|
||||||
|
sex: '未知',
|
||||||
|
account: '',
|
||||||
|
nickname: '',
|
||||||
|
real_name: '',
|
||||||
|
avatar: '',
|
||||||
|
collect_count: 0,
|
||||||
|
coupon_count: 0,
|
||||||
|
create_time: '',
|
||||||
|
has_auth: false,
|
||||||
|
has_password: false,
|
||||||
|
member: 0,
|
||||||
|
mobile: '',
|
||||||
|
user_money: '0.00',
|
||||||
|
version: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Action Sheet 相关
|
||||||
|
const showAvatarActionSheet = ref(false)
|
||||||
|
const avatarActions = ref([
|
||||||
|
{
|
||||||
|
name: '拍照',
|
||||||
|
value: 'camera',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '从手机相册选择',
|
||||||
|
value: 'album',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// 编辑昵称相关
|
||||||
|
const showEditNicknamePopup = ref(false)
|
||||||
|
const nicknameInput = ref('')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传头像文件
|
||||||
|
*/
|
||||||
|
function handleUploadAvatar(filePath: string) {
|
||||||
|
const { run: uploadFile } = useUpload<string>(
|
||||||
|
uploadFileUrl.USER_AVATAR,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
maxSize: 5,
|
||||||
|
onSuccess: async (res) => {
|
||||||
|
try {
|
||||||
|
const avatarUrl = typeof res === 'string' ? res : (res as any).uri || (res as any).url
|
||||||
|
await updateUserInfo({ field: 'avatar', value: avatarUrl })
|
||||||
|
user.value.avatar = avatarUrl
|
||||||
|
toast.info('头像上传成功')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('更新头像失败:', error)
|
||||||
|
toast.info('头像上传失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
console.error('上传失败:', err)
|
||||||
|
toast.info('头像上传失败')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filePath,
|
||||||
|
)
|
||||||
|
uploadFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 掩码处理手机号
|
||||||
|
*/
|
||||||
|
const maskedMobile = computed(() => {
|
||||||
|
if (!user.value.mobile || user.value.mobile.length !== 11)
|
||||||
|
return '+86 155****5456'
|
||||||
|
// 只处理11位手机号
|
||||||
|
return `+86 ${user.value.mobile.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')}`
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证昵称是否有效(1-10字符,一个汉字为一个字符)
|
||||||
|
*/
|
||||||
|
const isNicknameValid = computed(() => {
|
||||||
|
const trimmed = nicknameInput.value.trim()
|
||||||
|
return trimmed.length >= 1 && trimmed.length <= 10
|
||||||
|
})
|
||||||
|
|
||||||
|
const Profile = {
|
||||||
|
/**
|
||||||
|
* 初始化用户信息
|
||||||
|
*/
|
||||||
|
handleInit: () => {
|
||||||
|
// getUserInfo().then((res) => {
|
||||||
|
// user.value = res
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑头像 - 显示选择面板
|
||||||
|
*/
|
||||||
|
handleEditAvatar: () => {
|
||||||
|
showAvatarActionSheet.value = true
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理头像选择
|
||||||
|
*/
|
||||||
|
handleSelectAvatarAction: (item: any) => {
|
||||||
|
showAvatarActionSheet.value = false
|
||||||
|
|
||||||
|
if (item.value === 'camera') {
|
||||||
|
// 拍照
|
||||||
|
Profile.handleChooseImage(['camera'])
|
||||||
|
}
|
||||||
|
else if (item.value === 'album') {
|
||||||
|
// 从相册选择
|
||||||
|
Profile.handleChooseImage(['album'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择图片
|
||||||
|
*/
|
||||||
|
handleChooseImage: (sourceType: ('camera' | 'album')[]) => {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.chooseMedia({
|
||||||
|
count: 1,
|
||||||
|
mediaType: ['image'],
|
||||||
|
sourceType,
|
||||||
|
success: (res) => {
|
||||||
|
const file = res.tempFiles[0]
|
||||||
|
if (file) {
|
||||||
|
handleUploadAvatar(file.tempFilePath)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('选择图片失败:', err)
|
||||||
|
if (err.errMsg && !err.errMsg.includes('cancel')) {
|
||||||
|
toast.info('选择图片失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
sizeType: ['compressed'],
|
||||||
|
sourceType,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.tempFilePaths && res.tempFilePaths.length > 0) {
|
||||||
|
handleUploadAvatar(res.tempFilePaths[0])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('选择图片失败:', err)
|
||||||
|
if (err.errMsg && !err.errMsg.includes('cancel')) {
|
||||||
|
toast.info('选择图片失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑昵称 - 显示弹窗
|
||||||
|
*/
|
||||||
|
handleEditNickname: () => {
|
||||||
|
nicknameInput.value = user.value.nickname || ''
|
||||||
|
showEditNicknamePopup.value = true
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭编辑昵称弹窗
|
||||||
|
*/
|
||||||
|
handleCloseEditNickname: () => {
|
||||||
|
showEditNicknamePopup.value = false
|
||||||
|
nicknameInput.value = ''
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存昵称
|
||||||
|
*/
|
||||||
|
handleSaveNickname: async () => {
|
||||||
|
const trimmed = nicknameInput.value.trim()
|
||||||
|
if (!trimmed || trimmed.length < 1 || trimmed.length > 10) {
|
||||||
|
toast.info('昵称限制1-10字符')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await updateUserInfo({ field: 'nickname', value: trimmed })
|
||||||
|
user.value.nickname = trimmed
|
||||||
|
showEditNicknamePopup.value = false
|
||||||
|
toast.info('昵称修改成功')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('更新昵称失败:', error)
|
||||||
|
toast.info('昵称修改失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改手机号
|
||||||
|
*/
|
||||||
|
handleEditMobile: () => {
|
||||||
|
router.navigateTo('/pages/login/mobile?type=edit')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改密码
|
||||||
|
*/
|
||||||
|
handleEditPassword: () => {
|
||||||
|
// TODO: 实现修改密码功能
|
||||||
|
console.log('修改密码')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改绑定用户
|
||||||
|
*/
|
||||||
|
handleEditBoundUser: () => {
|
||||||
|
// TODO: 实现修改绑定用户功能
|
||||||
|
console.log('修改绑定用户')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
Profile.handleInit()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view>
|
||||||
|
<navbar title="个人信息" custom-class="!bg-white">
|
||||||
|
<template #right />
|
||||||
|
</navbar>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="mx-30rpx mt-20rpx">
|
||||||
|
<wd-cell-group>
|
||||||
|
<!-- 头像 -->
|
||||||
|
<wd-cell is-link title="头像" @click="Profile.handleEditAvatar">
|
||||||
|
<template #value>
|
||||||
|
<wd-img width="64rpx" height="64rpx" :src="(user.avatar && typeof user.avatar === 'string' && user.avatar.trim()) ? user.avatar : defaultAvatar" mode="aspectFill" round />
|
||||||
|
</template>
|
||||||
|
</wd-cell>
|
||||||
|
|
||||||
|
<!-- 昵称 -->
|
||||||
|
<wd-cell is-link title="昵称" :value="(user.nickname || '昵称名字')" @click="Profile.handleEditNickname" />
|
||||||
|
|
||||||
|
<!-- 修改手机号 -->
|
||||||
|
<wd-cell is-link title="修改手机号" :value="maskedMobile" @click="Profile.handleEditMobile" />
|
||||||
|
|
||||||
|
<!-- 修改密码 -->
|
||||||
|
<wd-cell is-link title="修改密码" @click="Profile.handleEditPassword" />
|
||||||
|
|
||||||
|
<!-- 修改绑定用户 -->
|
||||||
|
<wd-cell is-link title="修改绑定用户" @click="Profile.handleEditBoundUser" />
|
||||||
|
</wd-cell-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 头像选择 Action Sheet -->
|
||||||
|
<wd-action-sheet
|
||||||
|
v-model="showAvatarActionSheet"
|
||||||
|
:actions="avatarActions"
|
||||||
|
cancel-text="取消"
|
||||||
|
@close="showAvatarActionSheet = false"
|
||||||
|
@select="Profile.handleSelectAvatarAction"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 编辑昵称弹窗 -->
|
||||||
|
<wd-popup
|
||||||
|
v-model="showEditNicknamePopup"
|
||||||
|
lock-scroll
|
||||||
|
custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;"
|
||||||
|
position="bottom"
|
||||||
|
@close="Profile.handleCloseEditNickname"
|
||||||
|
>
|
||||||
|
<view class="relative bg-white px-30rpx pb-78rpx pt-50rpx">
|
||||||
|
<!-- 关闭按钮 -->
|
||||||
|
<view class="absolute right-30rpx top-18rpx" @click="Profile.handleCloseEditNickname">
|
||||||
|
<wd-icon name="close" size="20px" color="#C0C4CC" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标题 -->
|
||||||
|
<view class="mb-40rpx text-center text-36rpx text-[#121212] leading-50rpx">
|
||||||
|
修改昵称
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<view class="mb-20rpx">
|
||||||
|
<view class="mb-20rpx text-30rpx text-[#303133] leading-44rpx">
|
||||||
|
昵称:
|
||||||
|
</view>
|
||||||
|
<wd-input
|
||||||
|
v-model="nicknameInput"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入昵称"
|
||||||
|
no-border
|
||||||
|
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
|
||||||
|
custom-input-class="!px-32rpx !h-104rpx"
|
||||||
|
:maxlength="10"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示文字 -->
|
||||||
|
<view class="mb-40rpx text-24rpx text-[#606266] leading-34rpx">
|
||||||
|
昵称限制1-10字符,一个汉字为一个字符
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 保存按钮 -->
|
||||||
|
<view
|
||||||
|
class="h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-[#fff] leading-90rpx"
|
||||||
|
:class="{ 'opacity-40': !isNicknameValid }"
|
||||||
|
@click="isNicknameValid && Profile.handleSaveNickname()"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background: #f6f7f8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user