邹方成 6f7207da2d feat: 优化UI设计并重构样式系统
refactor(components): 重构ElCard、FlipGrid、YifanSelector和PaymentPopup组件样式
refactor(pages): 优化地址管理、商品详情、订单列表、积分记录和活动页面UI
style: 更新uni.scss全局样式变量和设计系统
docs: 添加说明文档记录UI优化进度
2025-12-17 14:32:55 +08:00

270 lines
6.1 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>