222 lines
5.5 KiB
Plaintext
222 lines
5.5 KiB
Plaintext
<template>
|
|
<view class="address-list-page">
|
|
<view class="address-list">
|
|
<view v-if="addresses.length === 0" class="empty-state">
|
|
<text class="empty-icon">馃搷</text>
|
|
<text class="empty-text">鏆傛棤鏀惰揣鍦板潃</text>
|
|
</view>
|
|
|
|
<view v-else v-for="(item, index) in addresses" :key="item.id" class="address-item" @click="selectAddress(item)">
|
|
<view class="item-content">
|
|
<view class="item-header">
|
|
<text class="user-name">{{ item.name }}</text>
|
|
<text class="user-phone">{{ item.phone }}</text>
|
|
<text v-if="item.isDefault" class="default-tag">榛樿</text>
|
|
<text v-if="item.label" class="label-tag">{{ item.label }}</text>
|
|
</view>
|
|
<text class="address-text">{{ getFullAddress(item) }}</text>
|
|
</view>
|
|
<view class="item-actions">
|
|
<view class="action-item" @click.stop="editAddress(item.id)">
|
|
<text class="action-icon">馃摑</text>
|
|
</view>
|
|
<view class="action-item" @click.stop="deleteAddress(item.id)">
|
|
<text class="action-icon">锟斤笍</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="footer-btn">
|
|
<button class="add-btn" @click="addAddress">鏂板缓鏀惰揣鍦板潃</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
|
|
type Address = {
|
|
id: string
|
|
name: string
|
|
phone: string
|
|
province: string
|
|
city: string
|
|
district: string
|
|
detail: string
|
|
isDefault: boolean
|
|
label?: string
|
|
}
|
|
|
|
const addresses = ref<Address[]>([])
|
|
const selectionMode = ref<boolean>(false)
|
|
let openerEventChannel: any | null = null
|
|
|
|
onShow(() => {
|
|
loadAddresses()
|
|
})
|
|
|
|
onMounted(() => {
|
|
try {
|
|
const ec = uni.getOpenerEventChannel()
|
|
openerEventChannel = ec
|
|
ec?.on('setSelectMode', (data: any) => {
|
|
if (data && typeof data.selectMode === 'boolean') {
|
|
selectionMode.value = data.selectMode
|
|
}
|
|
})
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
})
|
|
|
|
const loadAddresses = () => {
|
|
const storedAddresses = uni.getStorageSync('addresses')
|
|
if (storedAddresses) {
|
|
try {
|
|
addresses.value = JSON.parse(storedAddresses as string) as Address[]
|
|
} catch (e) {
|
|
console.error('Failed to parse addresses', e)
|
|
addresses.value = []
|
|
}
|
|
} else {
|
|
// 鍒濆Mock鏁版嵁
|
|
addresses.value = [
|
|
{
|
|
id: 'addr_001',
|
|
name: '寮犱笁',
|
|
phone: '13800138000',
|
|
province: '鍖椾含甯?,
|
|
city: '鍖椾含甯?,
|
|
district: '鏈濋槼鍖?,
|
|
detail: '涓夐噷灞疭OHO A搴?,
|
|
isDefault: true,
|
|
label: '鍏徃'
|
|
}
|
|
]
|
|
uni.setStorageSync('addresses', JSON.stringify(addresses.value))
|
|
}
|
|
}
|
|
|
|
const getFullAddress = (item: Address): string => {
|
|
return `${item.province}${item.city}${item.district} ${item.detail}`
|
|
}
|
|
|
|
const addAddress = () => {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/address-edit'
|
|
})
|
|
}
|
|
|
|
// 鍒犻櫎鍦板潃
|
|
const deleteAddress = (id: string) => {
|
|
uni.showModal({
|
|
title: '鎻愮ず',
|
|
content: '纭畾瑕佸垹闄よ鍦板潃鍚楋紵',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
const index = addresses.value.findIndex(addr => addr.id === id)
|
|
if (index !== -1) {
|
|
addresses.value.splice(index, 1)
|
|
uni.setStorageSync('addresses', JSON.stringify(addresses.value))
|
|
uni.showToast({
|
|
title: '鍒犻櫎鎴愬姛',
|
|
icon: 'success'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
const editAddress = (id: string) => {
|
|
uni.navigateTo({
|
|
url: `/pages/mall/consumer/address-edit?id=${id}`
|
|
})
|
|
}
|
|
|
|
const selectAddress = (item: Address) => {
|
|
if (selectionMode.value && openerEventChannel) {
|
|
openerEventChannel.emit('addressSelected', {
|
|
id: item.id,
|
|
recipient_name: item.name,
|
|
phone: item.phone,
|
|
province: item.province,
|
|
city: item.city,
|
|
district: item.district,
|
|
detail: item.detail,
|
|
is_default: item.isDefault
|
|
})
|
|
uni.navigateBack()
|
|
} else {
|
|
editAddress(item.id)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.item-actions {
|
|
padding: 10px;
|
|
border-left: 1px solid #f0f0f0;
|
|
display: flex;
|
|
flex-direction: column; /* 绔栧悜鎺掑垪鍥炬爣 */
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 15px;
|
|
}
|
|
|
|
.footer-btn {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background-color: white;
|
|
padding: 10px 15px;
|
|
padding-bottom: calc(10px + env(safe-area-inset-bottom));
|
|
box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
|
|
display: flex;
|
|
justify-content: center; /* 灞呬腑鏄剧ず */
|
|
align-items: center;
|
|
}
|
|
|
|
.add-btn {
|
|
background-color: #ff5000;
|
|
color: white;
|
|
border-radius: 25px;
|
|
font-size: 16px;
|
|
height: 44px;
|
|
line-height: 44px;
|
|
border: none;
|
|
width: 100%; /* 榛樿鍗犳弧 */
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* 鍝嶅簲寮忓竷灞€浼樺寲 */
|
|
@media screen and (min-width: 768px) {
|
|
.address-list {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.address-list-page {
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.footer-btn {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
|
|
border-radius: 12px 12px 0 0; /* 妗岄潰绔姞鐐瑰渾瑙掓洿缇庤 */
|
|
}
|
|
|
|
.add-btn {
|
|
width: 300px; /* 妗岄潰绔檺鍒跺搴?*/
|
|
}
|
|
}
|
|
</style>
|
|
|
|
|