shop_app/pages/user/info.vue

353 lines
8.1 KiB
Vue
Raw Normal View History

2025-05-08 09:16:37 +08:00
<template>
<view class="whole">
<view class="content">
<view class="infobox">
<view class="item">
<text>头像</text>
<view class="right" @click="editAvatar">
<image class="avatar" :src="avatarUrl" mode="aspectFill"></image>
<up-icon name="arrow-right" color="#999" size="14" />
</view>
</view>
<view class="item">
<text>昵称</text>
<view class="right">
<input type="input" v-model="nickName" class="nickname" placeholder="请输入昵称" />
</view>
</view>
<view class="item">
<text>生日</text>
<view class="right" @click="openTime()">
<text>{{info.birthday}}</text>
<up-icon name="arrow-right" color="#999" size="14" />
</view>
</view>
<view class="item">
<text>注销账户</text>
<view class="right" @click="toLogOff()">
<up-icon name="arrow-right" color="#999" size="14" />
</view>
</view>
</view>
</view>
<view class="bottom">
<view class="btn" @click="commitInfo()">&nbsp;</view>
</view>
<view class="out" @click="loginOut()">退出登录</view>
<up-datetime-picker
:show="showTime"
v-model="currentDate"
mode="date"
:minDate="minDate"
@confirm="chooseTimes"
@cancel="showTime = false"
@close="showTime = false"
:confirmColor="Color"
:closeOnClickOverlay="true">
</up-datetime-picker>
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import { get, post } from '@/api/request.js'
import { showToast, getUserInfo, getUserPhone } from '@/components/common.js'
import API from '/api/index'
import dayjs from 'dayjs'
import { func } from '../../uni_modules/uview-plus/libs/function/test'
export default {
setup() {
const data = reactive({
info: {},
nickName: '',
avatarUrl: '',
chooseImg: false,
showTime: false,
currentDate: '',
is_default_avatar: uni.getStorageSync('is_default_avatar'),
Color: uni.getStorageSync('theme_color'),
minDate: new Date('1900-01-01').getTime()
})
function getInfo() {
get('/api/v1/user/detail').then((res) => {
data.info = res.data
data.nickName = res.data.nickname
data.avatarUrl = res.data.avatar
})
}
function editAvatar() {
uni.chooseImage({
success(res) {
const tempFilePaths = res.tempFilePaths
uni.showLoading({
title: '正在上传...',
mask: true
})
uni.uploadFile({
url: API.url + '/api/v1/upload',
filePath: tempFilePaths[0],
name: 'file',
header: {
Authorization: uni.getStorageSync('token') || '',
accept: 'application/json',
appid: API.appId
},
success(req) {
let img = JSON.parse(req.data).data
data.avatarUrl = img.link
uni.hideLoading()
},
fail() {
uni.hideLoading()
}
})
},
fail() {
}
})
}
function commitInfo() {
if(!data.nickName) {
showToast('请输入您的昵称')
return
}
if(data.avatarUrl) {
uni.showLoading({
mask: true,
title: '正在保存'
})
// 如果不是默认图片则直接提交
if(!data.is_default_avatar) {
post('/api/v1/user', { nickname: data.nickName, avatar: data.avatarUrl }, 'PUT').then( res => {
uni.hideLoading()
wx.showToast({
title: '已保存',
icon: 'success',
duration: 1000,
mask: true,
success() {
uni.setStorageSync('nickname', data.nickName)
uni.setStorageSync('avatar', data.avatarUrl)
uni.setStorageSync('is_authorized', 1)
uni.setStorageSync('is_default_avatar', false)
setTimeout(() => {
wx.navigateBack({ delta: 1 })
}, 1000)
}
})
})
} else {
wx.uploadFile({
url: API.url + '/api/v1/upload',
filePath: data.avatarUrl,
name: 'file',
header: {
Authorization: uni.getStorageSync('token') || '',
accept: 'application/json',
appid: API.appId
},
success(res) {
let url = JSON.parse(res.data).data.link
post('/api/v1/user', { nickname: data.nickName, avatar: url }, 'PUT').then( res => {
uni.hideLoading()
wx.showToast({
title: '已保存',
icon: 'success',
duration: 1000,
mask: true,
success() {
uni.setStorageSync('nickname', data.nickName)
uni.setStorageSync('avatar', url)
uni.setStorageSync('is_authorized', 1)
uni.setStorageSync('is_default_avatar', false)
setTimeout(() => {
wx.navigateBack({ delta: 1 })
}, 1000)
}
})
}).catch((error) => {
uni.hideLoading()
})
},
fail(error) {
uni.hideLoading()
showToast('头像上传失败')
}
})
}
} else {
showToast('请上传您的头像')
}
}
const openTime = () => {
data.currentDate = data.info.birthday ? Date.parse(new Date(data.info.birthday)) : Date.parse(new Date())
data.showTime = true
}
const chooseTimes = (e) => {
data.info.birthday = dayjs(e.value).format('YYYY-MM-DD')
data.showTime = false
}
async function getPhoneNumber(e) {
if(e.detail.errMsg == 'getPhoneNumber:ok') {
await getUserPhone(e.detail).then((res) => {
const reg = /^(\d{3})(\d{4})(\d{4})$/
data.info.mobile = res.data.mobile.replace(reg, "$1****$3")
})
}
}
function loginOut() {
uni.removeStorageSync('token')
uni.removeStorageSync('saveTime')
uni.removeStorageSync('expires_in')
uni.removeStorageSync('login_type')
uni.removeStorageSync('unionid_open')
uni.switchTab({
url: '/pages/index/index'
})
}
function toLogOff() {
uni.showModal({
title: '提示',
content: '确定要注销当前账户吗?',
confirmColor: '#42b983',
success(res) {
if (res.confirm) {
uni.removeStorageSync('token')
uni.removeStorageSync('saveTime')
uni.removeStorageSync('expires_in')
uni.removeStorageSync('login_type')
uni.removeStorageSync('unionid_open')
uni.switchTab({
url: '/pages/index/index'
})
}
}
})
}
return {
...toRefs(data),
commitInfo,
editAvatar,
openTime,
chooseTimes,
getPhoneNumber,
getInfo,
loginOut,
toLogOff
}
},
async onLoad(options) {
this.nickName = uni.getStorageSync('nickname')
this.avatarUrl = uni.getStorageSync('avatar')
this.getInfo()
}
}
</script>
<style lang="scss" scoped>
.whole{
width: 100%;
height: 100vh;
background: #fff;
.content{
position: relative;
.dialog{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
}
.infobox{
padding: 0 30rpx;
.item{
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 0;
text{
font-size: 28rpx;
color: #333;
}
.right{
display: flex;
align-items: center;
width: 50%;
justify-content: flex-end;
}
.avatar{
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
border-radius: 5px;
}
.nickname{
width: 300rpx;
font-size: 28rpx;
color: #333;
text-align: right;
&.center{
padding-right: 20rpx;
}
}
.avatar-wrapper{
line-height: normal;
height: 80rpx;
display: flex;
align-items: center;
}
}
}
}
.bottom{
width: 100%;
padding: 0 30rpx;
box-sizing: border-box;
margin-top: 100rpx;
.btn{
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
width: 100%;
color: #fff;
border-radius: 80rpx;
background: v-bind('Color');
}
}
.out{
background-color: #fff;
height: 80rpx;
color: #333;
font-size: 28rpx;
text-align: center;
line-height: 80rpx;
border-top: 20rpx solid #f5f5f5;
border-bottom: 20rpx solid #f5f5f5;
position: fixed;
left: 0;
width: 100%;
bottom: 0;
}
</style>