HTML部分
<div class="user-img" @click="editUserImg">
<image style="height: 128rpx;width: 128rpx;border-radius: 999px;margin-right: 10px;"
:src="userInfo?.userImg" mode="scaleToFill" />
</div>
TS部分
用户接口类型
interface User {
id: number;
userName: string;
userImg: string;
userPhone: string;
userAddress: string;
authenticated?: boolean;
}
const userInfo = ref<User>()
具体代码
//修改用户信息
const updateUserInfo = () => {
loading.value = true
console.log('修改用户信息', userInfo.value)
http?.request({
url: "api/User/updateUserInfoByOpenId",
method: 'POST',
data: {
id: userInfo.value!.id,
name: userInfo.value!.userName,
address: userInfo.value!.userAddress,
phone: userInfo.value!.userPhone,
headshot: userInfo.value!.userImg,
openId: uni.getStorageSync('openid')
}
}).then((res: any) => {
if (res.code == 200) {
uni.showToast({
title: '修改成功!',
icon: 'success'
})
getUserInfoByToken(uni.getStorageSync('openid'))
} else {
uni.showToast({
title: '修改失败!',
icon: 'error'
})
}
}).catch((err: any) => {
console.log(err)
uni.showToast({
title: '网络错误!',
icon: 'error'
})
}).finally(() => {
loading.value = false
})
editState.value = false
}
//修改用户头像
const editUserImg = () => {
console.log('修改用户头像')
//@ts-ignore
wx.chooseMedia({
count: 1,
mediaTypes: ['image'],
sourceType: ['album', 'camera'],
sizeType: 'compressed',
camera: 'front',
success: (res: any) => {
loading.value = true
const { tempFiles } = res
const tempUserImg = tempFiles[0]
cutImgToSquare(tempUserImg.tempFilePath)
},
fail: (err: any) => {
console.log("调用失败", err)
},
complete: (res: any) => {
console.log("调用完成", res)
}
})
}
//将用户图片自动剪切成正方形
const cutImgToSquare = (imgPath: string) => {
//@ts-ignore
wx.createSelectorQuery()
.select('#canvas')
.fields({ node: true, size: true })
.exec((res: any) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const image = canvas.createImage()
image.onload = () => {
const size = Math.min(image.width, image.height)
canvas.width = size
canvas.height = size
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(image, (image.width - size) / 2, (image.height - size) / 2, size, size, 0, 0, size, size)
//@ts-ignore
wx.canvasToTempFilePath({
canvas,
success: (res: any) => {
console.log("调用成功", res)
//上传文件到服务器
uploadUserImg(res)
},
fail: (err: any) => {
console.log("调用失败", err)
loading.value = false
uni.showToast({
title: '图片上传失败!',
icon: 'error'
})
},
complete: (res: any) => {
console.log("调用完成", res)
}
})
}
image.src = imgPath
})
}
//将文件上传到服务器
const uploadUserImg = (file: any) => {
//@ts-ignore
wx.uploadFile({
url: uploadImg,
filePath: file.tempFilePath,
name: 'file',
success: (res: any) => {
const data = JSON.parse(res.data)
if (data.code == 200) {
console.log("图片路径", data.data.filePath)
userInfo.value!.userImg = data.data.filePath
editState.value = true
} else {
uni.showToast({
title: '上传失败!',
icon: 'error'
})
}
loading.value = false
},
fail: (err: any) => {
console.log("上传失败", err)
loading.value = false
uni.showToast({
title: '上传失败!',
icon: 'error'
})
},
complete: (res: any) => {
console.log("上传完成", res)
}
})
}
注意:这里上传的具体服务器是我自己的服务器,这里要把uploadUserImg中的uploadImg改成自己的接口地址,不会写文件传输的可以看我之前的文章
window下的:Java基于springboot上传文件(Windows系统)-CSDN博客
Linux下的:Java基于springboot上传文件(Linux系统)-CSDN博客
完整代码
<template>
<div class="header">
<div class="goback" @click="goback">
<image style="height: 3vh;" src="../../static/article/goback.png" mode="heightFix" />
</div>
<div class="user-img" @click="editUserImg">
<image style="height: 128rpx;width: 128rpx;border-radius: 999px;margin-right: 10px;"
:src="userInfo?.userImg" mode="scaleToFill" />
</div>
</div>
<div class="bodyer">
<div class="user-info">
<view class="user-title">
<view>
<image style="height: 32px;width: 32px;margin-right: 0.5em;"
src="../../static/userinfo/user-info-title.png" />
</view>
<view style="font-size: 18px;font-weight: bold;">用户信息</view>
</view>
<view class="user-info-box">
<view class="user-info-item">
<view style="display: flex;align-items: center;">
<view class="decoration-blue"></view>
<view style="font-size: 15px;">用户名称</view>
</view>
<view class="base-info-item" v-if="!editState">{{ userInfo?.userName }}</view>
<view class="base-info-item" v-if="editState">
<input v-model="userInfo!.userName" placeholder="请输入用户名" />
</view>
</view>
<view class="user-info-item">
<view style="display: flex;align-items: center;">
<view class="decoration-blue"></view>
<view style="font-size: 15px;">手机号</view>
</view>
<view class="base-info-item" v-if="!editState">{{ userInfo?.userPhone == null ? '未绑定' :
userInfo?.userPhone }}</view>
<view class="base-info-item" v-if="editState">
<input v-model="userInfo!.userPhone" placeholder="绑定手机号" />
</view>
</view>
<view class="user-info-item">
<view style="display: flex;align-items: center;">
<view class="decoration-blue"></view>
<view style="font-size: 15px;">居住地址</view>
</view>
<view class="base-info-item" v-if="!editState">{{ userInfo?.userAddress == null ? '未填写' :
userInfo?.userAddress }}</view>
<view class="base-info-item" v-if="editState">
<input v-model="userInfo!.userAddress" placeholder="请输入居住地址" />
</view>
</view>
</view>
<!-- <view class="authenticated">
<view @click.stop="goAuthenticated" class="goingauthenticated" v-if="!userInfo?.authenticated">
<text style="font-size: 14px;margin-right: 0.5em;">去实名认证</text>
<image style="height: 16px;" src="../../static/seekhelp/goingseek.png" mode="heightFix" />
</view>
</view> -->
</div>
</div>
<div class="footer">
<view @click="editState = true" v-if="!editState">修改个人信息</view>
<view @click="updateUserInfo" v-if="editState">保存</view>
<view @click="logout">退出登录</view>
</div>
<canvas v-show="false" id="canvas" type="2d" style="position: absolute;z-index: -999;opacity: 0;" />
<qgy-drawer ref="editAddressDrawer"></qgy-drawer>
<div class="back2"></div>
<qgy-loading style="position: absolute;top: 0px;left: 0px;" v-show="loading"></qgy-loading>
</template>
<script setup lang="ts">
import { Http } from '@/util/http';
import { inject, onMounted, ref } from 'vue';
const http: Http | undefined = inject('$http');
const loading = ref(false);
const uploadImg: string | undefined = inject('$uploadImg');
//修改状态
const editState = ref(false)
onMounted(() => {
getUserInfoByToken(uni.getStorageSync('openid'))
})
//从服务器中获取用户信息
const getUserInfoByToken = (openid: string) => {
loading.value = true
console.log("openid", openid)
//从后端获得用户信息
http?.request({
url: 'api/User/findUserInfoByOpenId?openId=' + openid,
method: 'GET'
}).then((res: any) => {
console.log(res)
if (res.code == 200) {
userInfo.value = {
id: res.data.id,
userName: res.data.name,
userAddress: res.data.address,
userImg: res.data.headshot,
userPhone: res.data.phone
}
} else {
uni.showToast({
title: "网络错误!",
duration: 2000,
icon: 'error'
})
}
}).catch((err: any) => {
console.log(err)
uni.showToast({
title: '网络错误!',
duration: 2000,
icon: 'error'
})
}).finally(() => {
loading.value = false
})
uni.setStorageSync('token', '孩子们我们现在没有token!')
}
//退出登录
const logout = () => {
console.log('退出登录')
uni.clearStorageSync()
uni.showToast({
title: '退出成功',
duration: 2000,
icon: 'success'
});
setTimeout(() => {
goback()
}, 2000)
}
interface User {
id: number;
userName: string;
userImg: string;
userPhone: string;
userAddress: string;
authenticated?: boolean;
}
const userInfo = ref<User>()
//页面是否处于修改状态
const pageState = ref<boolean>(false)
onMounted(() => {
//从token中获取用户信息
userInfo.value = {
id: 0,
userName: '乔冠宇',
userImg: '../../static/my/default.png',
userPhone: '15353365292',
userAddress: '陕西省咸阳市秦都区人民路财富中心一号楼三单元114514号',
authenticated: false
}
})
//返回上一页
const goback = () => {
uni.navigateBack({
fail: (err) => {
console.log(err)
uni.reLaunch({ url: '/pages/index/index' })
}
})
}
//去实名认证
// const goAuthenticated = () => {
// console.log('去实名认证')
// userInfo.value!.authenticated = true
// }
//修改用户信息
const updateUserInfo = () => {
loading.value = true
console.log('修改用户信息', userInfo.value)
http?.request({
url: "api/User/updateUserInfoByOpenId",
method: 'POST',
data: {
id: userInfo.value!.id,
name: userInfo.value!.userName,
address: userInfo.value!.userAddress,
phone: userInfo.value!.userPhone,
headshot: userInfo.value!.userImg,
openId: uni.getStorageSync('openid')
}
}).then((res: any) => {
if (res.code == 200) {
uni.showToast({
title: '修改成功!',
icon: 'success'
})
getUserInfoByToken(uni.getStorageSync('openid'))
} else {
uni.showToast({
title: '修改失败!',
icon: 'error'
})
}
}).catch((err: any) => {
console.log(err)
uni.showToast({
title: '网络错误!',
icon: 'error'
})
}).finally(() => {
loading.value = false
})
editState.value = false
}
//修改用户头像
const editUserImg = () => {
console.log('修改用户头像')
//@ts-ignore
wx.chooseMedia({
count: 1,
mediaTypes: ['image'],
sourceType: ['album', 'camera'],
sizeType: 'compressed',
camera: 'front',
success: (res: any) => {
loading.value = true
const { tempFiles } = res
const tempUserImg = tempFiles[0]
cutImgToSquare(tempUserImg.tempFilePath)
},
fail: (err: any) => {
console.log("调用失败", err)
},
complete: (res: any) => {
console.log("调用完成", res)
}
})
}
//将用户图片自动剪切成正方形
const cutImgToSquare = (imgPath: string) => {
//@ts-ignore
wx.createSelectorQuery()
.select('#canvas')
.fields({ node: true, size: true })
.exec((res: any) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const image = canvas.createImage()
image.onload = () => {
const size = Math.min(image.width, image.height)
canvas.width = size
canvas.height = size
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(image, (image.width - size) / 2, (image.height - size) / 2, size, size, 0, 0, size, size)
//@ts-ignore
wx.canvasToTempFilePath({
canvas,
success: (res: any) => {
console.log("调用成功", res)
//上传文件到服务器
uploadUserImg(res)
},
fail: (err: any) => {
console.log("调用失败", err)
loading.value = false
uni.showToast({
title: '图片上传失败!',
icon: 'error'
})
},
complete: (res: any) => {
console.log("调用完成", res)
}
})
}
image.src = imgPath
})
}
//将文件上传到服务器
const uploadUserImg = (file: any) => {
//@ts-ignore
wx.uploadFile({
url: uploadImg,
filePath: file.tempFilePath,
name: 'file',
success: (res: any) => {
const data = JSON.parse(res.data)
if (data.code == 200) {
console.log("图片路径", data.data.filePath)
userInfo.value!.userImg = data.data.filePath
editState.value = true
} else {
uni.showToast({
title: '上传失败!',
icon: 'error'
})
}
loading.value = false
},
fail: (err: any) => {
console.log("上传失败", err)
loading.value = false
uni.showToast({
title: '上传失败!',
icon: 'error'
})
},
complete: (res: any) => {
console.log("上传完成", res)
}
})
}
</script>
<style scoped>
.header {
height: 25vh;
width: 100vw;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.bodyer {
height: fit-content;
width: 100vw;
}
.user-img {
position: relative;
top: 3vh;
}
.footer {
width: 100vw;
font-size: 13px;
text-align: center;
display: flex;
justify-content: space-around;
padding: 2vh 0px;
color: gray;
}
.footer>view {
padding: 5px 10px;
}
.goback {
position: absolute;
top: 5vh;
left: 5vw;
}
.user-info {
width: 90vw;
margin: auto;
height: fit-content;
padding: 10px;
background-color: #ffffff;
border-radius: 30rpx;
}
.user-title {
display: flex;
align-items: center;
border-bottom: 2px solid #f4f7fc;
}
.base-info-item {
background-color: #f6f9ff;
border-radius: 2px;
padding: 5px 10px;
margin-top: 5px;
font-size: 14px;
}
.user-info-item {
margin: 10px 0px;
}
.goingauthenticated {
background-color: #ffffff;
color: #F56C6C;
padding: 5px 10px;
border-radius: 10px 10px 0px 0px;
display: flex;
align-items: center;
width: fit-content;
margin-left: auto;
}
</style>