鸿宇研学生前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

383 lines
7.3 KiB

<template>
<view class="page__view">
<navbar title="修改信息" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#FFFFFF" />
<view class="main">
<view class="card">
<view class="card-header">个人信息</view>
<view class="form">
<uv-form
ref="form"
:model="form"
:rules="rules"
errorType="toast"
>
<view class="form-item">
<uv-form-item prop="name" :customStyle="formItemStyle">
<view class="form-item-label">昵称</view>
<view class="form-item-content input">
<input
type="nickname"
placeholder="请输入"
placeholderStyle="color: #C6C6C6; font-size: 32rpx; font-weight: 400;"
v-model="form.name"
/>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<view class="form-item-label">电话</view>
<view class="form-item-content input">
<formInput v-if="form.phone" v-model="form.phone"></formInput>
<view v-else>
<button
class="btn btn-phone"
open-type="getPhoneNumber"
@getphonenumber="getPhone"
>
<view class="text placeholder">获取电话号码</view>
</button>
</view>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<view class="form-item-label">头像</view>
<view class="form-item-content input">
<button class="btn btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view v-if="form.avatar" class="avatar">
<image class="img" :src="form.avatar" mode="aspectFill"></image>
<view class="flex mask">
<image class="icon" src="@/static/image/icon-change.png" mode="widthFix" />
</view>
</view>
<view v-else class="flex avatar is-empty">
<image class="icon" src="@/static/image/icon-plus.png" mode="widthFix" />
</view>
</button>
</view>
</uv-form-item>
</view>
</uv-form>
</view>
</view>
</view>
<view class="bottom">
<button class="btn" @click="onSubmit">保存</button>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import formInput from '@/pages_order/components/formInput.vue'
export default {
components: {
formInput,
},
props: {
mode: {
type: String,
default: null,
}
},
data() {
return {
form: {
name: null,
phone: null,
avatar: null,
},
rules: {
'name': {
type: 'string',
required: true,
message: '请输入昵称',
},
'phone': {
type: 'string',
required: true,
message: '请输入手机号',
},
'avatar': {
type: 'array',
required: true,
message: '请选择头像',
},
},
formItemStyle: { padding: 0 },
}
},
computed: {
...mapState(['userInfo']),
},
onLoad(arg) {
this.mode = arg.mode
this.form.name = this.userInfo.name || ''
this.form.phone = this.userInfo.phone || ''
this.form.avatar = this.userInfo.avatar || ''
},
methods: {
onChooseAvatar(res) {
this.$Oss.ossUpload(res.target.avatarUrl)
.then(url => {
this.form.avatar = url
})
},
getPhone(e){
this.$api('bindPhone', {
code : e.detail.code
}, res => {
if(res.code == 200){
if(res.success){
this.form.phone = res.result
}else{
uni.showModal({
title: res.message
})
}
}
})
},
async onSubmit() {
try {
await this.$refs.form.validate()
const {
name,
phone,
avatar,
} = this.form
const params = {
name,
phone,
avatar,
}
// todo: check 415 Unsupported Media Type
const res = await this.$fetch('updateInfo', params, false)
if (res.code == 200) {
uni.showToast({
icon: 'success',
title: '保存成功',
});
this.$store.commit('getUserInfo')
setTimeout(() => {
if (this.mode === 'edit') {
this.$utils.navigateBack()
return
}
uni.reLaunch({
url:'/pages/index/index'
})
}, 800)
}
} catch (err) {
console.log('onSubmit err', err)
}
},
},
}
</script>
<style lang="scss" scoped>
.page__view {
width: 100vw;
min-height: 100vh;
background: $uni-bg-color;
position: relative;
/deep/ .nav-bar__view {
position: fixed;
top: 0;
left: 0;
}
}
.main {
padding: calc(var(--status-bar-height) + 144rpx) 32rpx 224rpx 32rpx;
}
.card {
padding: 32rpx;
background: #FFFFFF;
border: 2rpx solid #FFFFFF;
border-radius: 32rpx;
& + & {
margin-top: 40rpx;
}
&-header {
font-family: PingFang SC;
font-weight: 500;
font-size: 36rpx;
line-height: 1.4;
color: #252545;
margin-bottom: 32rpx;
}
}
.row {
justify-content: space-between;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
column-gap: 24rpx;
& + & {
margin-top: 32rpx;
}
&-label {
flex: none;
font-size: 26rpx;
color: #8B8B8B;
}
&-content {
font-size: 32rpx;
color: #181818;
}
}
.form {
padding: 8rpx 0 0 0;
&-item {
border-bottom: 2rpx solid #EEEEEE;
&:last-child {
border: none;
}
& + & {
margin-top: 40rpx;
}
&-label {
font-family: PingFang SC;
font-weight: 400;
font-size: 26rpx;
line-height: 1.4;
color: #181818;
}
&-content {
margin-top: 14rpx;
padding: 6rpx 0;
.text {
padding: 2rpx 0;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
line-height: 1.4;
&.placeholder {
color: #C6C6C6;
}
}
}
}
}
.btn-phone {
text-align: left;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
line-height: 1.4;
color: #393939;
}
.btn-avatar {
display: inline-block;
width: auto;
border: none;
}
.avatar {
position: relative;
width: 200rpx;
height: 200rpx;
border-radius: 24rpx;
overflow: hidden;
.img {
width: 100%;
height: 100%;
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #00000080;
border-radius: 24rpx;
.icon {
width: 64rpx;
height: 64rpx;
}
}
&.is-empty {
background: #F3F2F7;
.icon {
width: 61rpx;
height: auto;
}
}
}
.bottom {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
// height: 200rpx;
padding: 24rpx 40rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 24rpx);
background: #FFFFFF;
box-sizing: border-box;
.btn {
width: 100%;
padding: 14rpx 0;
box-sizing: border-box;
font-family: PingFang SC;
font-weight: 500;
font-size: 36rpx;
line-height: 1;
color: #FFFFFF;
background: linear-gradient(to right, #21FEEC, #019AF9);
border: 2rpx solid #00A9FF;
border-radius: 41rpx;
}
}
</style>