consumer模块完成度95%,安卓端大部分页面能正常获取数据,页面样式显示基本正常,逐渐完善;消费者端的积分、余额、评价、优惠券等小模块正在完善

This commit is contained in:
cyh666666
2026-03-03 17:02:53 +08:00
parent 7e74b88e1e
commit cceb556c62
15 changed files with 4975 additions and 612 deletions

View File

@@ -1314,7 +1314,7 @@ class SupabaseService {
const mappedData: Product[] = []
const rawData = res2.data as any[]
for(let i = 0; i < rawData.length; i++) {
const item = rawData[i] as UTSJSONObject
const item = JSON.parse(JSON.stringify(rawData[i])) as UTSJSONObject
const images: string[] = []
const mainImageUrl = item.getString('main_image_url')
@@ -1479,7 +1479,7 @@ class SupabaseService {
const mappedData: Product[] = []
const rawData = res2.data as any[]
for(let i = 0; i < rawData.length; i++) {
const item = rawData[i] as UTSJSONObject
const item = JSON.parse(JSON.stringify(rawData[i])) as UTSJSONObject
const images: string[] = []
const mainImageUrl = item.getString('main_image_url')
@@ -2745,12 +2745,14 @@ class SupabaseService {
// 批量删除购物车商品
async batchDeleteCartItems(cartItemIds: string[]): Promise<boolean> {
try {
console.log('[batchDeleteCartItems] 开始删除, ids:', cartItemIds.length)
const userId = this.getCurrentUserId()
if (userId == null) {
console.error('用户未登录,无法删除购物车商品')
return false
}
console.log('[batchDeleteCartItems] userId:', userId)
const response = await supa
.from('ml_shopping_cart')
.eq('user_id', userId)
@@ -2758,11 +2760,13 @@ class SupabaseService {
.delete()
.execute()
console.log('[batchDeleteCartItems] response.error:', response.error)
if (response.error != null) {
console.error('批量删除购物车商品失败:', response.error)
return false
}
console.log('[batchDeleteCartItems] 删除成功')
return true
} catch (error) {
console.error('批量删除购物车商品异常:', error)
@@ -2840,17 +2844,21 @@ class SupabaseService {
itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
}
const addrObj = new UTSJSONObject()
addrObj.set('id', itemObj.getString('id') ?? '')
addrObj.set('user_id', itemObj.getString('user_id') ?? '')
addrObj.set('recipient_name', itemObj.getString('receiver_name') ?? itemObj.getString('recipient_name') ?? '')
addrObj.set('phone', itemObj.getString('receiver_phone') ?? itemObj.getString('phone') ?? '')
addrObj.set('province', itemObj.getString('province') ?? '')
addrObj.set('city', itemObj.getString('city') ?? '')
addrObj.set('district', itemObj.getString('district') ?? '')
addrObj.set('detail_address', itemObj.getString('address_detail') ?? itemObj.getString('detail_address') ?? '')
addrObj.set('is_default', itemObj.getBoolean('is_default') ?? false)
result.push(addrObj as UserAddress)
const addr: UserAddress = {
id: itemObj.getString('id') ?? '',
user_id: itemObj.getString('user_id') ?? '',
recipient_name: itemObj.getString('receiver_name') ?? itemObj.getString('recipient_name') ?? '',
phone: itemObj.getString('receiver_phone') ?? itemObj.getString('phone') ?? '',
province: itemObj.getString('province') ?? '',
city: itemObj.getString('city') ?? '',
district: itemObj.getString('district') ?? '',
detail_address: itemObj.getString('address_detail') ?? itemObj.getString('detail_address') ?? '',
is_default: itemObj.getBoolean('is_default') ?? false,
label: itemObj.getString('label') ?? '',
created_at: itemObj.getString('created_at') ?? '',
updated_at: itemObj.getString('updated_at') ?? ''
}
result.push(addr)
}
console.log('[getAddresses] 返回地址数量:', result.length)
@@ -3168,9 +3176,22 @@ class SupabaseService {
const queryData = queryResponse.data as any
let orderId = ''
console.log('[CreateOrder] queryData 类型:', typeof queryData, '是否数组:', Array.isArray(queryData))
if (Array.isArray(queryData) && queryData.length > 0) {
const firstItem = queryData[0] as Record<string, any>
orderId = firstItem['id'] as string
console.log('[CreateOrder] queryData 长度:', queryData.length)
const firstItemRaw = queryData[0]
console.log('[CreateOrder] firstItemRaw 类型:', typeof firstItemRaw)
// 将 firstItemRaw 转换为可访问的对象
const firstItemStr = JSON.stringify(firstItemRaw)
const firstItemParsed = JSON.parse(firstItemStr)
if (firstItemParsed == null) {
console.error('[CreateOrder] 解析订单数据失败')
return null
}
const firstItem = firstItemParsed as UTSJSONObject
orderId = (firstItem.getString('id') ?? '') as string
console.log('[CreateOrder] 找到新创建的订单, id:', orderId)
} else {
console.error('[CreateOrder] 未找到新创建的订单,插入可能失败')
@@ -3180,12 +3201,21 @@ class SupabaseService {
console.log('[CreateOrder] 订单创建成功, orderId:', orderId)
const orderItems: UTSJSONObject[] = []
console.log('[CreateOrder] orderData.items 类型:', typeof orderData.items, '是否数组:', Array.isArray(orderData.items))
const rawItems = orderData.items as any[]
console.log('[CreateOrder] rawItems 长度:', rawItems.length)
for(let i = 0; i < rawItems.length; i++) {
let item: UTSJSONObject
console.log('[CreateOrder] 处理商品项', i, '类型:', typeof rawItems[i])
const rawItem = rawItems[i]
item = rawItem as UTSJSONObject
const itemStr = JSON.stringify(rawItem)
console.log('[CreateOrder] 商品项 JSON:', itemStr)
const itemParsed = JSON.parse(itemStr)
if (itemParsed == null) {
console.error('[CreateOrder] 商品项解析失败')
continue
}
const item = itemParsed as UTSJSONObject
const itemJson = new UTSJSONObject()
@@ -3193,19 +3223,21 @@ class SupabaseService {
if (pId == null) {
pId = item.get('id')
}
const productId = (pId ?? '') as string
itemJson.set('order_id', orderId)
itemJson.set('product_id', pId)
itemJson.set('product_id', productId)
const skuIdVal = item.get('sku_id')
if (skuIdVal != null && skuIdVal !== '') {
itemJson.set('sku_id', skuIdVal)
itemJson.set('sku_id', skuIdVal as string)
}
itemJson.set('product_name', item.get('product_name') ?? '')
const productName = (item.get('product_name') ?? '') as string
itemJson.set('product_name', productName)
const sName = item.get('sku_name')
itemJson.set('sku_name', sName ?? '')
itemJson.set('sku_name', (sName ?? '') as string)
const specVal = item.get('specifications')
let skuSnapshot = '{}'
@@ -3221,7 +3253,7 @@ class SupabaseService {
const img1 = item.get('product_image')
const img2 = item.get('image_url')
let imgUrl = (img1 ?? img2 ?? '') as string
let imgUrl = ((img1 ?? img2 ?? '') as string)
while (imgUrl.indexOf('`') >= 0) {
imgUrl = imgUrl.replace('`', '')
}
@@ -3238,15 +3270,31 @@ class SupabaseService {
}
console.log('[CreateOrder] 插入订单项数量:', orderItems.length)
console.log('[CreateOrder] 订单项数据:', JSON.stringify(orderItems))
for (let j: number = 0; j < orderItems.length; j++) {
console.log('[CreateOrder] 开始插入订单项', j)
const itemJson = orderItems[j]
// 将 UTSJSONObject 转换为普通对象
console.log('[CreateOrder] 序列化订单项...')
const itemObjStr = JSON.stringify(itemJson)
console.log('[CreateOrder] 订单项 JSON:', itemObjStr)
const itemObjParsed = JSON.parse(itemObjStr)
console.log('[CreateOrder] itemObjParsed 类型:', typeof itemObjParsed)
if (itemObjParsed == null) {
console.error('[CreateOrder] 订单项转换失败')
continue
}
// 使用 UTSJSONObject 而不是 Record<string, any>
const itemObj = itemObjParsed as UTSJSONObject
console.log('[CreateOrder] 执行 insert...')
const itemsResponse = await supa
.from('ml_order_items')
.insert(itemJson)
.insert(itemObj)
.execute()
console.log('[CreateOrder] insert 完成, error:', itemsResponse.error)
if (itemsResponse.error != null) {
console.error('[CreateOrder] 创建订单项失败:', itemsResponse.error)
}
@@ -3256,7 +3304,10 @@ class SupabaseService {
const cartItemIds: string[] = []
for(let i = 0; i < rawItems.length; i++) {
const item = rawItems[i] as UTSJSONObject
const rawItem = rawItems[i]
const itemParsed = JSON.parse(JSON.stringify(rawItem))
if (itemParsed == null) continue
const item = itemParsed as UTSJSONObject
const iid = item.getString('id')
if (iid != null && iid.length > 10) {
cartItemIds.push(iid)
@@ -3282,14 +3333,14 @@ class SupabaseService {
let grandTotal = 0.0
for(let k = 0; k < groups.length; k++) {
const g = groups[k] as UTSJSONObject
const g = JSON.parse(JSON.stringify(groups[k])) as UTSJSONObject
// 安全获取 items 数组
const gItemsRaw = g.get('items')
if (gItemsRaw == null) continue
const gItems = gItemsRaw as any[]
for(let gi = 0; gi < gItems.length; gi++) {
const it = gItems[gi] as UTSJSONObject
const it = JSON.parse(JSON.stringify(gItems[gi])) as UTSJSONObject
const itPrice = it.getNumber('price') ?? 0
const itQty = it.getNumber('quantity') ?? 1
grandTotal += itPrice * itQty
@@ -3298,14 +3349,14 @@ class SupabaseService {
// 为每个店铺创建一个订单
for (let i = 0; i < groups.length; i++) {
const group = groups[i] as UTSJSONObject
const group = JSON.parse(JSON.stringify(groups[i])) as UTSJSONObject
const shopItemsRaw = group.get('items')
if (shopItemsRaw == null) continue
const shopItems = shopItemsRaw as any[]
let productAmount = 0.0
for(let j = 0; j < shopItems.length; j++) {
const sItem = shopItems[j] as UTSJSONObject
const sItem = JSON.parse(JSON.stringify(shopItems[j])) as UTSJSONObject
const siPrice = sItem.getNumber('price') ?? 0
const siQty = sItem.getNumber('quantity') ?? 1
productAmount += siPrice * siQty
@@ -3329,6 +3380,16 @@ class SupabaseService {
const finalMerchantId = (mId != null && mId != '') ? mId : (sId ?? '')
console.log('[createOrdersByShop] 最终使用的 merchant_id:', finalMerchantId)
// 将 shopItems 转换为普通对象数组
const plainItems: any[] = []
for(let k = 0; k < shopItems.length; k++) {
const plainItemRaw = JSON.parse(JSON.stringify(shopItems[k]))
if (plainItemRaw != null) {
plainItems.push(plainItemRaw as any)
}
}
console.log('[createOrdersByShop] plainItems 数量:', plainItems.length)
const orderId = await this.createOrder({
merchant_id: finalMerchantId,
@@ -3336,7 +3397,7 @@ class SupabaseService {
shipping_fee: shopShippingFee,
total_amount: shopTotal,
shipping_address: params.shipping_address,
items: shopItems
items: plainItems
})
if (orderId != null) {
@@ -3362,12 +3423,10 @@ class SupabaseService {
return empty
}
// 关联查询店铺表获取店铺名称
let query = supa
.from('ml_orders')
.select(`
*,
ml_order_items (*)
`)
.select('*, ml_order_items(*), ml_shops(shop_name)')
.eq('user_id', userId)
.order('created_at', { ascending: false })
@@ -3377,6 +3436,11 @@ class SupabaseService {
const response = await query.execute()
console.log('[getOrders] response.error:', response.error)
if (response.data != null && Array.isArray(response.data)) {
console.log('[getOrders] 订单数量:', response.data.length)
}
if (response.error != null) {
console.error('获取订单列表失败:', response.error)
const empty: any[] = []
@@ -3405,14 +3469,14 @@ class SupabaseService {
const response = await supa
.from('ml_orders')
.select(`
*,
ml_order_items (*)
`)
.select('*, ml_order_items(*)')
.eq('id', orderId)
.eq('user_id', userId)
.eq('user_id', userId!)
.limit(1)
.execute()
console.log('[getOrderDetail] response.error:', response.error)
console.log('[getOrderDetail] response.data:', JSON.stringify(response.data))
if (response.error != null) {
console.error('[getOrderDetail] 获取订单详情失败:', response.error)
@@ -3433,7 +3497,35 @@ class SupabaseService {
const orderData = rawList[0]
console.log('[getOrderDetail] 成功获取订单')
return orderData
const orderObj = JSON.parse(JSON.stringify(orderData)) as UTSJSONObject
const result = new UTSJSONObject()
result.set('id', orderObj.get('id') ?? '')
result.set('order_no', orderObj.get('order_no') ?? '')
result.set('order_status', orderObj.get('order_status') ?? 1)
result.set('user_id', orderObj.get('user_id') ?? '')
result.set('merchant_id', orderObj.get('merchant_id') ?? '')
result.set('product_amount', orderObj.get('product_amount') ?? 0)
result.set('shipping_fee', orderObj.get('shipping_fee') ?? 0)
result.set('total_amount', orderObj.get('total_amount') ?? 0)
result.set('paid_amount', orderObj.get('paid_amount') ?? 0)
result.set('discount_amount', orderObj.get('discount_amount') ?? 0)
result.set('payment_method', orderObj.get('payment_method') ?? '')
result.set('payment_status', orderObj.get('payment_status') ?? 1)
result.set('shipping_status', orderObj.get('shipping_status') ?? 1)
result.set('created_at', orderObj.get('created_at') ?? '')
result.set('paid_at', orderObj.get('paid_at') ?? '')
result.set('shipped_at', orderObj.get('shipped_at') ?? '')
result.set('completed_at', orderObj.get('completed_at') ?? '')
result.set('shipping_address', orderObj.get('shipping_address'))
result.set('ml_order_items', orderObj.get('ml_order_items'))
// 添加物流信息
result.set('tracking_no', orderObj.get('tracking_no') ?? '')
result.set('carrier_name', orderObj.get('carrier_name') ?? '')
result.set('delivered_at', orderObj.get('delivered_at') ?? '')
return result
} catch (e) {
console.error('[getOrderDetail] 获取订单详情异常:', e)
return null
@@ -3537,7 +3629,7 @@ class SupabaseService {
const userId = this.getCurrentUserId()
if (userId == null) return { success: false, message: '请先登录' }
const d = data as UTSJSONObject
const d = JSON.parse(JSON.stringify(data)) as UTSJSONObject
const orderId = d.getString('order_id')
const refundType = d.getNumber('refund_type')
const refundReason = d.getString('refund_reason')
@@ -3578,7 +3670,7 @@ class SupabaseService {
async rePurchase(order: any): Promise<boolean> {
try {
// 将 order 转换为 UTSJSONObject 以安全访问属性
const orderObj = order as UTSJSONObject
const orderObj = JSON.parse(JSON.stringify(order)) as UTSJSONObject
// 尝试获取 ml_order_items 或 items
let itemsKey = 'ml_order_items'
let itemsRaw = orderObj.get(itemsKey)
@@ -3597,7 +3689,7 @@ class SupabaseService {
// 简单的循环添加,实际项目中可以优化为批量插入
for (let i = 0; i < items.length; i++) {
// 同样item 也是 UTSJSONObject 或支持访问的对象
const item = items[i] as UTSJSONObject
const item = JSON.parse(JSON.stringify(items[i])) as UTSJSONObject
const productId = item.getString('product_id')
const skuId = item.getString('sku_id')
// 数量可能是数字或字符串
@@ -4157,12 +4249,11 @@ class SupabaseService {
console.log(`[ToggleFav] Current status: ${exists}`)
if (exists) {
// Delete
const response = await supa
.from('ml_user_favorites')
.eq('user_id', userId!)
.eq('target_id', productId)
.eq('target_type', 1)
.eq('target_type', '1')
.delete()
.execute()
@@ -4172,13 +4263,12 @@ class SupabaseService {
}
return false // 已取消收藏
} else {
// Add
const response = await supa
.from('ml_user_favorites')
.insert({
user_id: userId,
target_id: productId,
target_type: 1,
target_type: '1',
created_at: new Date().toISOString()
})
.execute()
@@ -4209,7 +4299,7 @@ class SupabaseService {
.from('ml_user_favorites')
.select('*')
.eq('user_id', userId!)
.eq('target_type', 1)
.eq('target_type', '1')
.order('created_at', { ascending: false })
.execute()
@@ -4227,12 +4317,22 @@ class SupabaseService {
const productIds: string[] = []
for (let i = 0; i < favorites.length; i++) {
let item: any = favorites[i]
let pid = ''
let itemObj: UTSJSONObject
if (item instanceof UTSJSONObject) {
pid = item.getString('target_id') ?? ''
itemObj = item as UTSJSONObject
} else {
const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
pid = itemObj.getString('target_id') ?? ''
itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
}
// target_id 可能是 Integer 或 String 类型,需要安全转换
const targetIdRaw = itemObj.get('target_id')
let pid = ''
if (targetIdRaw != null) {
if (typeof targetIdRaw === 'string') {
pid = targetIdRaw as string
} else if (typeof targetIdRaw === 'number') {
pid = (targetIdRaw as number).toString()
}
}
if (pid !== '') productIds.push(pid)
}
@@ -4274,16 +4374,24 @@ class SupabaseService {
let newItem: UTSJSONObject
if (item instanceof UTSJSONObject) {
// Deep copy to ensure we have a fresh object to modify
newItem = JSON.parse(JSON.stringify(item)) as UTSJSONObject
} else {
newItem = JSON.parse(JSON.stringify(item)) as UTSJSONObject
}
let targetId = newItem.getString('target_id')
// Careful with null targetId
if (targetId != null) {
const product = productMap.get(targetId as string)
// target_id 可能是 Integer 或 String 类型,需要安全转换
const targetIdRaw = newItem.get('target_id')
let targetId = ''
if (targetIdRaw != null) {
if (typeof targetIdRaw === 'string') {
targetId = targetIdRaw as string
} else if (typeof targetIdRaw === 'number') {
targetId = (targetIdRaw as number).toString()
}
}
if (targetId !== '') {
const product = productMap.get(targetId)
if (product != null) {
newItem.set('ml_products', product)
result.push(newItem)
@@ -4689,12 +4797,9 @@ class SupabaseService {
// 如果没有 view可能需要改为两个查询或者使用 left join
const response = await supa
.from('ml_user_coupons')
.select(`
*,
template:ml_coupon_templates(name, amount, min_spend)
`)
.select('*, template:ml_coupon_templates(name, amount, min_spend)')
.eq('user_id', userId!)
.eq('status', status)
.eq('status', status.toString())
.order('expire_at', { ascending: true })
.execute()
@@ -4789,9 +4894,9 @@ class SupabaseService {
.from('ml_user_coupons')
.select('id', { count: 'exact' })
.eq('user_id', userId!)
.eq('status', 1) // 1: unused
.gt('expire_at', new Date().toISOString()) // 未过期
.limit(1) // Limit to 1 to reduce data transfer, we only want the count
.eq('status', '1')
.gt('expire_at', new Date().toISOString())
.limit(1)
.execute()
if (response.error != null) {