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.

287 lines
6.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<!-- 当前头像展示 -->
<view class="avatar-section">
<view class="current-avatar" @click="chooseImage">
<image :src="croppedImage?croppedImage:base.imgHost('logo-user.png')" />
<!-- <view v-else class="avatar-placeholder">
<text class="iconfont icon-user"></text>
</view> -->
</view>
<view class="avatar-tips">点击头像选择新照片</view>
</view>
<!-- 裁剪组件 -->
<!-- <u-cropper
v-if="showCropper"
:src="tempImage"
:width="300"
:height="300"
:scale="1"
:cut-width="300"
:cut-height="300"
:output-type="'jpg'"
:quality="0.9"
:max-width="600"
:max-height="600"
:show-cancel-btn="true"
:show-confirm-btn="true"
@cancel="cancelCrop"
@confirm="confirmCrop"
/> -->
<!-- 预览区 -->
<view v-if="croppedImage" class="crop-preview-wrap">
<view class="crop-preview">
<view class="preview-item">
<image :src="croppedImage" class="preview-circle small" mode="aspectFill" />
<view class="preview-label">小尺寸</view>
</view>
<view class="preview-item">
<image :src="croppedImage" class="preview-circle medium" mode="aspectFill" />
<view class="preview-label">中尺寸</view>
</view>
<view class="preview-item">
<image :src="croppedImage" class="preview-circle large" mode="aspectFill" />
<view class="preview-label">大尺寸</view>
</view>
</view>
<view class="form-btn">
<view @click="saveUser" type="primary">提交</view>
</view>
</view>
<qf-image-cropper ref="qfCropper" v-if="showCropper" :width="400" :height="400" :radius="200"
@crop="uploadSuccess" @close="closeCrop"></qf-image-cropper>
</view>
</template>
<script>
// 需在项目中安装 uCropper 组件https://ext.dcloud.net.cn/plugin?id=2713
import QfImageCropper from '@/uni_modules/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.vue';
import {
ROOTPATH
} from '@/common/config'
export default {
components: {
QfImageCropper
},
data() {
return {
tempImage: '', // 临时选中的图片
croppedImage: '', // 裁剪后的图片
showCropper: false,
loading: false,
success: false
}
},
onLoad(){
this.croppedImage = this.vuex_user.headimgurl?this.vuex_user.headimgurl:''
console.log("this.vuex_user.headimgurl",this.vuex_user.headimgurl)
},
methods: {
chooseImage() {
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: res => {
const filePath = res.tempFilePaths[0];
this.tempImage = filePath;
this.showCropper = true;
this.$nextTick(() => {
this.$refs.qfCropper?.resetData(); // 可选链操作符防止报错
this.$refs.qfCropper?.initImage(this.tempImage)
});
}
});
},
uploadSuccess(res) {
console.log("res", res)
this.saveAvatar(res.tempFilePath)
},
closeCrop(){
// this.croppedImage = ''
this.showCropper = false;
this.tempImage = '';
},
// 上传图片
// 更新userimg
async saveAvatar(file) {
if (!file) {
this.base.toast("请选择头像")
return
};
this.loading = true;
// 模拟上传
await uni.uploadFile({
url: ROOTPATH + "/api/mobile/upload-file",
filePath: file,
name: 'file',
header: {
['Authorization']: `Bearer ${this.vuex_token}`
},
success: (res) => {
console.log("res",res)
let data = JSON.parse(res.data)
this.croppedImage = data.url
this.showCropper = false;
this.tempImage = '';
}
})
},
async saveUser(files){
const res = await this.$u.api.saveUser({
headimgurl:this.croppedImage,
username:this.vuex_user.username
})
this.base.toast("更新成功",1500,function(){
setTimeout(function(){
uni.navigateBack()
},1500)
})
}
}
}
</script>
<style scoped lang="scss">
.container {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 40rpx;
}
.avatar-section {
background: rgba(255, 255, 255, 0.95);
border-radius: 40rpx;
padding: 60rpx 40rpx 30rpx 40rpx;
margin: 40rpx 0 20rpx 0;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
text-align: center;
width: 90vw;
max-width: 600rpx;
}
.current-avatar {
width: 240rpx;
height: 240rpx;
border-radius: 50%;
margin: 0 auto 30rpx;
overflow: hidden;
border: 8rpx solid #fff;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
position: relative;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
}
.current-avatar image {
width: 240rpx;
height: 240rpx;
border-radius: 50%;
}
.avatar-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #bbb;
font-size: 100rpx;
}
.avatar-tips {
color: #666;
font-size: 26rpx;
margin-bottom: 10rpx;
}
.crop-preview-wrap {
width: 90vw;
max-width: 600rpx;
background: rgba(255, 255, 255, 0.95);
border-radius: 40rpx;
padding: 60rpx 40rpx 30rpx 40rpx;
margin: 40rpx 0 20rpx 0;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
background-color: #fff;
}
.crop-preview{
display: flex;
justify-content: center;
gap: 30rpx;
text-align: center;
}
.preview-item {
text-align: center;
}
.preview-circle {
border-radius: 50%;
overflow: hidden;
margin: 0 auto 8rpx;
border: 4rpx solid #e5e7eb;
}
.preview-circle.small {
width: 60rpx;
height: 60rpx;
}
.preview-circle.medium {
width: 80rpx;
height: 80rpx;
}
.preview-circle.large {
width: 120rpx;
height: 120rpx;
}
.preview-label {
font-size: 24rpx;
color: #6b7280;
}
.loading {
text-align: center;
padding: 40rpx;
color: #666;
}
.success-message {
background: #10b981;
color: white;
padding: 30rpx 40rpx;
border-radius: 20rpx;
margin: 30rpx 0;
text-align: center;
}
.form-btn {
width: 100%;
position: relative;
padding: 60rpx 0;
&>view {
width: 70%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 20rpx;
}
}
</style>