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.

316 lines
8.8 KiB

<template>
<el-header>
<Header />
</el-header>
<div class="profile-list-container">
<div class="profile-content">
<!-- 用户资料表单 -->
<el-card class="profile-card" shadow="hover">
<div class="profile-header">
<!-- 头像 -->
<el-avatar
style="width: 80px; height: 80px;"
:src="avatarUrl"
class="avatar"
@click="changeAvatar"
/>
<div class="profile-info">
<el-form ref="profileForm" :model="profileInfo" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="profileInfo.name" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="profileInfo.email" placeholder="请输入邮箱"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="profileInfo.phone" placeholder="请输入手机号"></el-input>
<el-button type="primary" @click="bindPhone">绑定手机号</el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-button type="danger" @click="logout">退出登录</el-button>
<!-- 用户详细信息表单 -->
<div class="profile-details">
<el-form ref="profileDetailsForm" :model="profileInfo" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="性别">
<el-select v-model="profileInfo.gender" placeholder="请选择性别">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生日期">
<el-date-picker v-model="profileInfo.birthday" type="date" placeholder="选择日期"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="地址">
<el-input v-model="profileInfo.address" placeholder="请输入地址"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</el-card>
<!-- 地址管理表单 -->
<el-card class="address-card" shadow="hover">
<h3>地址管理</h3>
<el-button type="primary" @click="addAddress">添加地址</el-button>
<!-- 地址表单 -->
<el-form :model="addresses" label-width="80px">
<div v-for="(address, index) in addresses" :key="address.id" class="address-item">
<el-form-item label="收货人" :prop="'name' + index">
<el-input v-model="address.name" placeholder="请输入收货人姓名"></el-input>
</el-form-item>
<el-form-item label="地址" :prop="'address' + index">
<el-input v-model="address.address" placeholder="请输入收货地址"></el-input>
</el-form-item>
<el-form-item label="电话" :prop="'phone' + index">
<el-input v-model="address.phone" placeholder="请输入联系电话"></el-input>
</el-form-item>
<el-form-item>
<el-button type="text" @click="editAddress(index)">保存</el-button>
<el-button type="text" @click="deleteAddress(address.id)">删除</el-button>
<el-button type="text" @click="copyAddress(address)"></el-button>
</el-form-item>
</div>
</el-form>
</el-card>
</div>
</div>
</template>
<script lang="ts" setup>
import { ElMessage } from 'element-plus';
import { onMounted, ref } from 'vue';
import router from '../../router';
interface Address {
id: number;
name: string;
address: string;
phone: string;
}
// 用户信息
const profileInfo = ref({
name: '张三',
email: 'example@mail.com',
phone: '13800000000',
gender: '男',
birthday: '1990-01-01',
address: '北京市朝阳区某某街道',
});
// 读取 localStorage 中保存 的地址数据
const loadAddresses = () => {
const savedData = localStorage.getItem('addresses');
return savedData ? JSON.parse(savedData) : [];
};
// 保存地址数据到 localStorage
const saveAddresses = () => {
localStorage.setItem('addresses', JSON.stringify(addresses.value));
};
// 地址数据
const addresses = ref<Address[]>([]);
// 头像URL
const avatarUrl = ref<string>('src/assets/user.png'); // 假设默认头像路径
// 点击更换头像的方法
const changeAvatar = () => {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.onchange = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
avatarUrl.value = e.target.result; // 更新头像URL
};
reader.readAsDataURL(file); // 读取文件并转换为DataURL
}
};
fileInput.click(); // 触发点击事件,打开文件选择对话框
};
// 用于备份原始地址数据
const backupAddress = ref<Address | null>(null);
// 组件加载时读取数据
onMounted(() => {
addresses.value = loadAddresses(); // 页面加载时读取 localStorage 中的数据
});
// 备份当前地址数据
const backupCurrentAddress = (index: number) => {
backupAddress.value = { ...addresses.value[index] };
};
// 添加地址
const addAddress = () => {
const newId = addresses.value.length ? Math.max(...addresses.value.map(addr => addr.id)) + 1 : 1;
const newAddress = { id: newId, name: '', address: '', phone: '' };
addresses.value.push(newAddress);
saveAddresses(); // 添加地址后保存数据到 localStorage
};
// 编辑地址(保存修改)
const editAddress = (index: number) => {
backupCurrentAddress(index); // 备份当前地址
// 弹出确认框,询问用户是否保存修改
const isConfirmed = confirm('确定要保存更改吗?');
if (isConfirmed) {
// 执行保存操作
console.log('保存地址:', addresses.value[index]);
alert('保存成功');
saveAddresses(); // 保存修改后的数据到 localStorage
} else {
// 取消修改,恢复原有数据
if (backupAddress.value) {
addresses.value[index] = { ...backupAddress.value };
}
console.log('修改已取消');
window.location.reload();
}
};
// 删除地址
const deleteAddress = (id: number) => {
const index = addresses.value.findIndex((item) => item.id === id);
if (index !== -1) {
addresses.value.splice(index, 1);
saveAddresses(); // 删除地址后保存数据到 localStorage
}
};
const copyAddress = (address) => {
const textToCopy = `收货人: ${address.name}\n地址: ${address.address}\n电话: ${address.phone}`;
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
// 使用Element Plus的消息提示框
ElMessage.success('地址已复制到剪贴板');
};
const logout = () => {
router.push({ name: 'login' });
};
const bindPhone = () => {
if (!profileInfo.value.phone) {
ElMessage.error('手机号不能为空');
return;
}
// 这里可以添加手机号绑定的逻辑,比如发送请求到后端
ElMessage.success('手机号绑定成功!');
};
</script>
<style scoped>
.profile-list-container {
position: fixed;
top: 60px;
right: 0;
width: calc(100% - 220px);
height: calc(100vh - 60px);
overflow-y: auto;
padding: 20px;
box-sizing: border-box;
}
.profile-content {
max-width: 1000px;
margin: 20px auto;
}
.profile-card {
margin-bottom: 20px;
background-color: #fff;
border-radius: 8px;
}
.profile-header {
display: flex;
align-items: flex-start;
margin-bottom: 20px;
}
.avatar {
margin-right: 20px;
cursor: pointer;
}
.profile-info {
flex-grow: 1;
}
.profile-details {
margin-top: 20px;
}
.address-card {
background-color: #fff;
border-radius: 8px;
margin-top: 20px;
}
.address-item {
border-bottom: 1px solid #eee;
padding: 20px 0;
}
.address-item:last-child {
border-bottom: none;
}
/* 响应式布局 */
@media screen and (max-width: 768px) {
.profile-list-container {
width: calc(100% - 64px);
}
.profile-content {
padding: 10px;
}
.el-form-item {
margin-bottom: 15px;
}
}
/* Element Plus 样式覆盖 */
:deep(.el-card__body) {
padding: 20px;
}
:deep(.el-button--text) {
padding: 0 10px;
}
:deep(.el-form-item__label) {
font-weight: 500;
}
:deep(.el-input__inner) {
border-radius: 4px;
}
</style>