refactor(components): 重构ElCard、FlipGrid、YifanSelector和PaymentPopup组件样式 refactor(pages): 优化地址管理、商品详情、订单列表、积分记录和活动页面UI style: 更新uni.scss全局样式变量和设计系统 docs: 添加说明文档记录UI优化进度
270 lines
6.1 KiB
Vue
270 lines
6.1 KiB
Vue
<template>
|
||
<view class="wrap">
|
||
<view class="header">
|
||
<button class="add" @click="toAdd">新增地址</button>
|
||
</view>
|
||
<view v-if="error" class="error">{{ error }}</view>
|
||
<view v-if="list.length === 0 && !loading" class="empty">暂无地址</view>
|
||
<view v-for="item in list" :key="item.id" class="addr">
|
||
<view class="addr-main">
|
||
<view class="addr-row">
|
||
<text class="name">姓名:{{ item.name || item.realname }}</text>
|
||
</view>
|
||
<view class="addr-row">
|
||
<text class="phone">手机号:{{ item.phone || item.mobile }}</text>
|
||
</view>
|
||
<view class="addr-row" v-if="item.is_default">
|
||
<text class="default">默认</text>
|
||
</view>
|
||
<view class="addr-row">
|
||
<text class="region">省市区:{{ item.province }}{{ item.city }}{{ item.district }}</text>
|
||
</view>
|
||
<view class="addr-row">
|
||
<text class="detail">详细地址:{{ item.address || item.detail }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="addr-actions">
|
||
<button size="mini" @click="toEdit(item)">编辑</button>
|
||
<button size="mini" type="warn" @click="onDelete(item)">删除</button>
|
||
<button size="mini" :disabled="item.is_default" @click="onSetDefault(item)">设为默认</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
import { onLoad } from '@dcloudio/uni-app'
|
||
import { listAddresses, deleteAddress, setDefaultAddress } from '../../api/appUser'
|
||
|
||
const list = ref([])
|
||
const loading = ref(false)
|
||
const error = ref('')
|
||
|
||
async function fetchList() {
|
||
const user_id = uni.getStorageSync('user_id')
|
||
const token = uni.getStorageSync('token')
|
||
const phoneBound = !!uni.getStorageSync('phone_bound')
|
||
if (!user_id || !token || !phoneBound) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '请先登录并绑定手机号',
|
||
confirmText: '去登录',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateTo({ url: '/pages/login/index' })
|
||
}
|
||
}
|
||
})
|
||
return
|
||
}
|
||
loading.value = true
|
||
error.value = ''
|
||
try {
|
||
const data = await listAddresses(user_id)
|
||
list.value = Array.isArray(data) ? data : (data && (data.list || data.items)) || []
|
||
} catch (e) {
|
||
error.value = e && (e.message || e.errMsg) || '获取地址失败'
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
function toAdd() {
|
||
uni.removeStorageSync('edit_address')
|
||
uni.navigateTo({ url: '/pages/address/edit' })
|
||
}
|
||
|
||
function toEdit(item) {
|
||
uni.setStorageSync('edit_address', item)
|
||
uni.navigateTo({ url: `/pages/address/edit?id=${item.id}` })
|
||
}
|
||
|
||
function onDelete(item) {
|
||
const user_id = uni.getStorageSync('user_id')
|
||
uni.showModal({
|
||
title: '确认删除',
|
||
content: '确定删除该地址吗?',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
try {
|
||
await deleteAddress(user_id, item.id)
|
||
fetchList()
|
||
} catch (e) {
|
||
uni.showToast({ title: '删除失败', icon: 'none' })
|
||
}
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
async function onSetDefault(item) {
|
||
try {
|
||
const user_id = uni.getStorageSync('user_id')
|
||
await setDefaultAddress(user_id, item.id)
|
||
fetchList()
|
||
} catch (e) {
|
||
uni.showToast({ title: '设置失败', icon: 'none' })
|
||
}
|
||
}
|
||
|
||
onLoad(() => {
|
||
fetchList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* ============================================
|
||
奇盒潮玩 - 地址管理页面
|
||
采用暖橙色调的卡片列表设计
|
||
============================================ */
|
||
|
||
.wrap {
|
||
padding: $spacing-md;
|
||
min-height: 100vh;
|
||
background-color: $bg-page;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-bottom: $spacing-lg;
|
||
}
|
||
.add {
|
||
font-size: $font-md;
|
||
background: $gradient-brand !important;
|
||
color: #FFFFFF !important;
|
||
border-radius: $radius-round;
|
||
padding: 0 $spacing-xl;
|
||
height: 72rpx;
|
||
line-height: 72rpx;
|
||
font-weight: 600;
|
||
box-shadow: $shadow-warm;
|
||
}
|
||
.add:active {
|
||
transform: scale(0.96);
|
||
}
|
||
|
||
/* 地址卡片 */
|
||
.addr {
|
||
background: #FFFFFF;
|
||
border-radius: $radius-md;
|
||
padding: $spacing-lg;
|
||
margin-bottom: $spacing-md;
|
||
box-shadow: $shadow-sm;
|
||
animation: fadeInUp 0.4s ease-out backwards;
|
||
}
|
||
|
||
@for $i from 1 through 10 {
|
||
.addr:nth-child(#{$i}) {
|
||
animation-delay: #{$i * 0.05}s;
|
||
}
|
||
}
|
||
|
||
.addr-main {
|
||
margin-bottom: $spacing-md;
|
||
}
|
||
|
||
.addr-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: $spacing-sm;
|
||
}
|
||
.addr-row:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.name {
|
||
font-size: $font-lg;
|
||
font-weight: 600;
|
||
color: $text-main;
|
||
}
|
||
.phone {
|
||
font-size: $font-md;
|
||
color: $text-sub;
|
||
}
|
||
.default {
|
||
font-size: $font-xs;
|
||
color: #FFFFFF;
|
||
background: $gradient-brand;
|
||
padding: 4rpx $spacing-sm;
|
||
border-radius: $radius-round;
|
||
font-weight: 500;
|
||
}
|
||
.region {
|
||
font-size: $font-sm;
|
||
color: $text-sub;
|
||
}
|
||
.detail {
|
||
font-size: $font-md;
|
||
color: $text-main;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
/* 操作按钮 */
|
||
.addr-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: $spacing-md;
|
||
margin-top: $spacing-lg;
|
||
padding-top: $spacing-lg;
|
||
border-top: 1rpx solid $border-color-light;
|
||
}
|
||
.addr-actions button {
|
||
font-size: $font-sm;
|
||
height: 52rpx;
|
||
line-height: 52rpx;
|
||
padding: 0 $spacing-lg;
|
||
border-radius: $radius-round;
|
||
margin: 0;
|
||
font-weight: 600;
|
||
border: none;
|
||
background: $bg-secondary;
|
||
color: $text-main;
|
||
|
||
&::after { border: none; }
|
||
|
||
&:active {
|
||
transform: scale(0.96);
|
||
background: darken($bg-secondary, 5%);
|
||
}
|
||
}
|
||
.addr-actions button[type="warn"] {
|
||
background: rgba($color-error, 0.1) !important;
|
||
color: $color-error !important;
|
||
}
|
||
.addr-actions button:not([type]) {
|
||
background: $bg-secondary !important;
|
||
color: $text-main !important;
|
||
}
|
||
|
||
/* 空状态 */
|
||
.empty {
|
||
text-align: center;
|
||
color: $text-sub;
|
||
margin-top: 120rpx;
|
||
font-size: $font-md;
|
||
}
|
||
|
||
/* 错误提示 */
|
||
.error {
|
||
color: $color-error;
|
||
font-size: $font-sm;
|
||
margin-bottom: $spacing-md;
|
||
padding: $spacing-md;
|
||
background: rgba($color-error, 0.1);
|
||
border-radius: $radius-md;
|
||
text-align: center;
|
||
}
|
||
|
||
@keyframes fadeInUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
</style> |