解决登录显示、首页显示bug

This commit is contained in:
2026-05-19 11:06:46 +08:00
parent 2f7e097e6c
commit 00a859c551
181 changed files with 55329 additions and 998 deletions

View File

@@ -1,5 +1,6 @@
import supa from '@/components/supadb/aksupainstance.uts'
import type { AkReqResponse } from '@/uni_modules/ak-req/index.uts'
import { APP_ROLE, CURRENT_CLIENT, SUPA_KEY, SUPA_URL } from '@/ak/config.uts'
// 导出 supa 实例,供 services 层统一使用
export { supa }
@@ -35,6 +36,65 @@ function fixImageUrls(urls: any): string[] {
return []
}
function canUseConsumerData(): boolean {
return CURRENT_CLIENT === 'consumer' || CURRENT_CLIENT === 'full'
}
function maskConsumerKey(key: string): string {
const keyLen = key.length
if (keyLen <= 20) {
return '(too short)'
}
return key.substring(0, 10) + '...' + key.substring(keyLen - 8)
}
function logConsumerQueryStart(action: string, tableName: string, fieldList: string = '*'): boolean {
if (!canUseConsumerData()) {
console.error('[consumer-db] 已阻止非 consumer 数据请求')
console.error('[consumer-db] 当前端类型:', CURRENT_CLIENT)
console.error('[consumer-db] 当前应用角色:', APP_ROLE)
console.error('[consumer-db] 查询表:', tableName)
console.error('[consumer-db] 查询动作:', action)
return false
}
console.log('[consumer-db] 当前端类型:', CURRENT_CLIENT)
console.log('[consumer-db] 当前应用角色:', APP_ROLE)
console.log('[consumer-db] supabaseUrl 已加载:', SUPA_URL)
console.log('[consumer-db] supabaseKey 已加载:', maskConsumerKey(SUPA_KEY))
console.log('[consumer-db] 首页开始加载数据')
console.log('[consumer-db] 查询表:', tableName)
console.log('[consumer-db] 查询字段:', fieldList)
console.log('[consumer-db] 查询动作:', action)
return true
}
function logConsumerQuerySuccess(action: string, tableName: string, count: number): void {
console.log('[consumer-db] 查询成功,动作:', action)
console.log('[consumer-db] 查询成功,表:', tableName)
console.log('[consumer-db] 查询成功,数量:', count)
}
function logConsumerQueryFailure(action: string, tableName: string, error: any): void {
console.error('[consumer-db] 查询失败')
console.error('[consumer-db] 查询动作:', action)
console.error('[consumer-db] 查询表:', tableName)
if (error != null) {
try {
console.error('[consumer-db] error.message:', error.message)
} catch (e) {}
try {
console.error('[consumer-db] error.code:', error.code)
} catch (e) {}
try {
console.error('[consumer-db] error.details:', error.details)
} catch (e) {}
try {
console.error('[consumer-db] error.hint:', error.hint)
} catch (e) {}
}
console.error('[consumer-db] error.raw:', error)
}
// 使用单例 Supabase 客户端
// const supa = createClient(SUPA_URL, SUPA_KEY)
@@ -602,14 +662,18 @@ class SupabaseService {
// 获取一级分类
async getParentCategories(): Promise<Category[]> {
try {
if (!logConsumerQueryStart('getParentCategories', 'ml_categories', '*')) {
return []
}
const response = await supa
.from('ml_categories')
.select('*')
.is('parent_id', null)
.eq('level', 1)
.order('sort_order', { ascending: true })
.execute()
if (response.error != null) {
logConsumerQueryFailure('getParentCategories', 'ml_categories', response.error)
console.error('获取一级分类失败:', response.error)
return []
}
@@ -643,8 +707,10 @@ class SupabaseService {
}
categories.push(cat)
}
logConsumerQuerySuccess('getParentCategories', 'ml_categories', categories.length)
return categories
} catch (error) {
logConsumerQueryFailure('getParentCategories', 'ml_categories', error)
console.error('获取一级分类异常:', error)
return []
}
@@ -653,16 +719,22 @@ class SupabaseService {
// 获取子分类
async getSubCategories(parentId: string): Promise<Category[]> {
try {
if (!logConsumerQueryStart('getSubCategories', 'ml_categories', '*')) {
return []
}
console.log('[getSubCategories] 开始获取子分类, parentId:', parentId)
const response = await supa
.from('ml_categories')
.select('*')
.eq('level', 2)
.eq('parent_id', parentId)
.order('sort_order', { ascending: true })
.execute()
console.log('[getSubCategories] 查询完成')
if (response.error != null) {
logConsumerQueryFailure('getSubCategories', 'ml_categories', response.error)
console.error('获取子分类失败:', response.error)
return []
}
@@ -674,20 +746,13 @@ class SupabaseService {
}
const categories: Category[] = []
const rawList = rawData as any[]
const rawList = rawData as UTSJSONObject[]
console.log('[getSubCategories] 原始数据条数:', rawList.length)
for (let i = 0; i < rawList.length; i++) {
const item = rawList[i]
const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
// 手动过滤 parent_id
const itemParentId = safeGetString(itemObj, 'parent_id')
const isMatch = (itemParentId.length > 0 && itemParentId == parentId)
if (!isMatch) {
continue
}
const icon = this.getCategoryIcon(itemObj)
const cat: Category = {
id: safeGetString(itemObj, 'id'),
@@ -702,8 +767,10 @@ class SupabaseService {
categories.push(cat)
}
console.log('[getSubCategories] 返回分类数量:', categories.length)
logConsumerQuerySuccess('getSubCategories', 'ml_categories', categories.length)
return categories
} catch (error) {
logConsumerQueryFailure('getSubCategories', 'ml_categories', error)
console.error('获取子分类异常:', error)
return []
}
@@ -736,6 +803,9 @@ class SupabaseService {
// 获取所有品牌
async getBrands(): Promise<Brand[]> {
try {
if (!logConsumerQueryStart('getBrands', 'ml_brands', 'id, name, logo_url, description, is_active')) {
return []
}
console.log('[getBrands] 开始获取品牌数据...')
const response = await supa
.from('ml_brands')
@@ -744,6 +814,7 @@ class SupabaseService {
.execute()
if (response.error != null) {
logConsumerQueryFailure('getBrands', 'ml_brands', response.error)
console.error('获取品牌失败:', response.error)
return []
}
@@ -788,8 +859,10 @@ class SupabaseService {
brands.push(brand)
}
console.log('[getBrands] 返回品牌数量:', brands.length)
logConsumerQuerySuccess('getBrands', 'ml_brands', brands.length)
return brands
} catch (error) {
logConsumerQueryFailure('getBrands', 'ml_brands', error)
console.error('获取品牌异常:', error)
return []
}
@@ -802,6 +875,9 @@ class SupabaseService {
limit: number = 20
): Promise<PaginatedResponse<Product>> {
try {
if (!logConsumerQueryStart('getProductsByCategory', 'ml_products_detail_view', '*')) {
return emptyProductPage(page, limit)
}
console.log('[getProductsByCategory] 开始查询分类ID:', categoryId, '页码:', page)
// 在数据库层面进行分类过滤
@@ -818,6 +894,7 @@ class SupabaseService {
console.log('[getProductsByCategory] 查询完成total:', response.total)
if (response.error != null) {
logConsumerQueryFailure('getProductsByCategory', 'ml_products_detail_view', response.error)
console.error('获取商品失败:', response.error)
return {
data: [] as Product[],
@@ -847,6 +924,7 @@ class SupabaseService {
const item = rawList[i]
products.push(parseProductFromRaw(item))
}
logConsumerQuerySuccess('getProductsByCategory', 'ml_products_detail_view', products.length)
return {
data: products,
@@ -856,6 +934,7 @@ class SupabaseService {
hasmore: response.hasmore ?? false
}
} catch (error) {
logConsumerQueryFailure('getProductsByCategory', 'ml_products_detail_view', error)
console.error('获取商品异常:', error)
return {
data: [] as Product[],
@@ -1689,7 +1768,7 @@ class SupabaseService {
// 在数据库层面过滤 status获取更多数据以便手动过滤 is_hot
const response = await supa
.from('ml_products_detail_view')
.select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')
.select('*')
.eq('status', '1') // 使用字符串 '1'
.order('sale_count', { ascending: false })
.limit(limit * 5) // 获取更多数据以便过滤
@@ -1739,10 +1818,13 @@ class SupabaseService {
// 获取按销量排序的商品(所有商品,不限制 is_hot
async getProductsBySales(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
try {
if (!logConsumerQueryStart('getProductsBySales', 'ml_products_detail_view', '*')) {
return emptyProductPage(page, limit)
}
console.log('[getProductsBySales] 开始获取销量排序商品...')
const response = await supa
.from('ml_products_detail_view')
.select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot', { count: 'exact' })
.select('*', { count: 'exact' })
.eq('status', '1')
.order('sale_count', { ascending: false })
.page(page)
@@ -1750,6 +1832,7 @@ class SupabaseService {
.execute()
if (response.error != null) {
logConsumerQueryFailure('getProductsBySales', 'ml_products_detail_view', response.error)
console.error('获取销量排序商品失败:', response.error)
return emptyProductPage(page, limit)
}
@@ -1766,6 +1849,7 @@ class SupabaseService {
products.push(parseProductFromRaw(item))
}
console.log('[getProductsBySales] 返回商品数:', products.length)
logConsumerQuerySuccess('getProductsBySales', 'ml_products_detail_view', products.length)
return {
data: products,
total: response.total ?? products.length,
@@ -1774,6 +1858,7 @@ class SupabaseService {
hasmore: response.hasmore ?? false
}
} catch (error) {
logConsumerQueryFailure('getProductsBySales', 'ml_products_detail_view', error)
console.error('获取销量排序商品异常:', error)
return emptyProductPage(page, limit)
}
@@ -1782,9 +1867,12 @@ class SupabaseService {
// 获取按价格排序的商品(升序:从低到高)
async getProductsByPrice(page: number = 1, limit: number = 10, ascending: boolean = true): Promise<PaginatedResponse<Product>> {
try {
if (!logConsumerQueryStart('getProductsByPrice', 'ml_products_detail_view', '*')) {
return emptyProductPage(page, limit)
}
const response = await supa
.from('ml_products_detail_view')
.select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot', { count: 'exact' })
.select('*', { count: 'exact' })
.eq('status', '1') // 在数据库层面过滤
.order('base_price', { ascending })
.page(page)
@@ -1792,6 +1880,7 @@ class SupabaseService {
.execute()
if (response.error != null) {
logConsumerQueryFailure('getProductsByPrice', 'ml_products_detail_view', response.error)
console.error('获取价格排序商品失败:', response.error)
return emptyProductPage(page, limit)
}
@@ -1807,6 +1896,7 @@ class SupabaseService {
const item = rawList[i]
products.push(parseProductFromRaw(item))
}
logConsumerQuerySuccess('getProductsByPrice', 'ml_products_detail_view', products.length)
return {
data: products,
total: response.total ?? products.length,
@@ -1815,6 +1905,7 @@ class SupabaseService {
hasmore: response.hasmore ?? false
}
} catch (error) {
logConsumerQueryFailure('getProductsByPrice', 'ml_products_detail_view', error)
console.error('获取价格排序商品异常:', error)
return emptyProductPage(page, limit)
}
@@ -1823,17 +1914,22 @@ class SupabaseService {
// 获取新品(按创建时间排序,最新的在前)
async getProductsByNewest(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
try {
if (!logConsumerQueryStart('getProductsByNewest', 'ml_products_detail_view', '*')) {
return emptyProductPage(page, limit)
}
console.log('[getProductsByNewest] 开始获取新品...')
const response = await supa
.from('ml_products_detail_view')
.select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot', { count: 'exact' })
.select('*', { count: 'exact' })
.eq('status', '1')
.order('is_new', { ascending: false })
.order('created_at', { ascending: false })
.page(page)
.limit(limit * 5)
.limit(limit)
.execute()
if (response.error != null) {
logConsumerQueryFailure('getProductsByNewest', 'ml_products_detail_view', response.error)
console.error('获取新品失败:', response.error)
return emptyProductPage(page, limit)
}
@@ -1847,54 +1943,20 @@ class SupabaseService {
const rawList = rawData as any[]
for (let i: number = 0; i < rawList.length; i++) {
const item = rawList[i]
const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
// 手动过滤 is_new
const rawIsNew = prodObj.get('is_new')
let isNewBool: boolean = false
if (typeof rawIsNew == 'boolean') {
isNewBool = rawIsNew as boolean
} else if (typeof rawIsNew == 'number') {
isNewBool = (rawIsNew as number) == 1
}
if (!isNewBool) continue
products.push(parseProductFromRaw(item))
if (products.length >= limit) break
}
// 如果 is_new 商品不足,补充普通商品
if (products.length < limit) {
console.log('[getProductsByNewest] is_new商品不足补充普通商品')
const addedIds = new Set<string>()
for (let i = 0; i < products.length; i++) {
addedIds.add(products[i].id)
}
for (let i: number = 0; i < rawList.length; i++) {
const item = rawList[i]
const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
const rawId = prodObj.get('id')
const itemId = (typeof rawId == 'string') ? (rawId as string) : ''
if (!addedIds.has(itemId)) {
products.push(parseProductFromRaw(item))
addedIds.add(itemId)
if (products.length >= limit) break
}
}
}
console.log('[getProductsByNewest] 返回商品数:', products.length)
const pageData = products.slice(0, limit)
logConsumerQuerySuccess('getProductsByNewest', 'ml_products_detail_view', products.length)
return {
data: pageData,
data: products,
total: response.total ?? products.length,
page,
limit,
hasmore: products.length > limit || (response.hasmore ?? false)
hasmore: response.hasmore ?? false
}
} catch (error) {
logConsumerQueryFailure('getProductsByNewest', 'ml_products_detail_view', error)
console.error('获取新品异常:', error)
return emptyProductPage(page, limit)
}
@@ -1903,6 +1965,9 @@ class SupabaseService {
// 获取推荐商品is_featured=true
async getRecommendedProducts(limit: number = 10): Promise<Product[]> {
try {
if (!logConsumerQueryStart('getRecommendedProducts', 'ml_products_detail_view', 'id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')) {
return []
}
console.log('[getRecommendedProducts] 开始获取推荐商品...')
const response = await supa
.from('ml_products_detail_view')
@@ -1915,6 +1980,7 @@ class SupabaseService {
console.log('[getRecommendedProducts] 查询完成')
if (response.error != null) {
logConsumerQueryFailure('getRecommendedProducts', 'ml_products_detail_view', response.error)
console.error('获取推荐商品失败:', response.error)
return []
}
@@ -1947,8 +2013,10 @@ class SupabaseService {
products.push(parseProductFromRaw(item))
if (products.length >= limit) break
}
logConsumerQuerySuccess('getRecommendedProducts', 'ml_products_detail_view', products.length)
return products
} catch (error) {
logConsumerQueryFailure('getRecommendedProducts', 'ml_products_detail_view', error)
console.error('获取推荐商品异常:', error)
return []
}
@@ -1957,6 +2025,10 @@ class SupabaseService {
// 获取特价商品这里假设没有specific flag, just use logic or tag if exists, defaulting to hot for now or just skip
// Modify to use compatible logic if badge column doesn't exist
async getDiscountProducts(limit: number = 10): Promise<Product[]> {
if (!logConsumerQueryStart('getDiscountProducts', 'ml_products_detail_view', '(none)')) {
return [] as Product[]
}
logConsumerQuerySuccess('getDiscountProducts', 'ml_products_detail_view', 0)
return [] as Product[] // 暂无特价字段
}
@@ -5660,6 +5732,9 @@ class SupabaseService {
// 获取热搜词(全站搜索频率最高的关键词)
async getHotKeywords(limit: number = 10): Promise<string[]> {
try {
if (!logConsumerQueryStart('getHotKeywords', 'ml_search_history', 'keyword')) {
return [] as string[]
}
const response = await supa
.from('ml_search_history')
.select('keyword')
@@ -5668,6 +5743,7 @@ class SupabaseService {
.execute()
if (response.error != null || response.data == null) {
logConsumerQueryFailure('getHotKeywords', 'ml_search_history', response.error)
return [] as string[]
}
@@ -5712,8 +5788,10 @@ class SupabaseService {
sortedKeywords.push(entryArray[i].keyword)
}
logConsumerQuerySuccess('getHotKeywords', 'ml_search_history', sortedKeywords.length)
return sortedKeywords
} catch (e) {
logConsumerQueryFailure('getHotKeywords', 'ml_search_history', e)
console.error('获取热搜词失败:', e)
return [] as string[]
}
@@ -5809,8 +5887,8 @@ class SupabaseService {
// 查询这些商品的分类
const prodResponse = await supa
.from('ml_products')
.select('category_id')
.from('ml_products_detail_view')
.select('id, category_id')
.limit(50)
.execute()
@@ -5852,6 +5930,9 @@ class SupabaseService {
// 智能推荐:综合用户搜索历史、浏览历史、热销商品
async getSmartRecommendations(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
try {
if (!logConsumerQueryStart('getSmartRecommendations', 'ml_products_detail_view', 'composed: search_history + browse_history + products_detail_view')) {
return emptyProductPage(page, limit)
}
console.log('[getSmartRecommendations] 开始获取智能推荐...')
const products: Product[] = []
@@ -5922,6 +6003,7 @@ class SupabaseService {
const endIndex = startIndex + limit
const pageData = products.slice(startIndex, endIndex)
console.log('[getSmartRecommendations] 返回商品数量:', pageData.length)
logConsumerQuerySuccess('getSmartRecommendations', 'ml_products_detail_view', pageData.length)
return {
data: pageData,
total: products.length,
@@ -5930,6 +6012,7 @@ class SupabaseService {
hasmore: products.length > endIndex
}
} catch (e) {
logConsumerQueryFailure('getSmartRecommendations', 'ml_products_detail_view', e)
console.error('获取智能推荐失败:', e)
return emptyProductPage(page, limit)
}