Files
sgxt_web/src/views/backOfficeSystem/luntan/components/ChangeAvatar.vue

204 lines
5.1 KiB
Vue
Raw Normal View History

2026-03-24 12:18:39 +08:00
<template>
<el-dialog :model-value="modelValue" center width="500px" :destroy-on-close="true" :title="title" @close="close"
:close-on-click-modal="false">
<div class="avatar-upload-container">
<div class="avatar-preview">
<img v-if="avatarUrl" :src="avatarUrl" alt="预览头像" class="preview-image">
<div v-else class="preview-placeholder">
<el-icon class="placeholder-icon">
<User />
</el-icon>
<span>请上传头像</span>
</div>
</div>
<div class="upload-section">
<el-upload class="avatar-uploader" :auto-upload="false" :show-file-list="false"
:on-change="handleAvatarChange" :before-upload="beforeAvatarUpload" accept="image/*">
<el-button size="small" type="primary">选择图片</el-button>
</el-upload>
<div class="upload-tips">
<p> 支持 JPGPNG 格式</p>
<p> 图片大小不超过 2MB</p>
<p> 建议尺寸为 200x200 像素</p>
</div>
</div>
</div>
<template #footer>
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="confirmUpload" :loading="uploading" :disabled="!avatarUrl || uploading">
{{ uploading ? '上传中...' : '确认更换' }}
</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from "vue";
import { ElMessage } from 'element-plus';
import { User } from '@element-plus/icons-vue';
import { upImageUploadId } from '@/api/commit';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: "更换头像"
},
heightNumber: {
type: Number,
default: 250
}
});
const emits = defineEmits(["update:modelValue", "avatarUpdated"]);
// 头像相关状态
const avatarUrl = ref('');
const uploading = ref(false);
// 监听对话框显示状态,重置头像预览
watch(() => props.modelValue, (newVal) => {
if (!newVal) {
// 对话框关闭时重置头像预览
avatarUrl.value = '';
}
});
// 当前选择的文件
const selectedFile = ref(null);
// 处理头像选择
const handleAvatarChange = (file) => {
selectedFile.value = file.raw;
// 创建临时预览URL
const reader = new FileReader();
reader.onload = (e) => {
avatarUrl.value = e.target.result;
};
reader.readAsDataURL(file.raw);
};
// 上传前检查
const beforeAvatarUpload = (file) => {
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG && !isPNG) {
ElMessage.error('请上传 JPG 或 PNG 格式的图片!');
return false;
}
if (!isLt2M) {
ElMessage.error('图片大小不能超过 2MB!');
return false;
}
return true;
};
// 确认上传头像
const confirmUpload = async () => {
if (!avatarUrl.value || !selectedFile.value) {
ElMessage.warning('请先选择头像图片');
return;
}
uploading.value = true;
try {
// 创建FormData对象
const formData = new FormData();
formData.append('file', selectedFile.value);
// 调用实际的上传接口
const response = await upImageUploadId(formData);
console.log(response);
emits('avatarUpdated', response);
// 关闭对话框
close();
} catch (error) {
console.error('上传头像失败:', error);
ElMessage.error('上传头像失败,请重试');
} finally {
uploading.value = false;
}
};
// 关闭对话框
const close = () => {
emits("update:modelValue", false);
};
</script>
<style lang="scss" scoped>
.avatar-upload-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.avatar-preview {
width: 160px;
height: 160px;
border-radius: 50%;
overflow: hidden;
border: 2px solid #e8e8e8;
margin-bottom: 20px;
display: flex;
justify-content: center;
align-items: center;
background-color: #f5f7fa;
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.preview-placeholder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #909399;
.placeholder-icon {
font-size: 48px;
margin-bottom: 8px;
}
span {
font-size: 14px;
}
}
}
.upload-section {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.avatar-uploader {
margin-bottom: 16px;
}
.upload-tips {
width: 100%;
padding: 12px;
background-color: #f5f7fa;
border-radius: 4px;
font-size: 12px;
color: #909399;
p {
margin: 4px 0;
line-height: 1.5;
}
}
</style>