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

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>
<!-- 已登录用户显示地址列表 -->
<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-item">
<text class="label">收货人</text>
@ -32,7 +62,7 @@
<view class="footer-btn">
<button class="submit-btn" :loading="loading" @tap="onSubmit">确认提交</button>
</view>
<view class="tip-section">
<text class="tip-text">* 请确保信息准确提交后无法修改</text>
<text class="tip-text" v-if="isLoggedIn">* 您已登录提交后该奖品将转移至您的账户下</text>
@ -45,10 +75,13 @@
import { ref, reactive, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { request } from '@/utils/request'
import { listAddresses } from '@/api/appUser'
const token = ref('')
const loading = ref(false)
const isLoggedIn = ref(!!uni.getStorageSync('token'))
const addressList = ref([])
const selectedAddressIndex = ref(-1)
const form = reactive({
name: '',
@ -62,16 +95,52 @@ const form = reactive({
onLoad((options) => {
if (options.token) {
token.value = options.token
//
if (isLoggedIn.value) {
loadAddressList()
}
} else {
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) {
const [p, c, d] = e.detail.value
form.province = p
form.city = c
form.district = d
//
selectedAddressIndex.value = -1
}
async function onSubmit() {
@ -127,14 +196,14 @@ async function onSubmit() {
padding: 40rpx;
margin-bottom: 30rpx;
animation: fadeInDown 0.5s ease-out;
.title {
font-size: 36rpx;
font-weight: 700;
color: $text-main;
margin-bottom: 16rpx;
}
.desc {
font-size: 26rpx;
color: $text-sub;
@ -142,17 +211,125 @@ 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 {
padding: 20rpx 40rpx;
animation: fadeInUp 0.5s ease-out 0.1s backwards;
animation: fadeInUp 0.5s ease-out 0.2s backwards;
}
.form-item {
padding: 30rpx 0;
border-bottom: 1rpx solid rgba(0,0,0,0.05);
&:last-child { border-bottom: none; }
.label {
display: block;
font-size: 28rpx;
@ -160,18 +337,18 @@ async function onSubmit() {
margin-bottom: 20rpx;
font-weight: 600;
}
.input, .textarea {
width: 100%;
font-size: 28rpx;
color: $text-main;
}
.textarea {
height: 160rpx;
padding: 0;
}
.picker-placeholder { color: $text-tertiary; }
}
@ -191,7 +368,7 @@ async function onSubmit() {
align-items: center;
justify-content: center;
box-shadow: $shadow-warm;
&:active { transform: scale(0.98); opacity: 0.9; }
}

View File

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