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
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> |