From 5454ac5f64ca4608b55f277d5198c19e7193bf87 Mon Sep 17 00:00:00 2001 From: zpc Date: Fri, 20 Feb 2026 23:10:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(profile):=20=E4=B8=AA=E4=BA=BA=E8=B5=84?= =?UTF-8?q?=E6=96=99=E9=A1=B5=E6=8C=89=E8=AE=BE=E8=AE=A1=E5=9B=BE=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 头像居中展示,右下角叠加编辑图标(icon-user-icon-edit.png) - 昵称改为表单输入框样式,支持直接编辑 - UID只读展示 - 底部橙色保存按钮 - 移除旧的列表式布局和弹窗修改昵称方式 --- uniapp/pages/mine/profile/index.vue | 428 +++++++-------------- uniapp/static/mine/icon-user-icon-edit.png | Bin 0 -> 1281 bytes 2 files changed, 146 insertions(+), 282 deletions(-) create mode 100644 uniapp/static/mine/icon-user-icon-edit.png diff --git a/uniapp/pages/mine/profile/index.vue b/uniapp/pages/mine/profile/index.vue index 9661694..36c13ec 100644 --- a/uniapp/pages/mine/profile/index.vue +++ b/uniapp/pages/mine/profile/index.vue @@ -2,61 +2,44 @@ - - - 头像 - - + + + - + - - - 昵称 - - {{ userInfo.nickname || '未设置' }} - - + + + 昵称 + - - - UID - - {{ userInfo.uid || '--' }} - + + + UID + - - - - - - 修改昵称 - - - - - - - 取消 - - - 确定 - - + + + @@ -76,19 +59,23 @@ * 展示和修改用户头像、昵称 * UID 仅展示不可修改 */ -import { ref, computed, onMounted } from 'vue' +import { ref, reactive, computed, onMounted } from 'vue' import { onShow } from '@dcloudio/uni-app' import { useUserStore } from '@/store/user.js' -import { getProfile, updateProfile, updateAvatar } from '@/api/user.js' +import { updateProfile, updateAvatar } from '@/api/user.js' import config from '@/config/index.js' const userStore = useUserStore() // 状态 const loading = ref(false) +const saving = ref(false) const loadingText = ref('加载中...') -const nicknamePopupVisible = ref(false) -const newNickname = ref('') + +// 表单数据 +const formData = reactive({ + nickname: '' +}) // 用户信息 const userInfo = computed(() => ({ @@ -99,26 +86,10 @@ const userInfo = computed(() => ({ })) /** - * 获取用户资料 + * 初始化表单数据 */ -async function fetchProfile() { - try { - loading.value = true - loadingText.value = '加载中...' - - const res = await getProfile() - if (res.code === 0 && res.data) { - userStore.updateUserInfo(res.data) - } - } catch (error) { - console.error('获取用户资料失败:', error) - uni.showToast({ - title: '获取资料失败', - icon: 'none' - }) - } finally { - loading.value = false - } +function initFormData() { + formData.nickname = userStore.nickname || '' } /** @@ -135,10 +106,7 @@ function handleChangeAvatar() { }, fail: (err) => { if (err.errMsg && !err.errMsg.includes('cancel')) { - uni.showToast({ - title: '选择图片失败', - icon: 'none' - }) + uni.showToast({ title: '选择图片失败', icon: 'none' }) } } }) @@ -152,8 +120,7 @@ async function uploadAvatar(filePath) { try { loading.value = true loadingText.value = '上传中...' - - // 上传图片到服务器 + const uploadRes = await new Promise((resolve, reject) => { uni.uploadFile({ url: `${config.API_BASE_URL}/upload/image`, @@ -165,8 +132,7 @@ async function uploadAvatar(filePath) { success: (res) => { if (res.statusCode === 200) { try { - const data = JSON.parse(res.data) - resolve(data) + resolve(JSON.parse(res.data)) } catch (e) { reject(new Error('解析响应失败')) } @@ -177,18 +143,14 @@ async function uploadAvatar(filePath) { fail: (err) => reject(err) }) }) - + if (uploadRes.code === 0 && uploadRes.data) { - // 更新头像 const avatarUrl = uploadRes.data.url || uploadRes.data const updateRes = await updateAvatar(avatarUrl) - + if (updateRes.code === 0) { userStore.updateUserInfo({ avatar: avatarUrl }) - uni.showToast({ - title: '头像更新成功', - icon: 'success' - }) + uni.showToast({ title: '头像更新成功', icon: 'success' }) } else { throw new Error(updateRes.message || '更新头像失败') } @@ -197,253 +159,159 @@ async function uploadAvatar(filePath) { } } catch (error) { console.error('上传头像失败:', error) - uni.showToast({ - title: error.message || '上传失败', - icon: 'none' - }) + uni.showToast({ title: error.message || '上传失败', icon: 'none' }) } finally { loading.value = false } } /** - * 显示修改昵称弹窗 + * 保存资料(昵称) */ -function showNicknamePopup() { - newNickname.value = userInfo.value.nickname || '' - nicknamePopupVisible.value = true -} +async function handleSave() { + const nickname = formData.nickname.trim() -/** - * 隐藏修改昵称弹窗 - */ -function hideNicknamePopup() { - nicknamePopupVisible.value = false - newNickname.value = '' -} - -/** - * 更新昵称 - */ -async function handleUpdateNickname() { - const nickname = newNickname.value.trim() - if (!nickname) { - uni.showToast({ - title: '请输入昵称', - icon: 'none' - }) + uni.showToast({ title: '请输入昵称', icon: 'none' }) return } - - if (nickname === userInfo.value.nickname) { - hideNicknamePopup() + + if (nickname === userStore.nickname) { + uni.showToast({ title: '资料未修改', icon: 'none' }) return } - + try { + saving.value = true loading.value = true loadingText.value = '保存中...' - hideNicknamePopup() - + const res = await updateProfile({ nickname }) - + if (res.code === 0) { userStore.updateUserInfo({ nickname }) - uni.showToast({ - title: '昵称更新成功', - icon: 'success' - }) + uni.showToast({ title: '保存成功', icon: 'success' }) } else { - throw new Error(res.message || '更新失败') + throw new Error(res.message || '保存失败') } } catch (error) { - console.error('更新昵称失败:', error) - uni.showToast({ - title: error.message || '更新失败', - icon: 'none' - }) + console.error('保存资料失败:', error) + uni.showToast({ title: error.message || '保存失败', icon: 'none' }) } finally { + saving.value = false loading.value = false } } -/** - * 页面显示时刷新数据 - */ +// Lifecycle onShow(() => { - userStore.restoreFromStorage() + initFormData() }) -/** - * 页面加载 - */ onMounted(() => { userStore.restoreFromStorage() - fetchProfile() + initFormData() }) diff --git a/uniapp/static/mine/icon-user-icon-edit.png b/uniapp/static/mine/icon-user-icon-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..6670c702bffda4dee4fd9c26c4a105e79e955853 GIT binary patch literal 1281 zcmV+c1^)VpP)>HGS(UXFzOtcATy|V_RGQ>_? z{lSm9;>U=e?ae}AQx6T&9F$%ercUs)Jy}2IEj?;Nf@knZ#dB=9koB_g1bsY^^}Bh( zx`NV_q^bEEJWd&WfPGNN%bKL1e3W7%7w@Dz^zc|0^!}r$^d13^KL_c+#lH~y>0Pip z1^AX&V65~K8`74YP4dNLC>dAC_;#$m{XO*k$6O(6b_V_GN}U9#A9fvtdndZ5vFSLZ z&)~Eb-Za=ET(oxR6Y}I?^IE+=31wkYYR6WKP#1ow7N`&Q9&R*VI1S9XMx|varEaHJ zJDSW4Wl%htOu|bw$jJ0p==kkxw3HK4Xn?#c9&mL<)+4d*)tt4mdFmNY!$p;?J@spK z&PSY*$-RJr3whYdSw-E|b=)x($yMK~@xo4-f!ante+Gi_w zM1W_u0r4%sQ=5SuFE-kqC-44qlcw)K1csdZ5v|2j^mkqkYNl%I+P13-BVcP%qp*RB zU-2$*?NS5yp+E{0*5?6A(;n*tcK27k=tsitkc`^`z8#dYWrUINs8elwQqim>`_xzXEG5VYteQvl2NVTv(3Wnh z{pmJX-dePSDm))*zjyUJf-DiFB}EWnO)n#~bYs?9v`sxb@R!Cyhy7~N})gdD#|L;^o>IE@81J%1@&fY zNRtCT#V6lMqjR%3HAzYh#NxSfG04|QoSmlG`-NZq7zaCcoE}M1myB)mCBSYk1n{It ze2g&^ADm-3&36(M?jW}cJcz#+(^#5M`t+hkJ;#Fr*3|yd_~*T}w=w#l@_pb+5@KIo rZPCn}lCc?)39%FNe_}%$3a