xcxFront/pages/ucenter/profile.vue

354 lines
7.9 KiB
Vue
Raw Normal View History

2024-11-05 10:14:41 +08:00
<template>
<view class="profile-page">
<tn-navbar fixed :bottom-shadow="false" />
<view class="user-info">
<view class="avatar-nickname">
<view class="left">
<view class="nickname">
{{ userInfo.nickname?userInfo.nickname:userInfo.username }}
</view>
<view class="desc">
<input
class="input"
v-model ="userInfo.desc"
placeholder="请输入描述"
placeholder-style="color: var(--tn-color-gray-disabled)"
/>
</view>
</view>
<view class="avatar">
<tn-button class="tn-w-full tn-h-full" bg-color="#fff" width="100%" height="100%" shape="circle" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image class="tn-image" :src="userInfo.avatar" mode="aspectFill" />
</tn-button>
</view>
</view>
<view class="info-item">
<view class="left">
<view class="item-title">登录名</view>
<view class="content">
<input
class="input"
v-model="userInfo.username"
placeholder="请设置登录名"
placeholder-style="color: var(--tn-color-gray-disabled)"
/>
</view>
</view>
</view>
<view class="info-item">
<view class="left">
<view class="item-title">昵称</view>
<view class="content">
<input
class="input"
v-model="userInfo.nickname"
placeholder="请输入昵称"
placeholder-style="color: var(--tn-color-gray-disabled)"
type="nickname"
@blur="bindName"
/>
</view>
</view>
</view>
<view class="info-item">
<view class="left">
<view class="item-title">密码</view>
<view class="content">
<input
class="input"
type="password"
v-model="userInfo.password"
placeholder="请设置密码"
placeholder-style="color: var(--tn-color-gray-disabled)"
@blur="change('password')"
/>
</view>
</view>
</view>
<view class="info-item" @tap.stop="openSexPicker">
<view class="left">
<view class="item-title">性别</view>
<view class="content">
{{ UserSex?.[userInfo.sex] || '请选择性别' }}
</view>
</view>
<view class="right">
<tn-icon name="right" />
</view>
</view>
<view class="info-item" @click="bindWechat">
<view class="left">
<view class="item-title">绑定微信</view>
<view class="content">
{{ userInfo.openid || '未绑定' }}
</view>
</view>
<view class="right">
<tn-icon name="right" />
</view>
</view>
<view class="clear-cache tn-red_shadow tn-mt">
<view class="text tn-text-lg tn-text-center tn-red_text tn-text-bold tn-shadow-blur" @click="saveUser">
保存
</view>
</view>
<view class="logout tn-red_shadow">
<view class="text tn-text-lg tn-text-center tn-red_text tn-text-bold tn-shadow-blur" @click="openModal">
退出登录
</view>
</view>
</view>
<!-- 性别选择 -->
<tn-picker
v-model:open="showSexPicker"
v-model="userInfo.sex"
:data="sexPickerData"
@confirm="change('sex')"
/>
<tn-modal ref="modalRef" />
</view>
</template>
<script lang='ts' setup>
import { reactive, ref } from 'vue';
import baseUrl from '@/config/config';
import TnModal from '@/uni_modules/tuniaoui-vue3/components/modal/src/modal.vue'
import type { TnModalInstance } from '@/uni_modules/tuniaoui-vue3/components/modal'
import TnPicker from '@/uni_modules/tuniaoui-vue3/components/picker/src/picker.vue'
import storage from '@/utils/storage';
const modalRef = ref<TnModalInstance>()
const UserSex = ref(['保密','男','女'])
const userInfo = reactive({
id:undefined,
username:'',
nickname:'',
password:'',
openid:'',
avatar:'',
sex:0,
deleted:'',
right:'',
isAdmin:'',
desc:''
})
const showSexPicker = ref<boolean>(false)
const onChooseAvatar = (e) => {
console.log(e)
userInfo.avatar = e.detail.avatarUrl
}
const bindName = (e) => {
userInfo.nickname = e.detail.value
}
const sexPickerData = [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '保密', value: 0 },
]
const change = (item:string) => {
const data = {
uid:userInfo.id
}
if(item === 'password'){
Object.assign(data,{password:userInfo.password})
}
if(item === 'sex'){
Object.assign(data,{sex:userInfo.sex})
}
uni.request({
url:baseUrl + '/front/update_user',
method:'PUT',
data:data,
success: (res:any) => {
if(res.data.code === 0){
storage.set('storageUser',userInfo)
}
uni.showToast({
icon:'none',
title:res.data.message
})
}
})
}
const openSexPicker = () => {
showSexPicker.value = true
}
const openModal = () => {
modalRef.value?.showModal({
title: '退出登录',
content: '确定要退出登录?',
showCancel: true,
confirm: () => {
storage.remove('storageUser')
storage.remove('isLogin')
storage.remove('token')
uni.redirectTo({
url:'/pages/entry/index'
})
}
})
}
const saveUser = () => {
const data = {
uid:userInfo.id,
desc:userInfo.desc,
username:userInfo.username,
nickname:userInfo.nickname
}
uni.request({
url:baseUrl + '/front/update_user',
method:'PUT',
data:data,
success: (res:any) => {
if(res.data.code === 0){
storage.set('storageUser',userInfo)
}
uni.showToast({
icon:'none',
title:res.data.message
})
}
})
}
const bindWechat = () => {
if(userInfo.openid){
uni.showToast({
icon:'none',
title:'请不要重复绑定!'
})
return;
}
uni.login({
provider:'weixin',
success: (loginRes) => {
uni.request({
url:baseUrl + '/front/bind',
method:'POST',
data:{uid:userInfo.id,code:loginRes.code},
success: (res:any) => {
if(res.data.code === 0){
userInfo.openid = '已绑定';
storage.set('storageUser',userInfo)
}
uni.showToast({
icon:'none',
title:res.data.message
})
}
})
}
})
}
const getUserInfo = () => {
let storageUser = storage.get('storageUser')
Object.assign(userInfo,storageUser)
}
getUserInfo()
</script>
<style lang="scss" scoped>
.user-info {
position: relative;
width: 100%;
padding: 30rpx 0rpx;
.input {
padding: 0;
color: var(--tn-color-gray);
}
/* nickname、头像 start */
.avatar-nickname {
position: relative;
width: 100%;
padding: 30rpx;
display: flex;
align-items: center;
border-bottom: 20rpx solid var(--tn-color-gray-light);
.left {
flex: 1;
.nickname {
width: 100%;
font-size: 32rpx;
font-weight: bold;
}
.desc {
width: 100%;
margin-top: 10rpx;
}
}
.avatar {
flex-grow: 0;
flex-shrink: 0;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
}
/* nickname、头像 end */
/* 信息item start */
.info-item {
position: relative;
width: 100%;
padding: 30rpx;
display: flex;
align-items: center;
.left {
flex: 1;
.item-title {
width: 100%;
font-size: 32rpx;
font-weight: bold;
}
.content {
margin-top: 10rpx;
color: var(--tn-color-gray);
}
}
.right {
flex-grow: 0;
flex-shrink: 0;
margin-left: 12rpx;
}
& + .info-item {
border-top: 1rpx solid var(--tn-color-gray-light);
}
}
/* 信息item end */
.logout,
.clear-cache{
width: 100%;
padding: 30rpx;
border-bottom: 20rpx solid var(--tn-color-gray-light);
}
.clear-cache {
border-top: 20rpx solid var(--tn-color-gray-light);
}
}
</style>