Browse Source

个人信息渲染与头像修改

template
liruiqiang 2 months ago
parent
commit
3401859db9
  1. 9
      src/pages.json
  2. 257
      src/pagesMember/profile/profile.vue
  3. 12
      src/services/profile.ts
  4. 22
      src/types/member.d.ts

9
src/pages.json

@ -113,6 +113,15 @@
{
"navigationBarTitleText" : "设置"
}
},
{
"path" : "profile/profile",
"style" :
{
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
"navigationBarTitleText" : "个人中心"
}
}
]
}

257
src/pagesMember/profile/profile.vue

@ -0,0 +1,257 @@
<template>
<view class="viewport">
<!-- 导航栏 -->
<view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<navigator open-type="navigateBack" class="back icon-left" hover-class="none"></navigator>
<view class="title">个人信息</view>
</view>
<!-- 头像 -->
<view class="avatar">
<view class="avatar-content" @tap="onAvatarChange">
<image class="image" :src="profile?.avatar" mode="aspectFill" />
<text class="text">点击修改头像</text>
</view>
</view>
<!-- 表单 -->
<view class="form">
<!-- 表单内容 -->
<view class="form-content">
<view class="form-item">
<text class="label">账号</text>
<text class="account">{{ profile?.account }}</text>
</view>
<view class="form-item">
<text class="label">昵称</text>
<input class="input" type="text" placeholder="请填写昵称" :value="profile?.nickname" />
</view>
<view class="form-item">
<text class="label">性别</text>
<radio-group>
<label class="radio">
<radio value="男" color="#27ba9b" :checked="profile?.gender === '男'" />
</label>
<label class="radio">
<radio value="女" color="#27ba9b" :checked="profile?.gender === '女'" />
</label>
</radio-group>
</view>
<view class="form-item">
<text class="label">生日</text>
<picker
class="picker"
mode="date"
start="1900-01-01"
:end="new Date()"
:value="profile?.birthday"
>
<view v-if="profile?.birthday">{{ profile?.birthday }}</view>
<view class="placeholder" v-else>请选择日期</view>
</picker>
</view>
<!-- 只有微信小程序端内置了省市区数据 -->
<!-- #ifdef MP-WEIXIN -->
<view class="form-item">
<text class="label">城市</text>
<picker class="picker" mode="region" :value="profile?.fullLocation?.split(' ')">
<view v-if="profile?.fullLocation">{{ profile?.fullLocation }}</view>
<view class="placeholder" v-else>请选择城市</view>
</picker>
</view>
<!-- #endif -->
<view class="form-item">
<text class="label">职业</text>
<input class="input" type="text" placeholder="请填写职业" :value="profile?.profession" />
</view>
</view>
<!-- 提交按钮 -->
<button class="form-button"> </button>
</view>
</view>
</template>
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import type { Gender, ProfileDetail } from '@/types/member'
import { getMemberProfileAPI } from '@/services/profile'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
//
const profile = ref<ProfileDetail>()
const getMemberProfileData = async () => {
const res = await getMemberProfileAPI()
profile.value = res.result
}
//
const onAvatarChange = () => {
// /
uni.chooseMedia({
//
count: 1,
//
mediaType: ['image'],
success: (res) => {
//
const { tempFilePath } = res.tempFiles[0]
//
uni.uploadFile({
url: '/member/profile/avatar',
name: 'file', //
filePath: tempFilePath, //
success: (res) => {
//
if (res.statusCode === 200) {
//
const { avatar } = JSON.parse(res.data).result
//
profile.value!.avatar = avatar
uni.showToast({ icon: 'success', title: '更新成功' })
} else {
uni.showToast({ icon: 'error', title: '出现错误' })
}
},
})
},
})
}
onLoad(() => {
getMemberProfileData()
})
</script>
<style lang="scss">
page {
background-color: #f4f4f4;
}
.viewport {
display: flex;
flex-direction: column;
height: 100%;
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/order_bg.png);
background-size: auto 420rpx;
background-repeat: no-repeat;
}
//
.navbar {
position: relative;
.title {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: 500;
color: #fff;
}
.back {
position: absolute;
height: 40px;
width: 40px;
left: 0;
font-size: 20px;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
}
//
.avatar {
text-align: center;
width: 100%;
height: 260rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.image {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background-color: #eee;
}
.text {
display: block;
padding-top: 20rpx;
line-height: 1;
font-size: 26rpx;
color: #fff;
}
}
//
.form {
background-color: #f4f4f4;
&-content {
margin: 20rpx 20rpx 0;
padding: 0 20rpx;
border-radius: 10rpx;
background-color: #fff;
}
&-item {
display: flex;
height: 96rpx;
line-height: 46rpx;
padding: 25rpx 10rpx;
background-color: #fff;
font-size: 28rpx;
border-bottom: 1rpx solid #ddd;
&:last-child {
border: none;
}
.label {
width: 180rpx;
color: #333;
}
.account {
color: #666;
}
.input {
flex: 1;
display: block;
height: 46rpx;
}
.radio {
margin-right: 20rpx;
}
.picker {
flex: 1;
}
.placeholder {
color: #808080;
}
}
&-button {
height: 80rpx;
text-align: center;
line-height: 80rpx;
margin: 30rpx 20rpx;
color: #fff;
border-radius: 80rpx;
font-size: 30rpx;
background-color: #27ba9b;
}
}
</style>

12
src/services/profile.ts

@ -0,0 +1,12 @@
import type { ProfileDetail } from '@/types/member'
import { http } from '@/utils/http'
/**
*
*/
export const getMemberProfileAPI = () => {
return http<ProfileDetail>({
method: 'GET',
url: '/member/profile',
})
}

22
src/types/member.d.ts

@ -1,5 +1,5 @@
/** 小程序登录 登录用户信息 */
export type LoginResult = {
/** 封装通用信息 */
type BaseProfile = {
/** 用户ID */
id: number
/** 头像 */
@ -8,8 +8,26 @@ export type LoginResult = {
account: string
/** 昵称 */
nickname?: string
}
/** 小程序登录 登录用户信息 */
export type LoginResult = BaseProfile & {
/** 手机号 */
mobile: string
/** 登录凭证 */
token: string
}
/** 个人信息 用户详情信息 */
export type ProfileDetail = BaseProfile & {
/** 性别 */
gender?: Gender
/** 生日 */
birthday?: string
/** 省市区 */
fullLocation?: string
/** 职业 */
profession?: string
}
/** 性别 */
export type Gender = '女' | '男'
Loading…
Cancel
Save