继续完善

This commit is contained in:
2026-01-30 17:29:02 +08:00
parent ab038ec029
commit d57592ca7d
14 changed files with 8003 additions and 407 deletions

View File

@@ -120,8 +120,42 @@
</view>
<scroll-view class="address-list-container" scroll-y>
<!-- 登录提示 -->
<view v-if="!isLoggedIn" class="login-prompt" @click="goToLogin">
<text class="login-prompt-icon">🔒</text>
<text class="login-prompt-text">您尚未登录,点击登录以同步服务器地址</text>
<text class="login-prompt-arrow"></text>
</view>
<!-- 地址列表 -->
<view v-if="addressList.length > 0">
<view v-if="isLoggedIn">
<view v-if="addressList.length > 0">
<view v-for="address in addressList" :key="address.id"
class="popup-address-item" @click="handleSelectAddress(address)">
<view class="popup-address-header">
<text class="popup-address-name">{{ address.recipient_name }}</text>
<text class="popup-address-phone">{{ address.phone }}</text>
<view v-if="address.is_default" class="popup-default-tag">
<text class="popup-tag-text">默认</text>
</view>
</view>
<text class="popup-address-detail">{{ getFullAddress(address) }}</text>
<view v-if="selectedAddress && selectedAddress.id === address.id" class="popup-selected-indicator">
<text>✓</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-else class="popup-empty-address">
<text class="popup-empty-icon">📍</text>
<text class="popup-empty-text">暂无收货地址</text>
</view>
</view>
<!-- 未登录时的本地地址展示 -->
<view v-if="!isLoggedIn && addressList.length > 0">
<text class="local-address-title">本地地址(未同步)</text>
<view v-for="address in addressList" :key="address.id"
class="popup-address-item" @click="handleSelectAddress(address)">
<view class="popup-address-header">
@@ -138,8 +172,8 @@
</view>
</view>
<!-- 状态 -->
<view v-else class="popup-empty-address">
<!-- 完全无地址状态 -->
<view v-if="isLoggedIn && addressList.length === 0" class="popup-empty-address">
<text class="popup-empty-icon">📍</text>
<text class="popup-empty-text">暂无收货地址</text>
</view>
@@ -241,6 +275,7 @@
<script setup lang="uts">
import { ref, onMounted, computed, watch, onUnmounted, getCurrentInstance } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { supabaseService, type UserAddress as SupabaseUserAddress } from '@/utils/supabaseService.uts'
type CheckoutItemType = {
id: string
@@ -467,9 +502,26 @@ onMounted(() => {
})
})
// 页面显示时触发
const onShow = () => {
console.log('checkout页面显示检查登录状态并重新加载地址')
// 检查用户登录状态
const userId = getCurrentUserId()
if (userId) {
console.log('用户已登录,重新加载地址数据')
// 重新加载默认地址和地址列表
loadDefaultAddress()
loadAddressList()
}
}
// 注册页面显示事件
uni.$on('checkoutPageShow', onShow)
// 组件卸载时移除事件监听
onUnmounted(() => {
uni.$off('addressUpdated')
uni.$off('checkoutPageShow')
// 离开页面时清除结算数据,防止下次进入时显示旧数据
uni.removeStorageSync('checkout_type')
uni.removeStorageSync('checkout_items')
@@ -523,76 +575,269 @@ const loadCheckoutData = () => {
// 加载默认地址
const loadDefaultAddress = async () => {
// 从本地存储加载地址数据
const storedAddresses = uni.getStorageSync('addresses')
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
try {
// 首先检查用户是否登录
const currentUserId = getCurrentUserId()
console.log('loadDefaultAddress: 当前用户ID:', currentUserId)
// 如果用户已登录尝试从Supabase加载地址数据
if (currentUserId) {
console.log('loadDefaultAddress: 用户已登录从Supabase加载地址')
const supabaseAddresses = await supabaseService.getAddresses()
console.log('loadDefaultAddress: Supabase返回地址:', supabaseAddresses)
if (supabaseAddresses && supabaseAddresses.length > 0) {
// 查找默认地址
const defaultAddress = addresses.find((addr: any) => addr.isDefault === true)
const defaultAddress = supabaseAddresses.find((addr: SupabaseUserAddress) => addr.is_default === true)
if (defaultAddress) {
// 转换地址格式以匹配selectedAddress的结构
selectedAddress.value = {
id: defaultAddress.id,
recipient_name: defaultAddress.name,
recipient_name: defaultAddress.recipient_name,
phone: defaultAddress.phone,
province: defaultAddress.province,
city: defaultAddress.city,
district: defaultAddress.district,
detail: defaultAddress.detail,
is_default: defaultAddress.isDefault
detail: defaultAddress.detail_address,
is_default: defaultAddress.is_default
}
console.log('loadDefaultAddress: 找到默认地址:', selectedAddress.value)
} else {
// 如果没有默认地址,使用第一个地址
const firstAddress = addresses[0]
const firstAddress = supabaseAddresses[0]
selectedAddress.value = {
id: firstAddress.id,
recipient_name: firstAddress.name,
recipient_name: firstAddress.recipient_name,
phone: firstAddress.phone,
province: firstAddress.province,
city: firstAddress.city,
district: firstAddress.district,
detail: firstAddress.detail,
is_default: firstAddress.isDefault
detail: firstAddress.detail_address,
is_default: firstAddress.is_default
}
console.log('loadDefaultAddress: 使用第一个地址:', selectedAddress.value)
}
// 同时更新本地存储缓存
const localAddresses = supabaseAddresses.map((addr: SupabaseUserAddress) => ({
id: addr.id,
name: addr.recipient_name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail_address,
isDefault: addr.is_default
}))
uni.setStorageSync('addresses', JSON.stringify(localAddresses))
console.log('loadDefaultAddress: 地址已保存到本地存储')
} else {
console.log('loadDefaultAddress: Supabase未返回地址数据')
}
}
// 如果Supabase没有地址数据或用户未登录尝试从本地存储加载
if (!selectedAddress.value) {
console.log('loadDefaultAddress: 尝试从本地存储加载地址')
const storedAddresses = uni.getStorageSync('addresses')
console.log('loadDefaultAddress: 本地存储地址数据:', storedAddresses)
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
// 查找默认地址
const defaultAddress = addresses.find((addr: any) => addr.isDefault === true)
if (defaultAddress) {
selectedAddress.value = {
id: defaultAddress.id,
recipient_name: defaultAddress.name,
phone: defaultAddress.phone,
province: defaultAddress.province,
city: defaultAddress.city,
district: defaultAddress.district,
detail: defaultAddress.detail,
is_default: defaultAddress.isDefault
}
console.log('loadDefaultAddress: 从本地存储找到默认地址:', selectedAddress.value)
} else {
// 如果没有默认地址,使用第一个地址
const firstAddress = addresses[0]
selectedAddress.value = {
id: firstAddress.id,
recipient_name: firstAddress.name,
phone: firstAddress.phone,
province: firstAddress.province,
city: firstAddress.city,
district: firstAddress.district,
detail: firstAddress.detail,
is_default: firstAddress.isDefault
}
console.log('loadDefaultAddress: 从本地存储使用第一个地址:', selectedAddress.value)
}
}
} catch (err) {
console.error('解析本地地址数据失败:', err)
}
}
} catch (err) {
console.error('解析地址数据失败:', err)
}
} else {
// 如果没有地址数据尝试使用Mock数据初始化为了演示效果
const mockAddress = {
id: 'addr_mock_default',
name: '测试用户',
phone: '13800138000',
province: '北京市',
city: '北京市',
district: '朝阳区',
detail: '三里屯SOHO A座',
isDefault: true
}
uni.setStorageSync('addresses', JSON.stringify([mockAddress]))
selectedAddress.value = {
id: mockAddress.id,
recipient_name: mockAddress.name,
phone: mockAddress.phone,
province: mockAddress.province,
city: mockAddress.city,
district: mockAddress.district,
detail: mockAddress.detail,
is_default: mockAddress.isDefault
}
}
// 如果仍然没有地址,使用模拟地址数据
if (!selectedAddress.value) {
console.log('loadDefaultAddress: 使用模拟地址数据')
// 模拟地址数据
const mockAddresses = [
{
id: 'addr_001',
name: '张三',
phone: '13800138001',
province: '北京市',
city: '北京市',
district: '朝阳区',
detail: '建国路88号SOHO现代城A座1001',
isDefault: true
},
{
id: 'addr_002',
name: '李四',
phone: '13900139001',
province: '上海市',
city: '上海市',
district: '浦东新区',
detail: '陆家嘴环路1000号汇亚大厦20层',
isDefault: false
}
]
// 保存模拟地址到本地存储
uni.setStorageSync('addresses', JSON.stringify(mockAddresses))
console.log('loadDefaultAddress: 模拟地址已保存到本地存储')
// 使用第一个地址作为默认地址
selectedAddress.value = {
id: mockAddresses[0].id,
recipient_name: mockAddresses[0].name,
phone: mockAddresses[0].phone,
province: mockAddresses[0].province,
city: mockAddresses[0].city,
district: mockAddresses[0].district,
detail: mockAddresses[0].detail,
is_default: mockAddresses[0].isDefault
}
console.log('loadDefaultAddress: 使用模拟地址:', selectedAddress.value)
}
// 如果仍然没有地址selectedAddress.value将保持为null
// 用户可以在结算页面点击地址区域添加新地址
} catch (error) {
console.error('从Supabase加载默认地址失败:', error)
// 失败时从本地存储加载
const storedAddresses = uni.getStorageSync('addresses')
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
const defaultAddress = addresses.find((addr: any) => addr.isDefault === true)
if (defaultAddress) {
selectedAddress.value = {
id: defaultAddress.id,
recipient_name: defaultAddress.name,
phone: defaultAddress.phone,
province: defaultAddress.province,
city: defaultAddress.city,
district: defaultAddress.district,
detail: defaultAddress.detail,
is_default: defaultAddress.isDefault
}
} else {
const firstAddress = addresses[0]
selectedAddress.value = {
id: firstAddress.id,
recipient_name: firstAddress.name,
phone: firstAddress.phone,
province: firstAddress.province,
city: firstAddress.city,
district: firstAddress.district,
detail: firstAddress.detail,
is_default: firstAddress.isDefault
}
}
}
} catch (err) {
console.error('解析本地地址数据失败:', err)
}
}
}
}
// 获取当前用户ID
const getCurrentUserId = (): string => {
const userStore = uni.getStorageSync('userInfo')
return userStore?.id || ''
// 尝试从多个可能的键名获取用户ID
const possibleKeys = ['user_id', 'userId', 'uid', 'user_uuid', 'userID', 'user.id']
for (const key of possibleKeys) {
const value = uni.getStorageSync(key)
console.log(`getCurrentUserId: 尝试键名 ${key}:`, value)
if (value) {
console.log(`getCurrentUserId: 从 ${key} 获取到用户ID:`, value)
return value as string
}
}
// 尝试从userInfo对象获取
const userInfo = uni.getStorageSync('userInfo')
console.log('getCurrentUserId: 从userInfo获取:', userInfo)
if (userInfo) {
// userInfo可能是字符串需要解析或对象
let userInfoObj: any = userInfo
if (typeof userInfo === 'string') {
try {
userInfoObj = JSON.parse(userInfo)
} catch (e) {
console.error('解析userInfo失败:', e)
}
}
// 尝试多个可能的属性名
const possibleProps = ['id', 'userId', 'uid', 'user_id', 'uuid', 'user_uuid']
for (const prop of possibleProps) {
if (userInfoObj && userInfoObj[prop]) {
console.log(`getCurrentUserId: 从userInfo.${prop} 获取到用户ID:`, userInfoObj[prop])
return userInfoObj[prop] as string
}
}
}
// 尝试从auth获取如果使用Supabase Auth
const authData = uni.getStorageSync('supabase.auth.token')
if (authData) {
console.log('getCurrentUserId: 从supabase.auth.token获取:', authData)
try {
const authObj = typeof authData === 'string' ? JSON.parse(authData) : authData
if (authObj.currentSession && authObj.currentSession.user && authObj.currentSession.user.id) {
console.log('getCurrentUserId: 从auth session获取用户ID:', authObj.currentSession.user.id)
return authObj.currentSession.user.id as string
}
} catch (e) {
console.error('解析auth数据失败:', e)
}
}
// 打印所有存储键,用于调试
console.log('getCurrentUserId: 所有Storage键:')
const allKeys = uni.getStorageInfoSync().keys
console.log('Storage keys:', allKeys)
console.log('getCurrentUserId: 未找到用户ID')
return ''
}
// 用户登录状态
const isLoggedIn = computed(() => {
const userId = getCurrentUserId()
return !!userId
})
// 获取完整地址
const getFullAddress = (address: any): string => {
return `${address.province}${address.city}${address.district}${address.detail}`
@@ -600,32 +845,159 @@ const getFullAddress = (address: any): string => {
// 加载地址列表
const loadAddressList = async () => {
// 从本地存储加载地址数据
const storedAddresses = uni.getStorageSync('addresses')
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
try {
// 首先检查用户是否登录
const currentUserId = getCurrentUserId()
console.log('loadAddressList: 当前用户ID:', currentUserId)
// 如果用户已登录尝试从Supabase加载地址数据
if (currentUserId) {
console.log('loadAddressList: 用户已登录从Supabase加载地址')
const supabaseAddresses = await supabaseService.getAddresses()
console.log('loadAddressList: Supabase返回地址:', supabaseAddresses)
if (supabaseAddresses && supabaseAddresses.length > 0) {
// 转换地址格式以匹配addressList的结构
addressList.value = addresses.map((addr: any) => ({
addressList.value = supabaseAddresses.map((addr: SupabaseUserAddress) => ({
id: addr.id,
recipient_name: addr.name,
recipient_name: addr.recipient_name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail,
is_default: addr.isDefault
detail: addr.detail_address,
is_default: addr.is_default
}))
console.log('loadAddressList: 从Supabase加载地址成功数量:', addressList.value.length)
// 同时更新本地存储缓存
const localAddresses = supabaseAddresses.map((addr: SupabaseUserAddress) => ({
id: addr.id,
name: addr.recipient_name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail_address,
isDefault: addr.is_default
}))
uni.setStorageSync('addresses', JSON.stringify(localAddresses))
console.log('loadAddressList: 地址已保存到本地存储')
} else {
console.log('loadAddressList: Supabase未返回地址数据')
}
}
// 如果Supabase没有地址数据或用户未登录尝试从本地存储加载
if (!addressList.value || addressList.value.length === 0) {
console.log('loadAddressList: 尝试从本地存储加载地址')
const storedAddresses = uni.getStorageSync('addresses')
console.log('loadAddressList: 本地存储地址数据:', storedAddresses)
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
// 转换地址格式以匹配addressList的结构
addressList.value = addresses.map((addr: any) => ({
id: addr.id,
recipient_name: addr.name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail,
is_default: addr.isDefault
}))
console.log('loadAddressList: 从本地存储加载地址成功,数量:', addressList.value.length)
} else {
addressList.value = []
console.log('loadAddressList: 本地存储地址为空数组')
}
} catch (err) {
console.error('解析本地地址数据失败:', err)
addressList.value = []
}
} else {
addressList.value = []
console.log('loadAddressList: 本地存储没有地址数据')
}
} catch (err) {
console.error('解析地址数据失败:', err)
}
// 如果仍然没有地址使用模拟地址数据与loadDefaultAddress保持一致
if (!addressList.value || addressList.value.length === 0) {
console.log('loadAddressList: 使用模拟地址数据')
// 模拟地址数据与loadDefaultAddress中保持一致
const mockAddresses = [
{
id: 'addr_001',
name: '张三',
phone: '13800138001',
province: '北京市',
city: '北京市',
district: '朝阳区',
detail: '建国路88号SOHO现代城A座1001',
isDefault: true
},
{
id: 'addr_002',
name: '李四',
phone: '13900139001',
province: '上海市',
city: '上海市',
district: '浦东新区',
detail: '陆家嘴环路1000号汇亚大厦20层',
isDefault: false
}
]
// 保存模拟地址到本地存储
uni.setStorageSync('addresses', JSON.stringify(mockAddresses))
console.log('loadAddressList: 模拟地址已保存到本地存储')
// 转换为checkout页面格式
addressList.value = mockAddresses.map((addr: any) => ({
id: addr.id,
recipient_name: addr.name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail,
is_default: addr.isDefault
}))
console.log('loadAddressList: 模拟地址已加载到地址列表,数量:', addressList.value.length)
}
console.log('loadAddressList: 最终地址列表:', addressList.value)
} catch (error) {
console.error('从Supabase加载地址列表失败:', error)
// 失败时从本地存储加载
const storedAddresses = uni.getStorageSync('addresses')
if (storedAddresses) {
try {
const addresses = JSON.parse(storedAddresses as string) as any[]
if (addresses && addresses.length > 0) {
// 转换地址格式以匹配addressList的结构
addressList.value = addresses.map((addr: any) => ({
id: addr.id,
recipient_name: addr.name,
phone: addr.phone,
province: addr.province,
city: addr.city,
district: addr.district,
detail: addr.detail,
is_default: addr.isDefault
}))
} else {
addressList.value = []
}
} catch (err) {
console.error('解析本地地址数据失败:', err)
addressList.value = []
}
} else {
addressList.value = []
}
} else {
addressList.value = []
}
}
@@ -1001,6 +1373,7 @@ const clearShoppingCart = async () => {
}
}
// 返回
const goBack = () => {
uni.navigateBack()