编辑头像修改

This commit is contained in:
qiuyuan 2025-08-05 15:19:33 +08:00
parent 11e2900c47
commit d65a23d727

View File

@ -6,7 +6,7 @@
<view class="avatar-section"> <view class="avatar-section">
<view class="avatar-wrapper"> <view class="avatar-wrapper">
<image class="avatar" :src="userInfo.avatarUrl || '/static/imgs/index/nav.png'" <image class="avatar" :src="userInfo.avatarUrl || '/static/imgs/index/nav.png'"
mode="aspectFill"></image> mode="aspectFill" @click="onAvatarClick"></image>
<view class="edit-icon" @click="handleEditClick"> <view class="edit-icon" @click="handleEditClick">
<u-icon name="edit-pen" color="#fff" size="24"></u-icon> <u-icon name="edit-pen" color="#fff" size="24"></u-icon>
</view> </view>
@ -23,7 +23,6 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 功能按钮区域 --> <!-- 功能按钮区域 -->
<view class="function-card"> <view class="function-card">
<view class="button-item" v-for="(item, index) in choseList" :key="index" @click="goPage(item)"> <view class="button-item" v-for="(item, index) in choseList" :key="index" @click="goPage(item)">
@ -34,7 +33,6 @@
<u-icon name="arrow-right" color="#c8c9cc" size="28"></u-icon> <u-icon name="arrow-right" color="#c8c9cc" size="28"></u-icon>
</view> </view>
</view> </view>
<!-- 修改用户信息弹窗 --> <!-- 修改用户信息弹窗 -->
<u-modal :show="showEditModal" :title="isLogin ? '修改用户信息' : '微信授权登录'" :show-confirm-button="isLogin" <u-modal :show="showEditModal" :title="isLogin ? '修改用户信息' : '微信授权登录'" :show-confirm-button="isLogin"
:show-cancel-button="isLogin" @confirm="handleSubmit" @cancel="handleCancel" confirm-color="#2979ff" :show-cancel-button="isLogin" @confirm="handleSubmit" @cancel="handleCancel" confirm-color="#2979ff"
@ -55,25 +53,33 @@
</button> </button>
<view class="auth-tip">登录即表示同意用户协议隐私政策</view> <view class="auth-tip">登录即表示同意用户协议隐私政策</view>
</view> </view>
<!-- 已登录时显示编辑表单 --> <!-- 已登录时显示编辑表单 -->
<view v-else class="edit-section"> <view v-else class="edit-section">
<view class="form-item"> <view class="form-item">
<text class="form-label">头像</text> <text class="form-label">头像</text>
<u-upload :file-list="avatarList" :max-count="1" @afterRead="handleAvatarUpload" <view class="avatar-upload-container" @click="onAvatarClick">
@delete="handleAvatarDelete" width="160" height="160" preview-full-image> <view class="avatar-preview">
<view slot="delete" class="custom-delete"> <image
<u-icon name="close" color="#fff" size="24"></u-icon> v-if="avatarList.length > 0"
:src="avatarList[0].url"
mode="aspectFill"
class="avatar-img">
</image>
<view v-else class="avatar-placeholder">
<u-icon name="plus" color="#c0c4cc" size="28"></u-icon>
<text class="placeholder-text">点击上传</text>
</view> </view>
</u-upload> <view v-if="avatarList.length > 0" class="avatar-delete" @click.stop="handleAvatarDelete">
<view class="upload-tip">点击上传建议尺寸1:1</view> <u-icon name="close" color="#fff" size="26"></u-icon>
</view>
</view>
</view>
<view class="upload-tip">点击上传支持拍照或从相册选择</view>
</view> </view>
<view class="form-item"> <view class="form-item">
<text class="form-label">姓名</text> <text class="form-label">姓名</text>
<u-input v-model="formData.name" placeholder="请输入姓名" border="bottom" clearable></u-input> <u-input v-model="formData.name" placeholder="请输入姓名" border="bottom" clearable></u-input>
</view> </view>
<view class="form-item"> <view class="form-item">
<text class="form-label">简介</text> <text class="form-label">简介</text>
<u-input v-model="formData.bio" type="textarea" placeholder="请输入简介" :maxlength="200" <u-input v-model="formData.bio" type="textarea" placeholder="请输入简介" :maxlength="200"
@ -84,7 +90,6 @@
</view> </view>
</view> </view>
</u-modal> </u-modal>
<u-modal <u-modal
:show="showPhoneDialog" :show="showPhoneDialog"
title="联系社区" title="联系社区"
@ -98,7 +103,6 @@
<text class="phone-number">{{communityPhone}}</text> <text class="phone-number">{{communityPhone}}</text>
</view> </view>
</u-modal> </u-modal>
<Footer></Footer> <Footer></Footer>
</view> </view>
</template> </template>
@ -113,7 +117,6 @@
IMAGE_BASE_URL, IMAGE_BASE_URL,
BASE_URL BASE_URL
} from '@/utils/config'; } from '@/utils/config';
export default { export default {
components: { components: {
Footer Footer
@ -179,6 +182,44 @@
this.initData(); this.initData();
}, },
methods: { methods: {
//
onAvatarClick() {
if (!this.isLogin) {
this.showEditModal = true;
return;
}
//
if (this.uploading) return;
//
uni.chooseImage({
count: 1, //
sizeType: ['original', 'compressed'], //
sourceType: ['album', 'camera'], //
success: (res) => {
//
const tempFilePaths = res.tempFilePaths;
if (tempFilePaths && tempFilePaths.length > 0) {
// filehandleAvatarUpload
const file = {
url: tempFilePaths[0]
};
//
this.handleAvatarUpload({ file });
}
},
fail: (err) => {
console.error('选择图片失败', err);
uni.showToast({
title: '选择图片失败',
icon: 'none'
});
}
});
},
// ...
handleCloseModal() { handleCloseModal() {
this.showPhoneDialog = false; this.showPhoneDialog = false;
}, },
@ -203,34 +244,28 @@
this.clearUserData(); this.clearUserData();
} }
}, },
// //
updateUserInfo(data) { updateUserInfo(data) {
// IMAGE_BASE_URL // IMAGE_BASE_URL
const avatarUrl = data.avatar ? `${IMAGE_BASE_URL}${data.avatar}` : '/static/imgs/index/nav.png'; const avatarUrl = data.avatar ? `${IMAGE_BASE_URL}${data.avatar}` : '/static/imgs/index/nav.png';
this.userInfo = { this.userInfo = {
nickName: data.name || data.nickName || '未命名用户', nickName: data.name || data.nickName || '未命名用户',
avatarUrl: avatarUrl, avatarUrl: avatarUrl,
bio: data.introduce || data.bio || '这家伙很懒,什么都没有写~', bio: data.introduce || data.bio || '这家伙很懒,什么都没有写~',
phone: data.phone || '' phone: data.phone || ''
}; };
// //
this.displayAvatar = this.userInfo.avatarUrl; this.displayAvatar = this.userInfo.avatarUrl;
this.formData = { this.formData = {
name: this.userInfo.nickName, name: this.userInfo.nickName,
bio: this.userInfo.bio bio: this.userInfo.bio
}; };
if (this.userInfo.avatarUrl) { if (this.userInfo.avatarUrl) {
this.avatarList = [{ this.avatarList = [{
url: this.userInfo.avatarUrl url: this.userInfo.avatarUrl
}]; }];
} }
}, },
// //
clearUserData() { clearUserData() {
this.isLogin = false; this.isLogin = false;
@ -247,20 +282,17 @@
uni.removeStorageSync('token'); uni.removeStorageSync('token');
uni.removeStorageSync('userInfo'); uni.removeStorageSync('userInfo');
}, },
// //
handleEditClick() { handleEditClick() {
if (!this.isLogin) { if (!this.isLogin) {
this.showEditModal = true; this.showEditModal = true;
return; return;
} }
// //
this.formData = { this.formData = {
name: this.userInfo.nickName, name: this.userInfo.nickName,
bio: this.userInfo.bio bio: this.userInfo.bio
}; };
if (this.userInfo.avatarUrl) { if (this.userInfo.avatarUrl) {
this.avatarList = [{ this.avatarList = [{
url: this.userInfo.avatarUrl url: this.userInfo.avatarUrl
@ -268,10 +300,8 @@
} else { } else {
this.avatarList = []; this.avatarList = [];
} }
this.showEditModal = true; this.showEditModal = true;
}, },
// //
onGetUserInfo(e) { onGetUserInfo(e) {
if (e.detail.userInfo) { if (e.detail.userInfo) {
@ -286,13 +316,12 @@
this.showEditModal = false; this.showEditModal = false;
} }
}, },
// code // code
wxLogin() { wxLogin() {
uni.showLoading({ uni.showLoading({
title: '登录中...' title: '登录中...'
}); });
this.showEditModal = false;
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
success: (loginRes) => { success: (loginRes) => {
@ -308,17 +337,14 @@
} }
}); });
}, },
// //
async sendLoginRequest(code) { async sendLoginRequest(code) {
try { try {
const res = await post('/api/v1/apps/login/weixins', { const res = await post('/api/v1/apps/login/weixins', {
code: code code: code
}); });
if (res.success) { if (res.success) {
uni.setStorageSync('token', res.data.access_token); uni.setStorageSync('token', res.data.access_token);
if (!res.data.phone) { if (!res.data.phone) {
this.showPhoneButton = true; this.showPhoneButton = true;
uni.showToast({ uni.showToast({
@ -340,7 +366,6 @@
console.error('登录接口错误:', err); console.error('登录接口错误:', err);
} }
}, },
// //
async getPhoneNumber(e) { async getPhoneNumber(e) {
if (e.detail.errMsg !== "getPhoneNumber:ok") { if (e.detail.errMsg !== "getPhoneNumber:ok") {
@ -350,16 +375,13 @@
}); });
return; return;
} }
uni.showLoading({ uni.showLoading({
title: '获取手机号中...' title: '获取手机号中...'
}); });
try { try {
const res = await post('/api/v1/app_auth/weixin/bind_phone', { const res = await post('/api/v1/app_auth/weixin/bind_phone', {
code: e.detail.code code: e.detail.code
}); });
if (res.success) { if (res.success) {
await this.loginComplete(res.data); await this.loginComplete(res.data);
} else { } else {
@ -374,7 +396,6 @@
console.error('绑定手机号失败:', err); console.error('绑定手机号失败:', err);
} }
}, },
// //
async loginComplete(data) { async loginComplete(data) {
try { try {
@ -385,7 +406,6 @@
uni.setStorageSync('userInfo', res.data); uni.setStorageSync('userInfo', res.data);
this.updateUserInfo(res.data); this.updateUserInfo(res.data);
this.isLogin = true; this.isLogin = true;
// this.showEditModal = false;
this.showPhoneButton = false; this.showPhoneButton = false;
uni.showToast({ uni.showToast({
title: '登录成功' title: '登录成功'
@ -401,21 +421,17 @@
console.error('登录完成处理失败:', err); console.error('登录完成处理失败:', err);
} }
}, },
// //
async handleAvatarUpload(event) { async handleAvatarUpload(event) {
if (!this.isLogin) { if (!this.isLogin) {
this.showEditModal = true; this.showEditModal = true;
return; return;
} }
const { const {
file file
} = event; } = event;
if (!file || !file.url) return; if (!file || !file.url) return;
this.uploading = true; this.uploading = true;
try { try {
// //
const fileInfo = await new Promise((resolve, reject) => { const fileInfo = await new Promise((resolve, reject) => {
@ -425,17 +441,13 @@
fail: reject fail: reject
}); });
}); });
if (fileInfo.size > 3 * 1024 * 1024) { if (fileInfo.size > 3 * 1024 * 1024) {
throw new Error('图片大小不能超过2MB'); throw new Error('图片大小不能超过3MB');
} }
// //
const avatarUrl = await this.uploadAvatar(file.url); const avatarUrl = await this.uploadAvatar(file.url);
// //
await this.updateUserAvatar(avatarUrl); await this.updateUserAvatar(avatarUrl);
uni.showToast({ uni.showToast({
title: '头像上传成功' title: '头像上传成功'
}); });
@ -449,7 +461,6 @@
this.uploading = false; this.uploading = false;
} }
}, },
// //
uploadAvatar(filePath) { uploadAvatar(filePath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -478,7 +489,6 @@
}); });
}); });
}, },
// //
async updateUserAvatar(avatarUrl) { async updateUserAvatar(avatarUrl) {
try { try {
@ -488,7 +498,6 @@
introduce: this.formData.bio, introduce: this.formData.bio,
name: this.formData.name name: this.formData.name
}); });
// 2. // 2.
const res = await get('/api/v1/app_auth/mine'); const res = await get('/api/v1/app_auth/mine');
if (res && res.success) { if (res && res.success) {
@ -503,29 +512,38 @@
throw err; throw err;
} }
}, },
// -
//
handleAvatarDelete() { handleAvatarDelete() {
uni.showModal({
title: '提示',
content: '确定要删除当前头像吗?',
confirmText: '删除',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
this.avatarList = []; this.avatarList = [];
this.displayAvatar = '/static/imgs/index/nav.png'; this.displayAvatar = '/static/imgs/index/nav.png';
this.userInfo.avatarUrl = ''; this.userInfo.avatarUrl = '';
uni.showToast({
title: '已删除',
icon: 'none'
});
}
}
});
}, },
// //
async handleSubmit() { async handleSubmit() {
if (!this.isLogin) return; if (!this.isLogin) return;
const { const {
name, name,
bio bio
} = this.formData; } = this.formData;
console.log("====", this.avatarList)
let avatarUrl = this.avatarList.length > 0 ? this.avatarList[0].url : "";
let avatarUrl = this.avatarList.length > 0 ? this.avatarList[0].url : "";
if (avatarUrl && avatarUrl.includes(IMAGE_BASE_URL)) { if (avatarUrl && avatarUrl.includes(IMAGE_BASE_URL)) {
avatarUrl = avatarUrl.replace(IMAGE_BASE_URL, ''); avatarUrl = avatarUrl.replace(IMAGE_BASE_URL, '');
} }
if (!name) { if (!name) {
uni.showToast({ uni.showToast({
title: '请输入姓名', title: '请输入姓名',
@ -533,11 +551,9 @@
}); });
return; return;
} }
uni.showLoading({ uni.showLoading({
title: '提交中...' title: '提交中...'
}); });
try { try {
// 1. // 1.
await post('/api/v1/app_auth/bind', { await post('/api/v1/app_auth/bind', {
@ -545,7 +561,6 @@
introduce: bio, introduce: bio,
name: name name: name
}); });
// 2. // 2.
const res = await get('/api/v1/app_auth/mine'); const res = await get('/api/v1/app_auth/mine');
if (res && res.success) { if (res && res.success) {
@ -553,12 +568,10 @@
uni.setStorageSync('userInfo', res.data); uni.setStorageSync('userInfo', res.data);
this.updateUserInfo(res.data); this.updateUserInfo(res.data);
this.showEditModal = false; this.showEditModal = false;
uni.hideLoading(); uni.hideLoading();
uni.showToast({ uni.showToast({
title: '修改成功' title: '修改成功'
}); });
} else { } else {
throw new Error(res.message || '获取用户信息失败'); throw new Error(res.message || '获取用户信息失败');
} }
@ -571,38 +584,30 @@
console.error('修改失败:', err); console.error('修改失败:', err);
} }
}, },
// //
handleCancel() { handleCancel() {
this.showEditModal = false; this.showEditModal = false;
}, },
//
// //
goPage(item) { goPage(item) {
if (item.key === 6) { // if (item.key === 6) { //
this.handleContactCommunity(); this.handleContactCommunity();
return; return;
} }
if (item.key === 5) { // if (item.key === 5) { //
this.handleEditClick(); // this.handleEditClick(); //
return; return;
} }
if (!this.checkLogin()) { if (!this.checkLogin()) {
this.showEditModal = true; this.showEditModal = true;
return; return;
} }
if (item.pageUrl) { if (item.pageUrl) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/${item.pageUrl}/index` url: `/pages/${item.pageUrl}/index`
}); });
} }
}, },
// //
handleContactCommunity() { handleContactCommunity() {
if (!this.checkLogin()) { if (!this.checkLogin()) {
@ -622,7 +627,6 @@
} }
}); });
}, },
// //
callCommunityPhone() { callCommunityPhone() {
uni.makePhoneCall({ uni.makePhoneCall({
@ -640,7 +644,6 @@
}); });
this.showPhoneDialog = false; this.showPhoneDialog = false;
}, },
// //
checkLogin() { checkLogin() {
const token = uni.getStorageSync('token'); const token = uni.getStorageSync('token');
@ -665,29 +668,24 @@
box-sizing: border-box; box-sizing: border-box;
padding-bottom: 120rpx; padding-bottom: 120rpx;
} }
.user-info-card { .user-info-card {
background: #fff; background: #fff;
border-radius: 16rpx; border-radius: 16rpx;
padding: 40rpx 30rpx; padding: 40rpx 30rpx;
margin-bottom: 24rpx; margin-bottom: 24rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
.user-info { .user-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
} }
.avatar-section { .avatar-section {
margin-bottom: 20rpx; margin-bottom: 20rpx;
.avatar-wrapper { .avatar-wrapper {
position: relative; position: relative;
width: 140rpx; width: 140rpx;
height: 140rpx; height: 140rpx;
.avatar { .avatar {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -695,7 +693,6 @@
border: 4rpx solid #fff; border: 4rpx solid #fff;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1); box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
} }
.edit-icon { .edit-icon {
position: absolute; position: absolute;
right: 0; right: 0;
@ -709,7 +706,6 @@
justify-content: center; justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
} }
.u-loading-icon { .u-loading-icon {
position: absolute; position: absolute;
top: 0; top: 0;
@ -725,79 +721,66 @@
} }
} }
} }
.name-section { .name-section {
width: 100%; width: 100%;
align-items: center; align-items: center;
text-align: center; text-align: center;
margin-bottom: 30rpx; margin-bottom: 30rpx;
.name { .name {
font-size: 36rpx; font-size: 36rpx;
font-weight: 600; font-weight: 600;
color: #333; color: #333;
} }
.phone { .phone {
color: #999; color: #999;
font-size: 24rpx; font-size: 24rpx;
} }
} }
.description-card { .description-card {
background: #f8f9fa; background: #f8f9fa;
border-radius: 12rpx; border-radius: 12rpx;
padding: 24rpx; padding: 24rpx;
width: 100%; width: 100%;
text-align: center; text-align: center;
.title { .title {
font-size: 28rpx; font-size: 28rpx;
color: #666; color: #666;
margin-bottom: 12rpx; margin-bottom: 12rpx;
display: block; display: block;
} }
.content { .content {
font-size: 26rpx; font-size: 26rpx;
color: #999; color: #999;
line-height: 1.5; line-height: 1.5;
} }
} }
.function-card { .function-card {
background: #fff; background: #fff;
border-radius: 16rpx; border-radius: 16rpx;
padding: 0 30rpx; padding: 0 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
.button-item { .button-item {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 28rpx 0; padding: 28rpx 0;
border-bottom: 1rpx solid #f2f3f5; border-bottom: 1rpx solid #f2f3f5;
&:active { &:active {
background-color: #f8f8f8; background-color: #f8f8f8;
} }
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
} }
.button-content { .button-content {
display: flex; display: flex;
align-items: center; align-items: center;
flex: 1; flex: 1;
} }
.icon { .icon {
width: 48rpx; width: 48rpx;
height: 48rpx; height: 48rpx;
margin-right: 24rpx; margin-right: 24rpx;
} }
.label { .label {
font-size: 30rpx; font-size: 30rpx;
color: #333; color: #333;
@ -805,21 +788,17 @@
} }
} }
} }
.modal-content { .modal-content {
padding: 0 30rpx; padding: 0 30rpx;
width: 90%; width: 90%;
margin: 0 auto; margin: 0 auto;
max-height: 70vh; max-height: 70vh;
overflow-y: auto; overflow-y: auto;
/* 编辑表单区域 */ /* 编辑表单区域 */
.edit-section { .edit-section {
padding: 20rpx 0; padding: 20rpx 0;
.form-item { .form-item {
margin-bottom: 40rpx; margin-bottom: 40rpx;
.form-label { .form-label {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
@ -827,14 +806,12 @@
margin-bottom: 16rpx; margin-bottom: 16rpx;
font-weight: 500; font-weight: 500;
} }
.upload-tip { .upload-tip {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
margin-top: 10rpx; margin-top: 10rpx;
text-align: center; text-align: center;
} }
.word-count { .word-count {
text-align: right; text-align: right;
font-size: 24rpx; font-size: 24rpx;
@ -842,31 +819,13 @@
margin-top: 10rpx; margin-top: 10rpx;
} }
} }
/* 自定义删除按钮样式 */
.custom-delete {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background: #f56c6c;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
} }
}
/* 授权登录区域 */ /* 授权登录区域 */
.auth-section { .auth-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 40rpx 0; padding: 40rpx 0;
.auth-title { .auth-title {
font-size: 32rpx; font-size: 32rpx;
color: #333; color: #333;
@ -874,7 +833,6 @@
text-align: center; text-align: center;
font-weight: 500; font-weight: 500;
} }
.auth-button { .auth-button {
width: 100%; width: 100%;
height: 90rpx; height: 90rpx;
@ -889,20 +847,16 @@
justify-content: center; justify-content: center;
position: relative; position: relative;
box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.3); box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.3);
&::after { &::after {
border: none; border: none;
} }
&.phone-button { &.phone-button {
background: #2979ff; background: #2979ff;
box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3); box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3);
} }
&:active { &:active {
opacity: 0.9; opacity: 0.9;
} }
.wechat-icon, .wechat-icon,
.phone-icon { .phone-icon {
width: 40rpx; width: 40rpx;
@ -910,7 +864,6 @@
margin-right: 15rpx; margin-right: 15rpx;
} }
} }
.auth-tip { .auth-tip {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
@ -918,12 +871,10 @@
text-align: center; text-align: center;
} }
} }
.phone-dialog-content { .phone-dialog-content {
padding: 40rpx; padding: 40rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: 32rpx;
.phone-number { .phone-number {
font-weight: bold; font-weight: bold;
color: #2979ff; color: #2979ff;
@ -931,4 +882,61 @@
} }
} }
} }
//
.avatar-upload-container {
width: 160rpx;
height: 160rpx;
margin: 0 auto;
position: relative;
border-radius: 8rpx;
overflow: hidden;
}
//
.avatar-preview {
width: 100%;
height: 100%;
position: relative;
border-radius: 8rpx;
overflow: hidden;
background-color: #f5f7fa;
display: flex;
align-items: center;
justify-content: center;
.avatar-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #c0c4cc;
.placeholder-text {
font-size: 24rpx;
margin-top: 10rpx;
}
}
.avatar-delete {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background-color: #f56c6c;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
}
}
</style> </style>