增加好友领取界面的可选地址列表

This commit is contained in:
tsui110 2025-12-30 10:16:03 +08:00
parent 21118ce6f9
commit 952a2a2fe7
2 changed files with 187 additions and 11 deletions

View File

@ -5,6 +5,36 @@
<view class="desc">好友正在为您申请奖品发货请填写您的准确收货地址</view> <view class="desc">好友正在为您申请奖品发货请填写您的准确收货地址</view>
</view> </view>
<!-- 已登录用户显示地址列表 -->
<view v-if="isLoggedIn && addressList.length > 0" class="address-list-section">
<view class="section-title">选择已保存的地址</view>
<view class="address-list">
<view
v-for="(addr, index) in addressList"
:key="addr.id || index"
class="address-card"
:class="{ selected: selectedAddressIndex === index }"
@tap="selectAddress(index)"
>
<view class="address-info">
<view class="address-header">
<text class="name">{{ addr.name }}</text>
<text class="mobile">{{ addr.mobile }}</text>
</view>
<view class="address-detail">
{{ addr.province }} {{ addr.city }} {{ addr.district }} {{ addr.address }}
</view>
</view>
<view class="address-check" v-if="selectedAddressIndex === index">
<text class="check-icon"></text>
</view>
</view>
</view>
<view class="divider">
<text class="divider-text">或填写新地址</text>
</view>
</view>
<view class="form glass-card"> <view class="form glass-card">
<view class="form-item"> <view class="form-item">
<text class="label">收货人</text> <text class="label">收货人</text>
@ -45,10 +75,13 @@
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { request } from '@/utils/request' import { request } from '@/utils/request'
import { listAddresses } from '@/api/appUser'
const token = ref('') const token = ref('')
const loading = ref(false) const loading = ref(false)
const isLoggedIn = ref(!!uni.getStorageSync('token')) const isLoggedIn = ref(!!uni.getStorageSync('token'))
const addressList = ref([])
const selectedAddressIndex = ref(-1)
const form = reactive({ const form = reactive({
name: '', name: '',
@ -62,16 +95,52 @@ const form = reactive({
onLoad((options) => { onLoad((options) => {
if (options.token) { if (options.token) {
token.value = options.token token.value = options.token
//
if (isLoggedIn.value) {
loadAddressList()
}
} else { } else {
uni.showToast({ title: '参数错误', icon: 'none' }) uni.showToast({ title: '参数错误', icon: 'none' })
} }
}) })
//
async function loadAddressList() {
if (!isLoggedIn.value) return
try {
const userId = uni.getStorageSync('user_id')
if (!userId) return
const res = await listAddresses(userId)
addressList.value = res.list || res.data || res || []
} catch (e) {
console.error('获取地址列表失败:', e)
addressList.value = []
}
}
//
function selectAddress(index) {
selectedAddressIndex.value = index
const addr = addressList.value[index]
if (addr) {
form.name = addr.name || ''
form.mobile = addr.mobile || ''
form.province = addr.province || ''
form.city = addr.city || ''
form.district = addr.district || ''
form.address = addr.address || ''
}
}
function onRegionChange(e) { function onRegionChange(e) {
const [p, c, d] = e.detail.value const [p, c, d] = e.detail.value
form.province = p form.province = p
form.city = c form.city = c
form.district = d form.district = d
//
selectedAddressIndex.value = -1
} }
async function onSubmit() { async function onSubmit() {
@ -142,9 +211,117 @@ async function onSubmit() {
} }
} }
/* 地址列表部分 */
.address-list-section {
margin-bottom: 30rpx;
animation: fadeInUp 0.5s ease-out 0.1s backwards;
}
.section-title {
font-size: 28rpx;
color: $text-main;
font-weight: 600;
margin-bottom: 20rpx;
padding: 0 10rpx;
}
.address-list {
display: flex;
flex-direction: column;
gap: 16rpx;
margin-bottom: 30rpx;
}
.address-card {
background: #fff;
border-radius: $radius-lg;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: $shadow-sm;
border: 2rpx solid transparent;
transition: all 0.3s;
&.selected {
border-color: $brand-primary;
background: rgba($brand-primary, 0.03);
}
&:active {
transform: scale(0.98);
}
}
.address-info {
flex: 1;
margin-right: 20rpx;
}
.address-header {
display: flex;
align-items: center;
gap: 20rpx;
margin-bottom: 12rpx;
.name {
font-size: 30rpx;
font-weight: 600;
color: $text-main;
}
.mobile {
font-size: 26rpx;
color: $text-sub;
}
}
.address-detail {
font-size: 26rpx;
color: $text-secondary;
line-height: 1.5;
}
.address-check {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
background: $brand-primary;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
.check-icon {
color: #fff;
font-size: 28rpx;
font-weight: bold;
}
}
.divider {
display: flex;
align-items: center;
margin: 30rpx 0;
&::before,
&::after {
content: '';
flex: 1;
height: 1rpx;
background: rgba(0, 0, 0, 0.1);
}
.divider-text {
padding: 0 20rpx;
font-size: 24rpx;
color: $text-tertiary;
}
}
.form { .form {
padding: 20rpx 40rpx; padding: 20rpx 40rpx;
animation: fadeInUp 0.5s ease-out 0.1s backwards; animation: fadeInUp 0.5s ease-out 0.2s backwards;
} }
.form-item { .form-item {

View File

@ -204,7 +204,6 @@ function normalizeItems(list, kind) {
function switchTab(id) { function switchTab(id) {
if (currentTab.value === id) return if (currentTab.value === id) return
currentTab.value = id currentTab.value = id
loading.value = true
items.value = [] items.value = []
allItems.value = [] allItems.value = []
page.value = 1 page.value = 1