| | |
| | | <template> |
| | | <view class="page"> |
| | | <!-- 有数据:渲染地址列表,右侧为编辑入口 --> |
| | | <!-- 有数据:渲染地址列表,右侧为编辑/删除入口 --> |
| | | <view v-if="addressList.length"> |
| | | <view v-for="item in addressList" :key="item.id" class="addr-item"> |
| | | <view class="addr-main"> |
| | | <!-- 姓名 + 手机号 --> |
| | | <view class="addr-head"> |
| | | <text class="addr-name">{{ item.name }}</text> |
| | | <text class="addr-phone">{{ item.phone }}</text> |
| | | <text class="addr-name">{{ item.consignee }}</text> |
| | | <text class="addr-phone">{{ item.consigneePhone }}</text> |
| | | </view> |
| | | <!-- 默认地址标记 --> |
| | | <view v-if="item.isDefault" class="addr-tag">默认</view> |
| | | <text class="addr-detail">{{ item.detail }}</text> |
| | | <view v-if="item.isDefault === '1'" class="addr-tag">默认</view> |
| | | <text class="addr-detail">{{ item.address }}</text> |
| | | </view> |
| | | <view class="icon icon-edit" @tap="handleEdit(item)"></view> |
| | | <!-- 操作区:编辑 / 删除 --> |
| | | <view class="addr-actions"> |
| | | <view class="icon icon-edit" @tap="handleEdit(item)"></view> |
| | | <view class="icon icon-delete" @tap="handleDelete(item)"></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { onShow } from '@dcloudio/uni-app' |
| | | import { getAddressList, deleteAddress } from '@/api/index.js' |
| | | import { ensureLogin } from '@/utils/request.js' |
| | | |
| | | /** 收货地址列表:地址接口未就绪,先本地 mock(联调后由收货地址列表接口下发);手机号按规范脱敏展示 */ |
| | | const MOCK_ADDRESS_LIST = [ |
| | | { |
| | | id: '1', |
| | | name: '张三', |
| | | phone: '185****0110', |
| | | detail: '四川省成都市武侯区府城大道399号天府新谷9号楼2单元1005a', |
| | | isDefault: true |
| | | }, |
| | | { |
| | | id: '2', |
| | | name: '李四', |
| | | phone: '185****0110', |
| | | detail: '四川省成都市武侯区府城大道399号天府新谷9号楼2单元1005a' |
| | | }, |
| | | { |
| | | id: '3', |
| | | name: '王五', |
| | | phone: '185****0110', |
| | | detail: '四川省成都市武侯区府城大道399号天府新谷9号楼2单元1005a' |
| | | /** 收货地址列表(来自后端 /miniapp/account/user/addresses) */ |
| | | const addressList = ref([]) |
| | | |
| | | /** 拉取本人收货地址列表(默认地址在前) */ |
| | | const _loadAddressList = async () => { |
| | | try { |
| | | const res = await getAddressList() |
| | | addressList.value = res.data || [] |
| | | } catch (e) { |
| | | console.error('[ADDRESS_LIST] 加载收货地址失败', e) |
| | | uni.showToast({ title: e.message || '加载失败', icon: 'none' }) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | const addressList = ref(MOCK_ADDRESS_LIST) |
| | | /** onShow:从新增/编辑页返回时自动刷新列表 */ |
| | | onShow(() => { |
| | | if (!ensureLogin()) return |
| | | _loadAddressList() |
| | | }) |
| | | |
| | | /** 编辑地址:编辑页未实现,暂为占位反馈 */ |
| | | const handleEdit = () => { |
| | | uni.showToast({ title: '敬请期待', icon: 'none' }) |
| | | /** 编辑地址:跳转新增页并携带 id,复用为编辑模式 */ |
| | | const handleEdit = (item) => { |
| | | uni.navigateTo({ url: '/pages/address/add?id=' + item.id }) |
| | | } |
| | | |
| | | /** 删除地址:二次确认后删除并刷新列表 */ |
| | | const handleDelete = (item) => { |
| | | uni.showModal({ |
| | | title: '提示', |
| | | content: '确定要删除该收货地址吗?', |
| | | success: async (res) => { |
| | | if (!res.confirm) return |
| | | try { |
| | | await deleteAddress(item.id) |
| | | uni.showToast({ title: '删除成功', icon: 'none' }) |
| | | _loadAddressList() |
| | | } catch (e) { |
| | | console.error('[ADDRESS_DELETE] 删除收货地址失败', e) |
| | | uni.showToast({ title: e.message || '删除失败', icon: 'none' }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** 新增地址:跳转到新增地址页 */ |
| | |
| | | .addr-main { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | /* 操作区:编辑 + 删除图标并排 */ |
| | | .addr-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 28rpx; |
| | | flex-shrink: 0; |
| | | margin-left: 24rpx; |
| | | } |
| | | |
| | | .addr-head { |
| | |
| | | /* ==================== 图标(内联 base64 SVG) ==================== */ |
| | | |
| | | .icon-edit, |
| | | .icon-delete, |
| | | .icon-plus, |
| | | .icon-empty { |
| | | background-repeat: no-repeat; |
| | |
| | | width: 44rpx; |
| | | height: 44rpx; |
| | | flex-shrink: 0; |
| | | margin-left: 24rpx; |
| | | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMUU1RUJDIiBzdHJva2Utd2lkdGg9IjEuOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTIgM0g1YTIgMiAwIDAgMC0yIDJ2MTRhMiAyIDAgMCAwIDIgMmgxNGEyIDIgMCAwIDAgMi0ydi03Ii8+PHBhdGggZD0iTTE4LjM3NSAyLjYyNWExIDEgMCAwIDEgMyAzbC05LjAxMyA5LjAxNGEyIDIgMCAwIDEtLjg1My41MDVsLTIuODczLjg0YS41LjUgMCAwIDEtLjYyLS42MmwuODQtMi44NzNhMiAyIDAgMCAxIC41MDYtLjg1MnoiLz48L3N2Zz4='); |
| | | } |
| | | |
| | | /* 删除:垃圾桶(#EF4444) */ |
| | | .icon-delete { |
| | | width: 44rpx; |
| | | height: 44rpx; |
| | | flex-shrink: 0; |
| | | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRUY0NDQ0IiBzdHJva2Utd2lkdGg9IjEuOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMyA2aDE4Ii8+PHBhdGggZD0iTTggNlY0YTEgMSAwIDAgMSAxLTFoNmExIDEgMCAwIDEgMSAxdjIiLz48cGF0aCBkPSJNMTkgNmwtMSAxNGEyIDIgMCAwIDEtMiAySDhhMiAyIDAgMCAxLTItMkw1IDYiLz48cGF0aCBkPSJNMTAgMTF2NiIvPjxwYXRoIGQ9Ik0xNCAxMXY2Ii8+PC9zdmc+'); |
| | | } |
| | | |
| | | /* 新增:白色加号 */ |
| | | .icon-plus { |
| | | width: 34rpx; |