285 lines
7.7 KiB
Vue
285 lines
7.7 KiB
Vue
<template>
|
|
<PageContainer ref="pageContainer" title="我的地址管理" show-back :show-not-data="showNotData" :refresh="onRefresh">
|
|
<view class="address-list">
|
|
<view v-for="(item, index) in addressList" :key="index" class="address-item">
|
|
<view class="address-content">
|
|
<view class="address-top">
|
|
<text class="name">{{ item.receiver_name }}</text>
|
|
<text class="phone">{{ item.receiver_phone }}</text>
|
|
<text v-if="item.is_default === 1" class="default-tag">默认</text>
|
|
</view>
|
|
<view class="address-bottom">
|
|
<text class="address-text">{{ item.detailed_address }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="edit-btn" @click="editAddress(item)">
|
|
<image src="/static/app-plus/edit.png" mode="widthFix" style="width:32px;height: 32px;"></image>
|
|
</view>
|
|
<view class="delete-btn" @click="showDeleteConfirm(item)">
|
|
<image src="/static/app-plus/del.png" mode="widthFix" style="width: 32px;height: 32px;"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="addressList.length === 0" class="empty-tip">
|
|
<text>暂无收货地址</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="add-btn" @click="addNewAddress">
|
|
<text>新增地址</text>
|
|
</view>
|
|
</PageContainer>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { getAddressList, deleteAddress } from '@/common/server/address';
|
|
|
|
const pageContainer = ref(null);
|
|
const showNotData = ref(false);
|
|
const addressList = ref([]);
|
|
|
|
// 刷新方法
|
|
const onRefresh = async (paging) => {
|
|
await loadAddressList();
|
|
paging.complete();
|
|
};
|
|
onShow(() => {
|
|
loadAddressList();
|
|
});
|
|
|
|
// // 页面加载时获取地址列表
|
|
// onMounted(() => {
|
|
// loadAddressList();
|
|
// });
|
|
// 加载地址列表
|
|
const loadAddressList = async () => {
|
|
try {
|
|
const res = await getAddressList();
|
|
if (res.status === 1 && res.data) {
|
|
addressList.value = res.data;
|
|
showNotData.value = addressList.value.length === 0;
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '获取地址列表失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('获取地址列表失败', error);
|
|
uni.showToast({
|
|
title: '网络异常,请稍后再试',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
};
|
|
|
|
// 编辑地址
|
|
const editAddress = (item) => {
|
|
uni.navigateTo({
|
|
url: '/pages/address/address-edit?id=' + item.id
|
|
});
|
|
};
|
|
|
|
// 新增地址
|
|
const addNewAddress = () => {
|
|
uni.navigateTo({
|
|
url: '/pages/address/address-edit'
|
|
});
|
|
};
|
|
|
|
// 显示删除确认对话框
|
|
const showDeleteConfirm = (item) => {
|
|
uni.showModal({
|
|
title: '提示',
|
|
content: '确定要删除该收货地址吗?',
|
|
success: async (res) => {
|
|
if (res.confirm) {
|
|
await deleteAddressItem(item.id);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// 删除地址
|
|
const deleteAddressItem = async (id) => {
|
|
try {
|
|
uni.showLoading({
|
|
title: '删除中...'
|
|
});
|
|
|
|
const res = await deleteAddress({
|
|
id: id
|
|
});
|
|
|
|
uni.hideLoading();
|
|
|
|
if (res.status === 1) {
|
|
uni.showToast({
|
|
title: '删除成功',
|
|
icon: 'success'
|
|
});
|
|
|
|
// 重新加载地址列表
|
|
loadAddressList();
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '删除失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
uni.hideLoading();
|
|
console.error('删除地址失败', error);
|
|
uni.showToast({
|
|
title: '网络异常,请稍后再试',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
};
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.address-list {
|
|
padding: 20rpx;
|
|
background-color: #f5f5f5;
|
|
min-height: calc(100vh - 120rpx);
|
|
|
|
.address-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
border-radius: 12rpx;
|
|
background-color: #fff;
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
transition: all 0.3s ease;
|
|
|
|
&:active {
|
|
transform: scale(0.98);
|
|
box-shadow: 0 1rpx 5rpx rgba(0, 0, 0, 0.03);
|
|
}
|
|
|
|
&:last-child {
|
|
margin-bottom: 100rpx;
|
|
}
|
|
|
|
.address-content {
|
|
flex: 1;
|
|
margin: 0 20rpx;
|
|
|
|
.address-top {
|
|
margin-bottom: 16rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
|
|
.name {
|
|
font-size: 34rpx;
|
|
font-weight: 600;
|
|
margin-right: 20rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.phone {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.default-tag {
|
|
display: inline-block;
|
|
font-size: 22rpx;
|
|
color: #fff;
|
|
background-color: #1296db;
|
|
padding: 4rpx 16rpx;
|
|
border-radius: 30rpx;
|
|
margin-left: 16rpx;
|
|
}
|
|
}
|
|
|
|
.address-bottom {
|
|
.address-text {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
line-height: 1.6;
|
|
}
|
|
}
|
|
}
|
|
|
|
.edit-btn,
|
|
.delete-btn {
|
|
width: 70rpx;
|
|
height: 70rpx;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
border-radius: 50%;
|
|
transition: background-color 0.2s ease;
|
|
|
|
&:active {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
image {
|
|
width: 36rpx;
|
|
height: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.empty-tip {
|
|
text-align: center;
|
|
padding: 120rpx 0;
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
&::before {
|
|
content: "";
|
|
width: 160rpx;
|
|
height: 160rpx;
|
|
margin-bottom: 30rpx;
|
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="%23cccccc"><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-5-7h10v2H7v-2zm0-3h10v2H7v-2zm0-3h10v2H7V7z"/></svg>');
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
background-size: contain;
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.add-btn {
|
|
position: fixed;
|
|
bottom: 40rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 90%;
|
|
height: 90rpx;
|
|
background: linear-gradient(to right, #1296db, #0e80c0);
|
|
color: #fff;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
border-radius: 45rpx;
|
|
box-shadow: 0 6rpx 16rpx rgba(18, 150, 219, 0.3);
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
|
|
&:active {
|
|
transform: translateX(-50%) scale(0.98);
|
|
box-shadow: 0 3rpx 8rpx rgba(18, 150, 219, 0.2);
|
|
}
|
|
|
|
&::before {
|
|
content: "+";
|
|
font-size: 40rpx;
|
|
margin-right: 10rpx;
|
|
font-weight: 400;
|
|
}
|
|
}
|
|
</style> |