【小程序】个人资料

This commit is contained in:
洪树泽 2022-09-09 14:27:52 +08:00
parent a54756e081
commit 145f85edf7
3 changed files with 413 additions and 0 deletions

View File

@ -22,4 +22,13 @@ export enum SMSEnum {
export enum SearchTypeEnum {
HISTORY = 'history'
}
// 用户资料
export enum FieldType {
NONE = '',
AVATAR = 'avatar',
USERNAME = 'username',
NICKNAME = 'nickname',
SEX = 'sex',
}

View File

@ -0,0 +1,361 @@
<template>
<!-- Main Start -->
<!-- 头部修改头像 -->
<view class="header bg-white pt-[30rpx]">
<view class="flex justify-center">
<image @click="uploaderAvatar"
:src="userInfo?.avatar ? userInfo?.avatar : '/static/images/icon_default_user.png'"></image>
</view>
<view class="mt-[20rpx] text-center text-muted text-xs" @click="uploaderAvatar">点击修改头像</view>
</view>
<!-- 用户ID -->
<view class="item text-nr flex justify-between" @click="(showUserName = true), (newUsername = userInfo?.username)">
<view class="label">账号</view>
<view class="content">{{ userInfo?.username }}</view>
<u-icon name="arrow-right" size="22"></u-icon>
</view>
<!-- 昵称 -->
<view class="item text-nr flex justify-between" @click="(showNickName = true), (newNickname = userInfo?.nickname)">
<view class="label">昵称</view>
<view class="content">{{ userInfo?.nickname }}</view>
<u-icon name="arrow-right" size="22"></u-icon>
</view>
<!-- 性别 -->
<view class="item text-nr flex justify-between" @click="changeSex">
<view class="label">性别</view>
<view class="content">{{ userInfo?.sex }}</view>
<u-icon name="arrow-right" size="22"></u-icon>
</view>
<!-- 手机号 -->
<view class="item text-nr flex justify-between">
<view class="label">手机号</view>
<view class="content">{{ userInfo?.mobile == '' ? '未绑定手机号' : userInfo?.mobile }}</view>
<!-- #ifdef MP-WEIXIN -->
<u-button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" size="mini" type="primary" shape="circle" :plain="true">
{{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }}
</u-button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<u-button @click="" size="mini" type="primary" shape="circle" :plain="true">
{{ userInfo?.mobile == '' ? '绑定手机号' : '更换手机号' }}
</u-button>
<!-- #endif -->
</view>
<!-- 注册时间 -->
<view class="item text-nr flex justify-between">
<view class="label">注册时间</view>
<view class="content">{{ userInfo?.createTime }}</view>
</view>
<!-- 昵称修改组件 -->
<u-popup v-model="showNickName" :closeable="true" mode="center" border-radius="20">
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<view class="mb-[70rpx] text-xl text-center">修改昵称</view>
<u-field v-model="newNickname" label="新昵称" placeholder="请输入新的昵称"> </u-field>
<view class="mt-[80rpx]">
<u-button @click="changeNameConfirm" type="primary" shape="circle">
确定
</u-button>
</view>
</view>
</u-popup>
<!-- 账号修改组件 -->
<u-popup v-model="showUserName" :closeable="true" mode="center" border-radius="20">
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<view class="mb-[70rpx] text-xl text-center">修改账号</view>
<u-field v-model="newUsername" label="新账号" placeholder="请输入新的账号"> </u-field>
<view class="mt-[80rpx]">
<u-button @click="changeUserNameConfirm" type="primary" shape="circle">
确定
</u-button>
</view>
</view>
</u-popup>
<!-- 性别修改组件 -->
<u-picker mode="selector" v-model="showPicker" confirm-color="#4173FF" :default-selector="[0]" :range="sexList"
@confirm="changeSexConfirm" />
<!-- 账号修改组件 -->
<u-popup v-model="showMobilePop" :closeable="true" mode="center" border-radius="20">
<view class="px-[50rpx] py-[40rpx] bg-white" style="width: 85vw">
<view class="mb-[70rpx] text-xl text-center">修改手机号码</view>
<u-form-item borderBottom>
<u-input
class="flex-1"
v-model="newMobile"
placeholder="请输入新的手机号码"
:border="false"
/>
</u-form-item>
<u-form-item borderBottom>
<u-input
class="flex-1"
v-model="mobileCode"
placeholder="请输入验证码"
:border="false"
/>
<view
class="border-l border-solid border-0 border-light pl-3 text-muted leading-4 ml-3 w-[180rpx]"
@click="sendSms"
>
<u-verification-code
ref="uCodeRef"
:seconds="60"
@change="codeChange"
change-text="x秒"
/>
{{ codeTips }}
</view>
</u-form-item>
<view class="mt-[80rpx]">
<u-button @click="changeCodeMobile" type="primary" shape="circle">
确定
</u-button>
</view>
</view>
</u-popup>
</template>
<script lang="ts" setup>
import {
ref,
shallowRef,
} from 'vue'
import {
onShow,
onUnload
} from '@dcloudio/uni-app'
import {
// apiUserInfoGet,
// apiUserInfoSet,
// apiWechatMobileGet,
// apiHasPassword,
getUserInfo,
userEdit,
userBindMobile,
userMnpMobile,
} from '@/api/user.ts'
import { smsSend } from '@/api/app'
import {
FieldType,
SMSEnum,
} from '@/enums/appEnums'
import {
uploadFile
} from '@/utils/util.ts'
import {
getWxCode
} from '@/utils/util'
let wxCode = ref < any | null > ('')
//
let userInfo = ref < any | null > (null)
//
const fieldType = ref(FieldType.NONE)
//
const showNickName = ref < boolean | null > (false)
//
const showUserName = ref < boolean | null > (false)
//
const newNickname = ref < string > ('')
//
const newUsername = ref < string > ('')
//
const mobile = ref < string > ('')
//
const showPicker = ref < boolean | null > (false)
//
const sexList = ref < Array < string > | null > (['男', '女'])
//
const showMobilePop = ref < boolean | null > (true)
//
const newMobile = ref < string > ('')
//
const mobileCode = ref <string > ('')
const codeTips = ref('')
const uCodeRef = shallowRef()
const codeChange = (text: string) => {
codeTips.value = text
}
//
const sendSms = async () => {
if (!newMobile.value) return uni.$u.toast('请输入新的手机号码')
if (uCodeRef.value?.canGetCode) {
await smsSend({
scene: userInfo.mobile ? SMSEnum.CHANGE_MOBILE : SMSEnum.BIND_MOBILE,
mobile: newMobile.value
})
uni.$u.toast('发送成功')
uCodeRef.value?.start()
}
}
//
const changeCodeMobile = async () => {
await userBindMobile({
type: userInfo.mobile ? 'change' : 'bind',
mobile: newMobile.value,
code: mobileCode.value,
})
getUser()
}
//
const getUser = async (): Promise < void > => {
userInfo.value = await getUserInfo()
}
//
const setUserInfoFun = async (value: string): Promise < void > => {
await userEdit({
field: fieldType.value,
value: value,
})
getUser()
}
//
const uploaderAvatar = () => {
fieldType.value = FieldType.AVATAR
uni.navigateTo({
url: '/uni_modules/uview-ui/components/u-avatar-cropper/u-avatar-cropper?destWidth=300&rectWidth=200&fileType=jpg',
})
}
//
const changeNameConfirm = () => {
if (newNickname.value == '') return toast('昵称不能为空')
if (newNickname.value.length > 10) return toast('昵称长度不得超过十位数')
showNickName.value = false
fieldType.value = FieldType.NICKNAME
setUserInfoFun(newNickname.value)
}
//
const changeUserNameConfirm = () => {
if (newUsername.value == '') return toast('账号不能为空')
if (newUsername.value.length > 10) return toast('账号长度不得超过十位数')
fieldType.value = FieldType.USERNAME
setUserInfoFun(newUsername.value)
showUserName.value = false
}
//
const changeSex = () => {
showPicker.value = true
fieldType.value = FieldType.SEX
}
//
const changeSexConfirm = (value) => {
setUserInfoFun(value[0] + 1)
showPicker.value = false
}
//
const getPhoneNumber = async (e): Promise < void > => {
// wxCode.value = await getWxCode()
console.log('wxCode.value', wxCode.value)
fieldType.value = FieldType.MOBILE
const {
encryptedData,
iv
} = e.detail
let data = {
code: wxCode.value,
encrypted_data: encryptedData,
iv,
}
if (encryptedData) {
await userMnpMobile({
...data
})
getUser()
}
}
const goPage = (url: string) => {
uni.navigateTo({
url: url,
})
}
//
uni.$on('uAvatarCropper', (path) => {
uni.showLoading({
title: '正在上传中...',
mask: true,
})
uploadFile(path)
.then((res) => {
uni.hideLoading()
setUserInfoFun(res.uri)
})
.catch(() => {
uni.hideLoading()
toast('上传失败')
})
})
onShow(async () => {
getUser()
wxCode.value = await getWxCode()
})
onUnload(() => {
uni.$off('uAvatarCropper')
})
</script>
<style lang="scss">
.header {
width: 100%;
height: 240rpx;
// border-radius: 14rpx;
image {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
.item {
margin-top: 2rpx;
padding: 30rpx 20rpx;
// border-radius: 14rpx;
background-color: #ffffff;
.label {
width: 150rpx;
}
.content {
flex: 1;
width: 80%;
}
.bind {
height: 56rpx;
border-width: 1rpx;
border-style: solid;
}
}
.license {
margin-top: 80rpx;
color: #a7a7a7;
}
</style>

View File

@ -1,3 +1,5 @@
import { getToken } from './auth'
/**
* @description ctx
* @param { String } selector '.app' | '#app'
@ -23,3 +25,44 @@ export const getRect = (selector: string, all = false, context?: any) => {
.exec()
})
}
/**
* @description
* @param { String } path
*/
export function uploadFile(path: any) {
return new Promise((resolve, reject) => {
const token = getToken()
uni.uploadFile({
url: `${import.meta.env.VITE_APP_BASE_URL}/api/Upload/image`,
filePath: path,
name: 'file',
header: {
token,
},
fileType: 'image',
success: res => {
console.log('uploadFile res ==> ', res)
let data = JSON.parse(res.data);
if (data.code == 1) {
resolve(data.data);
} else {
reject()
}
},
fail: (err) => {
console.log(err)
reject()
}
});
});
}
export const getWxCode = (): Promise<void> => {
return new Promise((resolve, reject) => {
uni.login({
desc: '获取用户信息,完善用户资料',
success: (res: Event) => resolve(res.code)
})
})
}