mrr.sj.front/pages/my/profile.vue

594 lines
14 KiB
Vue
Raw Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view class="profile-page">
<!-- 顶部导航栏 -->
<custom-navbar
title="个人资料"
:show-back="true"
></custom-navbar>
<!-- 个人资料列表 -->
<view class="profile-list">
<!-- 头像 -->
<view class="profile-item">
<text class="item-label">头像</text>
<view class="item-content avatar-content" @click="chooseAvatar">
<image :src="!userInfo.head_photo ? baseAvartar : userInfo.head_photo " mode="aspectFill" class="avatar"></image>
</view>
</view>
<!-- 昵称 -->
<view class="profile-item">
<text class="item-label">昵称</text>
<view class="item-content">
<input type="text"
class="item-value item-inp"
:value="userInfo.username"
@input="editNickname"
placeholder="未设置" />
</view>
</view>
<!-- 性别 -->
<view class="profile-item" @click="chooseSex">
<text class="item-label">性别</text>
<view class="item-content">
<text class="item-value">{{userInfo.sex == 1 ? '女' : userInfo.sex == 2 ? '男' : '未设置'}}</text>
</view>
</view>
<!-- 所在地 -->
<view class="profile-item" @click="chooseLocation">
<text class="item-label">所在地</text>
<view class="item-content">
<text class="item-value">{{userInfo.dependency || '未设置'}}</text>
</view>
</view>
<!-- 邀请码 -->
<!-- <view class="profile-item">
<text class="item-label">邀请码</text>
<view class="item-content">
<text class="item-value">{{userInfo.invite_code}}</text>
</view>
</view> -->
</view>
<!-- 编辑按钮 -->
<view class="edit-btn" @click="saveProfile">
<text class="edit-text">保存</text>
</view>
<!-- 所在地省市区选择 -->
<view class="popup" :class="{ show: showLocationPopupFlag }">
<view class="popup-mask" @click="hideLocationPopup"></view>
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">选择所在地</text>
<text class="popup-close" @click="hideLocationPopup">×</text>
</view>
<view class="region-body">
<picker-view @change="bindChangeLocation"
class="picker-scroll"
:indicator-style="indicatorStyle"
:value="locationValue">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in ChinaCitys" :key="index">{{item.province}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in locatinCitys" :key="index">{{item.city}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in locationAreas" :key="index">{{item.area}}</view>
</picker-view-column>
</picker-view>
</view>
<view class="popup-footer">
<view class="popup-btn cancel" @click="hideLocationPopup">
<text class="btn-text">取消</text>
</view>
<view class="popup-btn confirm" @click="confirmLocationSelect">
<text class="btn-text">确定</text>
</view>
</view>
</view>
</view>
<!-- 获取权限提示匡内容 -->
<view class="permission"
:class="{ transform: isShowPer && nowQer === 'xc' }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中读取相册和文件内容</view>
</view>
<view class="permission"
:class="{ transform: isShowPer && nowQer === 'xj' }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request'
import ChinaCitys from '../../static/data/ChinaCitys.json'
import uploadImage from '../../utils/uploadImage'
import permissionUtils from '../../utils/per'
import locationService from '../../utils/locationService';
export default {
data() {
return {
userInfo: {},
indicatorStyle: 'height: 68rpx;',
baseAvartar: 'https://app.mrrweb.com.cn' + '/public/images/headanimal.png',
showLocationPopupFlag: false,
locatinCitys: [],
locationValue: [],
locationAreas: [],
ChinaCitys: '',
isShowPer: false,
nowQer: 'xc'
}
},
onLoad() {
this.ChinaCitys = ChinaCitys;
this.locatinCitys = this.ChinaCitys[0].citys;
this.locationAreas = this.locatinCitys[0].areas;
this.getUserInfo();
},
methods: {
getUserInfo() {
request.post('/user/getuser',{type: 1}).then(result=>{
this.userInfo = result.data;
console.log(result)
})
},
hideLocationPopup() {
this.showLocationPopupFlag = false
},
confirmLocationSelect() {
let valueArr = this.locationValue;
let index1 = valueArr[0] || 0;
let index2 = valueArr[1] || 0;
let index3 = valueArr[2] || 0;
let province = this.ChinaCitys[index1].province;
let city = this.locatinCitys[index2].city;
let area = this.locationAreas[index3].area;
this.userInfo.dependency = province + '-' + city + '-' + area;
this.showLocationPopupFlag = false;
},
bindChangeLocation(e) {
this.locationValue = e.detail.value;
let index1 = e.detail.value[0] || 0;
let index2 = e.detail.value[1] || 0;
this.locatinCitys = this.ChinaCitys[index1].citys;
this.locationAreas = this.locatinCitys[index2].areas;
},
// 返回上一页
goBack() {
uni.navigateBack()
},
// 选择头像
// async chooseAvatar() {
// if(!this.isShowPer) {
// this.isShowPer = true;
// }
// const result = await uploadImage.handleUpload(this.userInfo.id,1);
// uni.hideLoading();
// this.userInfo.head_photo = result;
// },
async chooseAvatar() {
try {
const systemInfo = uni.getSystemInfoSync()
if(systemInfo.platform === 'ios') {
this.openCamera();
}else {
let xcpermission = '';
let xjpermission = '';
if(systemInfo.platform === 'ios') {
xcpermission = 'photo_library',
xjpermission = 'camera'
}else {
xcpermission = `android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE`
xjpermission = 'android.permission.CAMERA'
}
const xcfirstRequest = !plus.storage.getItem(`perm_${xcpermission}`)
const xjfirstRequest = !plus.storage.getItem(`perm_${xjpermission}`)
if(xcfirstRequest || xjfirstRequest) {
this.isShowPer = true;
}
// 1. 检查权限
// const { granted } = await permissionUtils.checkPermission('photo_library', '需要相册权限用于上传照片');
this.nowQer = 'xc';
const xc = await permissionUtils.checkPermission('photo_library', '需要相册权限用于上传照片');
this.nowQer = 'xj';
const xj = await permissionUtils.checkPermission('camera', '需要相机权限用于拍摄照片');
this.isShowPer = false;
this.nowQer = '';
if (xc.granted && xj.granted) {
this.openCamera();
return;
}
// 2. 显示权限说明弹窗
const confirm = await this.showPermissionDialog(
'相机相册权限申请',
'我们需要访问您的相机以及相册以完成更换头像功能'
);
if (!confirm) return;
// 3. 请求权限
const result1 = await permissionUtils.requestPermission('photo_library', '我们需要访问您的相册以上传图片');
const result2 = await permissionUtils.requestPermission('camera', '我们需要访问您的相机以上传图片');
if (result1 && result2) {
this.openCamera();
} else {
locationService.openAppSettings();
// uni.showToast({ title: '相机权限被拒绝', icon: 'none' });
}
}
} catch (error) {
console.error('权限处理出错:', error);
uni.showToast({ title: '权限检查失败', icon: 'none' });
}
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 打开相机
async openCamera() {
this.isShowPer = false;
const result = await uploadImage.handleUpload(this.userInfo.id,1);
uni.hideLoading();
this.userInfo.head_photo = result;
},
// chooseAvatar() {
// uni.chooseImage({
// count: 1,
// sizeType: ['compressed'],
// sourceType: ['album', 'camera'],
// success: (res) => {
// this.userInfo.avatar = res.tempFiles[0].path;
// // TODO: 上传头像到服务器
// request.uploadImage('/user/uploadphoto',res.tempFiles[0].path,{type: 'image'}).then(result=>{
// if(result.message == '上传成功') {
// uni.hideLoading();
// this.userInfo.head_photo = result.path;
// }
// })
// }
// })
// },
// 编辑昵称
editNickname(e) {
this.userInfo.username = e.detail.value;
},
// 选择性别
chooseSex() {
uni.showActionSheet({
itemList: ['男', '女'],
success: (res) => {
this.userInfo.sex = [2, 1][res.tapIndex]
}
})
},
// 选择地区
chooseLocation() {
this.showLocationPopupFlag = true;
// uni.chooseLocation({
// success: (res) => {
// this.userInfo.location = res.address
// }
// })
},
// 保存资料
saveProfile() {
uni.showLoading({
title: '保存中...'
})
const data = {
username
}
let {username, head_photo, sex, dependency} = this.userInfo;
request.post('/user/useryhupdate',{username, head_photo, sex, dependency}).then(res=>{
uni.hideLoading()
uni.showToast({
title: '保存成功!',
icon: 'none'
})
// 修改上一页页面信息
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2]
if (prevPage) {
prevPage.$vm.getUserInfo()
}
})
}
}
}
</script>
<style>
.profile-page {
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.2);
z-index: 999;
}
/* 列表样式 */
.profile-list {
background-color: #FFFFFF;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.50);
padding: 0 24rpx;
box-sizing: border-box;
}
.profile-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx 0;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
}
.profile-item:last-child {
border-bottom: none;
}
.item-label {
font-size: 28rpx;
color: #333333;
}
.item-content {
flex: 1;
display: flex;
align-items: center;
justify-content: flex-end;
}
.item-value {
font-size: 28rpx;
color: #333333;
/* margin-right: 16rpx; */
}
.avatar-content {
height: 108rpx;
}
.avatar {
width: 108rpx;
height: 108rpx;
border-radius: 54rpx;
background-color: #333333;
}
/* .arrow-icon {
width: 32rpx;
height: 32rpx;
} */
/* 编辑按钮 */
.edit-btn {
position: fixed;
bottom: 24rpx;
left: 60rpx;
width: 630rpx;
height: 96rpx;
2026-06-02 11:39:23 +08:00
background: #FF4767;
2026-03-24 11:45:13 +08:00
border-radius: 58rpx;
display: flex;
align-items: center;
justify-content: center;
}
.edit-text {
font-size: 40rpx;
color: #FFFFFF;
}
.region-body {
flex: 1;
overflow: hidden;
}
.item-inp {
text-align: right;
}
.picker-scroll {
height: 400rpx;
}
.popup {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.popup.show {
visibility: visible;
opacity: 1;
}
.popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
position: relative;
background-color: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
padding: 32rpx;
transform: translateY(100%);
transition: transform 0.3s ease;
}
.popup.show .popup-content {
transform: translateY(0);
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.popup-title {
font-size: 32rpx;
color: #333333;
font-weight: 500;
}
.popup-close {
font-size: 40rpx;
color: #999999;
padding: 16rpx;
}
.popup-body {
max-height: 600rpx;
overflow-y: auto;
}
.region-tabs {
display: flex;
border-bottom: 1rpx solid #EEEEEE;
margin-bottom: 20rpx;
}
.region-tab {
flex: 1;
text-align: center;
padding: 20rpx 0;
font-size: 28rpx;
color: #666666;
position: relative;
}
.region-tab.active {
2026-06-02 11:39:23 +08:00
color: #FF4767;
2026-03-24 11:45:13 +08:00
font-weight: 500;
}
.region-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
2026-06-02 11:39:23 +08:00
background-color: #FF4767;
2026-03-24 11:45:13 +08:00
border-radius: 2rpx;
}
.region-body {
flex: 1;
overflow: hidden;
}
.region-scroll {
height: 100%;
}
.picker-scroll {
height: 400rpx;
}
.picker-item {
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
.popup-footer {
display: flex;
margin-top: 32rpx;
}
.popup-btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 0 16rpx;
}
.popup-btn.cancel {
background-color: #F5F5F5;
}
.popup-btn.confirm {
2026-06-02 11:39:23 +08:00
background: linear-gradient(90deg, #FF4767 0%, #FF618F 100%);
2026-03-24 11:45:13 +08:00
}
.popup-btn .btn-text {
font-size: 32rpx;
font-weight: 500;
}
.popup-btn.cancel .btn-text {
color: #666666;
}
.popup-btn.confirm .btn-text {
color: #FFFFFF;
}
/* #ifdef APP-PLUS */
/* .permission {
padding-top: calc(var(--status-bar-height) + 88rpx + 20rpx)
} */
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
/* 平台适配 */
/* #ifdef H5 */
.profile-page {
padding-bottom: env(safe-area-inset-bottom);
}
/* #endif */
/* #ifdef MP-WEIXIN */
.custom-nav {
padding-top: calc(var(--status-bar-height) + constant(safe-area-inset-top));
padding-top: calc(var(--status-bar-height) + env(safe-area-inset-top));
}
/* #endif */
</style>