1000 lines
36 KiB
Vue
1000 lines
36 KiB
Vue
<template>
|
||
<view class="profile-page">
|
||
<!-- 用户信息区域 -->
|
||
<view class="user-info-card">
|
||
<view class="user-info">
|
||
<view class="avatar-section">
|
||
<view class="avatar-wrapper">
|
||
<image class="avatar" :src="userInfo.avatarUrl || '/static/imgs/index/nav.png'"
|
||
mode="aspectFill" @click="onAvatarClick"></image>
|
||
<view class="edit-icon" @click="handleEditClick">
|
||
<u-icon name="edit-pen" color="#fff" size="24"></u-icon>
|
||
</view>
|
||
<u-loading-icon v-if="uploading" mode="circle" color="#2979ff" size="28"></u-loading-icon>
|
||
</view>
|
||
</view>
|
||
<view class="name-section" @click="handleEditClick">
|
||
<view class="name">{{userInfo.nickName || '未登录用户'}}</view>
|
||
<view class="phone">{{userInfo.phone || ''}}</view>
|
||
</view>
|
||
<view class="description-card">
|
||
<text class="title">个人简介</text>
|
||
<text class="content">{{userInfo.bio || '这家伙很懒,什么都没有写~'}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 功能按钮区域 -->
|
||
<view class="function-card">
|
||
<view class="button-item" v-for="(item, index) in choseList" :key="index" @click="goPage(item)">
|
||
<view class="button-content">
|
||
<image class="icon" :src='item.url' mode="aspectFit"></image>
|
||
<text class="label">{{item.name}}</text>
|
||
</view>
|
||
<u-icon name="arrow-right" color="#c8c9cc" size="28"></u-icon>
|
||
</view>
|
||
</view>
|
||
<!-- 修改用户信息弹窗 -->
|
||
<u-modal :show="showEditModal" :title="isLogin ? '修改用户信息' : '手机号快捷登录'" :show-confirm-button="isLogin"
|
||
:show-cancel-button="isLogin" @confirm="handleSubmit" @cancel="handleCancel" confirm-color="#2979ff"
|
||
cancel-color="#606266">
|
||
<view class="modal-content">
|
||
<!-- 未登录时显示授权按钮 -->
|
||
<view v-if="!isLogin" class="auth-section">
|
||
<view class="auth-title">请先授权手机号以使用完整功能</view>
|
||
<button v-if="!showPhoneButton" class="auth-button" open-type="getUserInfo"
|
||
@getuserinfo="onGetUserInfo">
|
||
<image class="auth-icon" src="/static/imgs/phone.png"></image>
|
||
手机号快捷登录
|
||
</button>
|
||
<button v-if="showPhoneButton" type="default" open-type="getPhoneNumber"
|
||
@getphonenumber="getPhoneNumber" class="auth-button phone-button">
|
||
<image class="phone-icon" src="/static/imgs/phone.png"></image>
|
||
授权获取手机号
|
||
</button>
|
||
<view class="auth-agreement">
|
||
<checkbox-group @change="handleAgreementChange">
|
||
<label>
|
||
<checkbox :checked="agreementChecked" color="#2979ff" style="transform:scale(0.7)"/>
|
||
我已阅读并同意<text class="agreement-link" @click.stop="goToAgreement('userAgreement')">《用户协议》</text>和<text class="agreement-link" @click.stop="goToAgreement('agreement')">《隐私政策》</text>
|
||
</label>
|
||
</checkbox-group>
|
||
</view>
|
||
</view>
|
||
<!-- 已登录时显示编辑表单 -->
|
||
<view v-else class="edit-section">
|
||
<view class="form-item">
|
||
<text class="form-label">头像:</text>
|
||
<view class="avatar-upload-container" @click="onAvatarClick">
|
||
<view class="avatar-preview">
|
||
<image
|
||
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 v-if="avatarList.length > 0" class="avatar-delete" @click.stop="handleAvatarDelete">
|
||
<u-icon name="close" color="#fff" size="26"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="upload-tip">点击上传,支持拍照或从相册选择</view>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">姓名:</text>
|
||
<u-input v-model="formData.name" placeholder="请输入姓名" border="bottom" clearable></u-input>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">简介:</text>
|
||
<u-input v-model="formData.bio" type="textarea" placeholder="请输入简介" :maxlength="200"
|
||
height="120" border="bottom">
|
||
</u-input>
|
||
<view class="word-count">{{formData.bio.length}}/200</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-modal>
|
||
<u-modal
|
||
:show="showPhoneDialog"
|
||
title="联系社区"
|
||
confirm-text="拨打"
|
||
cancel-text="取消"
|
||
@confirm="callCommunityPhone"
|
||
@cancel="showPhoneDialog = false"
|
||
:closeOnClickOverlay="true">
|
||
<view class="phone-dialog-content">
|
||
<text>社区电话:</text>
|
||
<text class="phone-number">{{communityPhone}}</text>
|
||
</view>
|
||
</u-modal>
|
||
<Copyright/>
|
||
<Footer></Footer>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import Footer from '@/components/footer_common.vue';
|
||
import Copyright from '@/components/gx-copyright.vue';
|
||
import {
|
||
get,
|
||
post
|
||
} from '@/utils/request';
|
||
import {
|
||
IMAGE_BASE_URL,
|
||
BASE_URL
|
||
} from '@/utils/config';
|
||
export default {
|
||
components: {
|
||
Footer,Copyright
|
||
},
|
||
data() {
|
||
return {
|
||
isLogin: false,
|
||
showEditModal: false,
|
||
showPhoneButton: false,
|
||
avatarList: [],
|
||
formData: {
|
||
name: "",
|
||
bio: "",
|
||
},
|
||
userInfo: {
|
||
nickName: "",
|
||
avatarUrl: "",
|
||
bio: "",
|
||
phone: ""
|
||
},
|
||
uploading: false,
|
||
displayAvatar: '/static/imgs/index/nav.png',
|
||
agreementChecked: false,
|
||
choseList: [{
|
||
key: 1,
|
||
url: "/static/imgs/service/service_list.png",
|
||
name: '全部工单',
|
||
pageUrl: 'myTickets'
|
||
},
|
||
{
|
||
key: 2,
|
||
url: "/static/imgs/service/service_help.png",
|
||
name: '邻里互助',
|
||
pageUrl: 'mySeekHelp'
|
||
},
|
||
{
|
||
key: 3,
|
||
url: "/static/imgs/service/service_service.png",
|
||
name: '周边服务',
|
||
pageUrl: 'neighbor'
|
||
},
|
||
{
|
||
key: 4,
|
||
url: "/static/imgs/service/service_friend.png",
|
||
name: '城市青年会客厅预约',
|
||
pageUrl: 'meetingList'
|
||
},
|
||
{
|
||
key: 5,
|
||
url: "/static/imgs/service/service_notice.png",
|
||
name: '设置'
|
||
},
|
||
{
|
||
key: 6,
|
||
url: "/static/imgs/service/service_phone.png",
|
||
name: '联系社区',
|
||
},
|
||
{
|
||
key: 7,
|
||
url: "/static/imgs/service/service_xieyi.png",
|
||
name: '用户协议',
|
||
pageUrl: 'userAgreement'
|
||
},
|
||
{
|
||
key: 8,
|
||
url: "/static/imgs/service/service_zhengce.png",
|
||
name: '隐私政策',
|
||
pageUrl: 'agreement'
|
||
}
|
||
],
|
||
communityPhone: '0513-59000051',
|
||
showPhoneDialog: false
|
||
}
|
||
},
|
||
onShow() {
|
||
this.initData();
|
||
},
|
||
methods: {
|
||
// 新增:协议勾选状态变化
|
||
handleAgreementChange(e) {
|
||
this.agreementChecked = e.detail.value.length > 0;
|
||
},
|
||
|
||
// 新增:跳转到协议页面
|
||
goToAgreement(type) {
|
||
if (type === 'user') {
|
||
uni.navigateTo({
|
||
url: '/pages/userAgreement/index'
|
||
});
|
||
} else {
|
||
uni.navigateTo({
|
||
url: '/pages/agreement/index'
|
||
});
|
||
}
|
||
},
|
||
|
||
// 点击头像触发上传
|
||
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) {
|
||
const file = {
|
||
url: tempFilePaths[0]
|
||
};
|
||
this.handleAvatarUpload({ file });
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择图片失败', err);
|
||
uni.showToast({
|
||
title: '选择图片失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
handleCloseModal() {
|
||
this.showPhoneDialog = false;
|
||
},
|
||
|
||
// 初始化数据
|
||
async initData() {
|
||
const token = uni.getStorageSync('token');
|
||
if (token) {
|
||
try {
|
||
const res = await get('/api/v1/app_auth/mine');
|
||
if (res && res.success) {
|
||
uni.setStorageSync('userInfo', res.data);
|
||
this.updateUserInfo(res.data);
|
||
this.isLogin = true;
|
||
} else {
|
||
this.clearUserData();
|
||
}
|
||
} catch (err) {
|
||
console.error('获取用户信息失败:', err);
|
||
this.clearUserData();
|
||
}
|
||
} else {
|
||
this.clearUserData();
|
||
}
|
||
},
|
||
|
||
// 更新用户信息
|
||
updateUserInfo(data) {
|
||
const avatarUrl = data.avatar ? `${IMAGE_BASE_URL}${data.avatar}` : '/static/imgs/index/nav.png';
|
||
this.userInfo = {
|
||
nickName: data.name || data.nickName || '未命名用户',
|
||
avatarUrl: avatarUrl,
|
||
bio: data.introduce || data.bio || '这家伙很懒,什么都没有写~',
|
||
phone: data.phone || ''
|
||
};
|
||
this.displayAvatar = this.userInfo.avatarUrl;
|
||
this.formData = {
|
||
name: this.userInfo.nickName,
|
||
bio: this.userInfo.bio
|
||
};
|
||
if (this.userInfo.avatarUrl) {
|
||
this.avatarList = [{
|
||
url: this.userInfo.avatarUrl
|
||
}];
|
||
}
|
||
},
|
||
|
||
// 清除用户数据
|
||
clearUserData() {
|
||
this.isLogin = false;
|
||
this.userInfo = {
|
||
nickName: '未登录用户',
|
||
avatarUrl: '/static/imgs/index/nav.png',
|
||
bio: '这家家伙很懒,什么都没有写~'
|
||
};
|
||
this.formData = {
|
||
name: '',
|
||
bio: ''
|
||
};
|
||
this.avatarList = [];
|
||
uni.removeStorageSync('token');
|
||
uni.removeStorageSync('userInfo');
|
||
},
|
||
|
||
// 处理编辑点击
|
||
handleEditClick() {
|
||
if (!this.isLogin) {
|
||
this.showEditModal = true;
|
||
return;
|
||
}
|
||
this.formData = {
|
||
name: this.userInfo.nickName,
|
||
bio: this.userInfo.bio
|
||
};
|
||
if (this.userInfo.avatarUrl) {
|
||
this.avatarList = [{
|
||
url: this.userInfo.avatarUrl
|
||
}];
|
||
} else {
|
||
this.avatarList = [];
|
||
}
|
||
this.showEditModal = true;
|
||
},
|
||
|
||
// 获取用户信息 - 修改方法名和逻辑
|
||
onGetUserInfo(e) {
|
||
if (!this.agreementChecked) {
|
||
uni.showToast({
|
||
title: '请先阅读并同意协议',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (e.detail.userInfo) {
|
||
this.userInfo.nickName = e.detail.userInfo.nickName;
|
||
this.userInfo.avatarUrl = e.detail.userInfo.avatarUrl;
|
||
this.wxLogin();
|
||
} else {
|
||
uni.showToast({
|
||
title: '您拒绝了授权',
|
||
icon: 'none'
|
||
});
|
||
this.showEditModal = false;
|
||
}
|
||
},
|
||
|
||
// 微信登录获取code - 修改方法名
|
||
wxLogin() {
|
||
uni.showLoading({
|
||
title: '登录中...'
|
||
});
|
||
this.showEditModal = false;
|
||
uni.login({
|
||
provider: 'weixin',
|
||
success: (loginRes) => {
|
||
this.sendLoginRequest(loginRes.code);
|
||
},
|
||
fail: (err) => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '登录失败',
|
||
icon: 'none'
|
||
});
|
||
console.error('登录失败:', err);
|
||
}
|
||
});
|
||
},
|
||
|
||
// 发送登录请求
|
||
async sendLoginRequest(code) {
|
||
try {
|
||
const res = await post('/api/v1/apps/login/weixins', {
|
||
code: code
|
||
});
|
||
if (res.success) {
|
||
uni.setStorageSync('token', res.data.access_token);
|
||
if (!res.data.phone) {
|
||
this.showPhoneButton = true;
|
||
uni.showToast({
|
||
title: '请授权获取手机号',
|
||
icon: 'none'
|
||
});
|
||
} else {
|
||
await this.loginComplete(res.data);
|
||
}
|
||
} else {
|
||
throw new Error(res.message || '登录失败');
|
||
}
|
||
} catch (err) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '登录失败,请稍后再试',
|
||
icon: 'none'
|
||
});
|
||
console.error('登录接口错误:', err);
|
||
}
|
||
},
|
||
|
||
// 获取手机号
|
||
async getPhoneNumber(e) {
|
||
if (!this.agreementChecked) {
|
||
uni.showToast({
|
||
title: '请先阅读并同意协议',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (e.detail.errMsg !== "getPhoneNumber:ok") {
|
||
uni.showToast({
|
||
title: '获取手机号失败',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
uni.showLoading({
|
||
title: '获取手机号中...'
|
||
});
|
||
try {
|
||
const res = await post('/api/v1/app_auth/weixin/bind_phone', {
|
||
code: e.detail.code
|
||
});
|
||
if (res.success) {
|
||
await this.loginComplete(res.data);
|
||
} else {
|
||
throw new Error(res.message || '绑定手机号失败');
|
||
}
|
||
} catch (err) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '绑定手机号失败',
|
||
icon: 'none'
|
||
});
|
||
console.error('绑定手机号失败:', err);
|
||
}
|
||
},
|
||
|
||
// 登录完成处理
|
||
async loginComplete(data) {
|
||
try {
|
||
this.showEditModal = false;
|
||
const res = await get('/api/v1/app_auth/mine');
|
||
if (res && res.success) {
|
||
uni.setStorageSync('userInfo', res.data);
|
||
this.updateUserInfo(res.data);
|
||
this.isLogin = true;
|
||
this.showPhoneButton = false;
|
||
uni.showToast({
|
||
title: '登录成功'
|
||
});
|
||
} else {
|
||
throw new Error(res.message || '获取用户信息失败');
|
||
}
|
||
} catch (err) {
|
||
uni.showToast({
|
||
title: '登录失败: ' + err.message,
|
||
icon: 'none'
|
||
});
|
||
console.error('登录完成处理失败:', err);
|
||
}
|
||
},
|
||
|
||
// 上传头像
|
||
async handleAvatarUpload(event) {
|
||
if (!this.isLogin) {
|
||
this.showEditModal = true;
|
||
return;
|
||
}
|
||
const {
|
||
file
|
||
} = event;
|
||
if (!file || !file.url) return;
|
||
this.uploading = true;
|
||
try {
|
||
const fileInfo = await new Promise((resolve, reject) => {
|
||
uni.getFileInfo({
|
||
filePath: file.url,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
});
|
||
if (fileInfo.size > 3 * 1024 * 1024) {
|
||
throw new Error('图片大小不能超过3MB');
|
||
}
|
||
const avatarUrl = await this.uploadAvatar(file.url);
|
||
await this.updateUserAvatar(avatarUrl);
|
||
uni.showToast({
|
||
title: '头像上传成功'
|
||
});
|
||
} catch (error) {
|
||
console.error('头像上传失败:', error);
|
||
uni.showToast({
|
||
title: '头像上传失败: ' + error.message,
|
||
icon: 'none'
|
||
});
|
||
} finally {
|
||
this.uploading = false;
|
||
}
|
||
},
|
||
|
||
// 上传头像到服务器
|
||
uploadAvatar(filePath) {
|
||
return new Promise((resolve, reject) => {
|
||
uni.uploadFile({
|
||
url: `${IMAGE_BASE_URL}/api/v1/upload`,
|
||
filePath: filePath,
|
||
name: 'file',
|
||
header: {
|
||
'Authorization': `Bearer ${uni.getStorageSync('token')}`
|
||
},
|
||
success: (uploadRes) => {
|
||
try {
|
||
const res = JSON.parse(uploadRes.data);
|
||
if (res && res.success) {
|
||
resolve(res.data);
|
||
} else {
|
||
reject(new Error(res.message || '上传失败'));
|
||
}
|
||
} catch (e) {
|
||
reject(new Error('解析响应失败'));
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error('上传失败: ' + JSON.stringify(err)));
|
||
}
|
||
});
|
||
});
|
||
},
|
||
|
||
// 更新用户头像
|
||
async updateUserAvatar(avatarUrl) {
|
||
try {
|
||
await post('/api/v1/app_auth/bind', {
|
||
avatar: avatarUrl,
|
||
introduce: this.formData.bio,
|
||
name: this.formData.name
|
||
});
|
||
const res = await get('/api/v1/app_auth/mine');
|
||
if (res && res.success) {
|
||
uni.setStorageSync('userInfo', res.data);
|
||
this.updateUserInfo(res.data);
|
||
} else {
|
||
throw new Error(res.message || '获取用户信息失败');
|
||
}
|
||
} catch (err) {
|
||
console.error('更新头像失败:', err);
|
||
throw err;
|
||
}
|
||
},
|
||
|
||
// 删除头像
|
||
handleAvatarDelete() {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定要删除当前头像吗?',
|
||
confirmText: '删除',
|
||
cancelText: '取消',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.avatarList = [];
|
||
this.displayAvatar = '/static/imgs/index/nav.png';
|
||
this.userInfo.avatarUrl = '';
|
||
uni.showToast({
|
||
title: '已删除',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
// 提交表单
|
||
async handleSubmit() {
|
||
if (!this.isLogin) return;
|
||
const {
|
||
name,
|
||
bio
|
||
} = this.formData;
|
||
|
||
let avatarUrl = this.avatarList.length > 0 ? this.avatarList[0].url : "";
|
||
if (avatarUrl && avatarUrl.includes(IMAGE_BASE_URL)) {
|
||
avatarUrl = avatarUrl.replace(IMAGE_BASE_URL, '');
|
||
}
|
||
if (!name) {
|
||
uni.showToast({
|
||
title: '请输入姓名',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
uni.showLoading({
|
||
title: '提交中...'
|
||
});
|
||
try {
|
||
await post('/api/v1/app_auth/bind', {
|
||
avatar: avatarUrl,
|
||
introduce: bio,
|
||
name: name
|
||
});
|
||
const res = await get('/api/v1/app_auth/mine');
|
||
if (res && res.success) {
|
||
uni.setStorageSync('userInfo', res.data);
|
||
this.updateUserInfo(res.data);
|
||
this.showEditModal = false;
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '修改成功'
|
||
});
|
||
} else {
|
||
throw new Error(res.message || '获取用户信息失败');
|
||
}
|
||
} catch (err) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '修改失败: ' + (err.message || '未知错误'),
|
||
icon: 'none'
|
||
});
|
||
console.error('修改失败:', err);
|
||
}
|
||
},
|
||
|
||
// 取消修改
|
||
handleCancel() {
|
||
this.showEditModal = false;
|
||
},
|
||
|
||
// 跳转页面
|
||
goPage(item) {
|
||
if (item.key === 6) {
|
||
this.handleContactCommunity();
|
||
return;
|
||
}
|
||
if (item.key === 5) {
|
||
this.handleEditClick();
|
||
return;
|
||
}
|
||
if (!this.checkLogin()) {
|
||
this.showEditModal = true;
|
||
return;
|
||
}
|
||
if (item.pageUrl) {
|
||
uni.navigateTo({
|
||
url: `/pages/${item.pageUrl}/index`
|
||
});
|
||
}
|
||
},
|
||
|
||
// 处理联系社区点击
|
||
handleContactCommunity() {
|
||
if (!this.checkLogin()) {
|
||
this.showEditModal = true;
|
||
return;
|
||
}
|
||
|
||
uni.showModal({
|
||
title: '联系社区',
|
||
content: '是否要拨打社区电话:' + this.communityPhone,
|
||
confirmText: '拨打',
|
||
cancelText: '取消',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.callCommunityPhone();
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
// 拨打社区电话
|
||
callCommunityPhone() {
|
||
uni.makePhoneCall({
|
||
phoneNumber: this.communityPhone,
|
||
success: () => {
|
||
console.log('拨打电话成功');
|
||
},
|
||
fail: (err) => {
|
||
uni.showToast({
|
||
title: '拨打电话失败',
|
||
icon: 'none'
|
||
});
|
||
console.error('拨打电话失败:', err);
|
||
}
|
||
});
|
||
this.showPhoneDialog = false;
|
||
},
|
||
|
||
// 检查登录状态
|
||
checkLogin() {
|
||
const token = uni.getStorageSync('token');
|
||
if (!token) {
|
||
uni.showToast({
|
||
title: '请先登录',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.profile-page {
|
||
background-color: #f5f7fa;
|
||
padding: 20rpx;
|
||
min-height: 100vh;
|
||
box-sizing: border-box;
|
||
padding-bottom: calc(100rpx + 50rpx);
|
||
}
|
||
.user-info-card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 40rpx 30rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
||
.user-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
}
|
||
.avatar-section {
|
||
margin-bottom: 20rpx;
|
||
.avatar-wrapper {
|
||
position: relative;
|
||
width: 140rpx;
|
||
height: 140rpx;
|
||
.avatar {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 50%;
|
||
border: 4rpx solid #fff;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
.edit-icon {
|
||
position: absolute;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: #2979ff;
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
.u-loading-icon {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.3);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 1;
|
||
}
|
||
}
|
||
}
|
||
.name-section {
|
||
width: 100%;
|
||
align-items: center;
|
||
text-align: center;
|
||
margin-bottom: 30rpx;
|
||
.name {
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
.phone {
|
||
color: #999;
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
.description-card {
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
padding: 24rpx;
|
||
width: 100%;
|
||
text-align: center;
|
||
.title {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
margin-bottom: 12rpx;
|
||
display: block;
|
||
}
|
||
.content {
|
||
font-size: 26rpx;
|
||
color: #999;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
.function-card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 0 30rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
||
.button-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 28rpx 0;
|
||
border-bottom: 1rpx solid #f2f3f5;
|
||
&:active {
|
||
background-color: #f8f8f8;
|
||
}
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.button-content {
|
||
display: flex;
|
||
align-items: center;
|
||
flex: 1;
|
||
}
|
||
.icon {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
margin-right: 24rpx;
|
||
}
|
||
.label {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
.modal-content {
|
||
padding: 0 30rpx;
|
||
width: 90%;
|
||
margin: 0 auto;
|
||
max-height: 70vh;
|
||
overflow-y: auto;
|
||
/* 编辑表单区域 */
|
||
.edit-section {
|
||
padding: 20rpx 0;
|
||
.form-item {
|
||
margin-bottom: 40rpx;
|
||
.form-label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #606266;
|
||
margin-bottom: 16rpx;
|
||
font-weight: 500;
|
||
}
|
||
.upload-tip {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-top: 10rpx;
|
||
text-align: center;
|
||
}
|
||
.word-count {
|
||
text-align: right;
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-top: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
/* 授权登录区域 - 修改相关文案和图标 */
|
||
.auth-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 40rpx 0;
|
||
.auth-title {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
margin-bottom: 40rpx;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
}
|
||
.auth-button {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
height: 90rpx;
|
||
background: #2979ff;
|
||
color: #fff;
|
||
font-size: 30rpx;
|
||
border-radius: 45rpx;
|
||
margin-bottom: 20rpx;
|
||
padding: 0 30rpx;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3);
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
|
||
.auth-icon,
|
||
.phone-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 15rpx;
|
||
}
|
||
}
|
||
|
||
.phone-button {
|
||
background: #07C160; /* 微信绿色,保持原有成功色 */
|
||
}
|
||
.auth-agreement {
|
||
margin-top: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
.agreement-link {
|
||
color: #2979ff;
|
||
}
|
||
}
|
||
}
|
||
.phone-dialog-content {
|
||
padding: 40rpx;
|
||
text-align: center;
|
||
font-size: 32rpx;
|
||
.phone-number {
|
||
font-weight: bold;
|
||
color: #2979ff;
|
||
margin-left: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 头像上传容器
|
||
.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> |