继续完善
This commit is contained in:
@@ -25,14 +25,46 @@ export interface Product {
|
||||
original_price?: number
|
||||
image?: string
|
||||
manufacturer: string
|
||||
sales: number
|
||||
stock: number
|
||||
sales?: number
|
||||
stock?: number
|
||||
badge?: string
|
||||
shop_id?: string
|
||||
shop_name?: string
|
||||
created_at?: string
|
||||
}
|
||||
|
||||
export interface CartItem {
|
||||
id: string
|
||||
user_id: string
|
||||
product_id: string
|
||||
sku_id?: string
|
||||
quantity: number
|
||||
selected: boolean
|
||||
product_name?: string
|
||||
product_image?: string
|
||||
product_price?: number
|
||||
product_specification?: string
|
||||
shop_id?: string
|
||||
shop_name?: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface UserAddress {
|
||||
id: string
|
||||
user_id: string
|
||||
recipient_name: string
|
||||
phone: string
|
||||
province: string
|
||||
city: string
|
||||
district: string
|
||||
detail_address: string
|
||||
postal_code?: string
|
||||
is_default: boolean
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[]
|
||||
total: number
|
||||
@@ -42,6 +74,17 @@ export interface PaginatedResponse<T> {
|
||||
}
|
||||
|
||||
class SupabaseService {
|
||||
// 获取当前用户ID
|
||||
private getCurrentUserId(): string | null {
|
||||
try {
|
||||
const userId = uni.getStorageSync('user_id')
|
||||
return userId ? userId as string : null
|
||||
} catch (e) {
|
||||
console.error('获取用户ID失败:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有分类
|
||||
async getCategories(): Promise<Category[]> {
|
||||
try {
|
||||
@@ -176,7 +219,7 @@ class SupabaseService {
|
||||
.select('*')
|
||||
.eq('id', productId)
|
||||
.single()
|
||||
.execute()
|
||||
.executeAs<Product>()
|
||||
|
||||
if (response.error) {
|
||||
console.error('获取商品详情失败:', response.error)
|
||||
@@ -304,6 +347,561 @@ class SupabaseService {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的购物车商品(关联商品和店铺信息)
|
||||
async getCartItems(): Promise<CartItem[]> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.warn('用户未登录,无法获取购物车')
|
||||
return []
|
||||
}
|
||||
|
||||
// 查询购物车表,并关联商品表(使用内联关联)
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.select(`
|
||||
id,
|
||||
user_id,
|
||||
product_id,
|
||||
sku_id,
|
||||
quantity,
|
||||
selected,
|
||||
created_at,
|
||||
updated_at,
|
||||
products!inner (
|
||||
id,
|
||||
name,
|
||||
image,
|
||||
price,
|
||||
specification,
|
||||
shop_id,
|
||||
shop_name
|
||||
)
|
||||
`)
|
||||
.eq('user_id', userId)
|
||||
.order('created_at', { ascending: false })
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('获取购物车失败:', response.error)
|
||||
return []
|
||||
}
|
||||
|
||||
// 处理返回数据,构建CartItem数组
|
||||
const cartItems: CartItem[] = []
|
||||
if (response.data && Array.isArray(response.data)) {
|
||||
for (const item of response.data) {
|
||||
const product = item.products as any
|
||||
|
||||
cartItems.push({
|
||||
id: item.id as string,
|
||||
user_id: item.user_id as string,
|
||||
product_id: item.product_id as string,
|
||||
sku_id: item.sku_id as string,
|
||||
quantity: item.quantity as number,
|
||||
selected: item.selected as boolean,
|
||||
product_name: product?.name as string,
|
||||
product_image: product?.image as string,
|
||||
product_price: product?.price as number,
|
||||
product_specification: product?.specification as string,
|
||||
shop_id: product?.shop_id as string,
|
||||
shop_name: product?.shop_name as string,
|
||||
created_at: item.created_at as string,
|
||||
updated_at: item.updated_at as string
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return cartItems
|
||||
} catch (error) {
|
||||
console.error('获取购物车异常:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 添加商品到购物车
|
||||
async addToCart(productId: string, quantity: number = 1, skuId?: string): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法添加商品到购物车')
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查商品是否已在购物车中
|
||||
const existingResponse = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.select('*')
|
||||
.eq('user_id', userId)
|
||||
.eq('product_id', productId)
|
||||
.eq('sku_id', skuId || '')
|
||||
.single()
|
||||
.execute()
|
||||
|
||||
let response
|
||||
if (existingResponse.data) {
|
||||
// 商品已存在,更新数量
|
||||
const existingItem = existingResponse.data as any
|
||||
response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.update({
|
||||
quantity: (existingItem.quantity || 0) + quantity,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', existingItem.id)
|
||||
.execute()
|
||||
} else {
|
||||
// 商品不存在,添加新记录
|
||||
response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.insert({
|
||||
user_id: userId,
|
||||
product_id: productId,
|
||||
sku_id: skuId || null,
|
||||
quantity: quantity,
|
||||
selected: true,
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.execute()
|
||||
}
|
||||
|
||||
if (response.error) {
|
||||
console.error('添加商品到购物车失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('添加商品到购物车异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 更新购物车商品数量
|
||||
async updateCartItemQuantity(cartItemId: string, quantity: number): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法更新购物车')
|
||||
return false
|
||||
}
|
||||
|
||||
if (quantity < 1) {
|
||||
// 数量小于1时删除商品
|
||||
return await this.deleteCartItem(cartItemId)
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.update({
|
||||
quantity: quantity,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', cartItemId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('更新购物车商品数量失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('更新购物车商品数量异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 更新购物车商品选中状态
|
||||
async updateCartItemSelection(cartItemId: string, selected: boolean): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法更新购物车')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.update({
|
||||
selected: selected,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', cartItemId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('更新购物车商品选中状态失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('更新购物车商品选中状态异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 批量更新购物车商品选中状态
|
||||
async batchUpdateCartItemSelection(cartItemIds: string[], selected: boolean): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法更新购物车')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.update({
|
||||
selected: selected,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('user_id', userId)
|
||||
.in('id', cartItemIds)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('批量更新购物车商品选中状态失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('批量更新购物车商品选中状态异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 删除购物车商品
|
||||
async deleteCartItem(cartItemId: string): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法删除购物车商品')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.delete()
|
||||
.eq('id', cartItemId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('删除购物车商品失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('删除购物车商品异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 批量删除购物车商品
|
||||
async batchDeleteCartItems(cartItemIds: string[]): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法删除购物车商品')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.delete()
|
||||
.eq('user_id', userId)
|
||||
.in('id', cartItemIds)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('批量删除购物车商品失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('批量删除购物车商品异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 清空购物车
|
||||
async clearCart(): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法清空购物车')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_shopping_cart')
|
||||
.delete()
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('清空购物车失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('清空购物车异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的所有地址
|
||||
async getAddresses(): Promise<UserAddress[]> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.warn('用户未登录,无法获取地址')
|
||||
return []
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.select('*')
|
||||
.eq('user_id', userId)
|
||||
.order('is_default', { ascending: false })
|
||||
.order('created_at', { ascending: false })
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('获取地址失败:', response.error)
|
||||
return []
|
||||
}
|
||||
|
||||
return response.data as UserAddress[]
|
||||
} catch (error) {
|
||||
console.error('获取地址异常:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 根据ID获取地址详情
|
||||
async getAddressById(addressId: string): Promise<UserAddress | null> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.warn('用户未登录,无法获取地址')
|
||||
return null
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.select('*')
|
||||
.eq('id', addressId)
|
||||
.eq('user_id', userId)
|
||||
.single()
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('获取地址详情失败:', response.error)
|
||||
return null
|
||||
}
|
||||
|
||||
return response.data as UserAddress
|
||||
} catch (error) {
|
||||
console.error('获取地址详情异常:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新地址
|
||||
async addAddress(address: {
|
||||
recipient_name: string
|
||||
phone: string
|
||||
province: string
|
||||
city: string
|
||||
district: string
|
||||
detail_address: string
|
||||
postal_code?: string
|
||||
is_default?: boolean
|
||||
}): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法添加地址')
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果设置为默认地址,需要先取消其他默认地址
|
||||
if (address.is_default) {
|
||||
await this.clearDefaultAddress(userId)
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.insert({
|
||||
user_id: userId,
|
||||
recipient_name: address.recipient_name,
|
||||
phone: address.phone,
|
||||
province: address.province,
|
||||
city: address.city,
|
||||
district: address.district,
|
||||
detail_address: address.detail_address,
|
||||
postal_code: address.postal_code || null,
|
||||
is_default: address.is_default || false,
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('添加地址失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('添加地址异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 更新地址
|
||||
async updateAddress(addressId: string, address: {
|
||||
recipient_name?: string
|
||||
phone?: string
|
||||
province?: string
|
||||
city?: string
|
||||
district?: string
|
||||
detail_address?: string
|
||||
postal_code?: string
|
||||
is_default?: boolean
|
||||
}): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法更新地址')
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果设置为默认地址,需要先取消其他默认地址
|
||||
if (address.is_default) {
|
||||
await this.clearDefaultAddress(userId)
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.update({
|
||||
...address,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', addressId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('更新地址失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('更新地址异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 删除地址
|
||||
async deleteAddress(addressId: string): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法删除地址')
|
||||
return false
|
||||
}
|
||||
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.delete()
|
||||
.eq('id', addressId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('删除地址失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('删除地址异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认地址
|
||||
async setDefaultAddress(addressId: string): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (!userId) {
|
||||
console.error('用户未登录,无法设置默认地址')
|
||||
return false
|
||||
}
|
||||
|
||||
// 先取消所有默认地址
|
||||
await this.clearDefaultAddress(userId)
|
||||
|
||||
// 设置新的默认地址
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.update({
|
||||
is_default: true,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', addressId)
|
||||
.eq('user_id', userId)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('设置默认地址失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('设置默认地址异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 清除用户的默认地址(内部方法)
|
||||
private async clearDefaultAddress(userId: string): Promise<boolean> {
|
||||
try {
|
||||
const response = await supa
|
||||
.from('ml_user_addresses')
|
||||
.update({
|
||||
is_default: false,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('user_id', userId)
|
||||
.eq('is_default', true)
|
||||
.execute()
|
||||
|
||||
if (response.error) {
|
||||
console.error('清除默认地址失败:', response.error)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('清除默认地址异常:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例实例
|
||||
|
||||
Reference in New Issue
Block a user