完成consumer端同步
This commit is contained in:
@@ -6,10 +6,7 @@ export { supa }
|
||||
import type { OrderOptions } from '@/components/supadb/aksupa.uts'
|
||||
|
||||
const OLD_URL = '192.168.1.61:18000'
|
||||
// const NEW_URL = '119.146.131.237:9126'
|
||||
|
||||
// 医疗项目 Supabase 实例地址(与 ak/config.uts 中的 SUPA_URL 保持一致,去掉 http:// 前缀)
|
||||
const NEW_URL = '119.146.131.237:9127'
|
||||
const NEW_URL = '119.146.131.237:9126'
|
||||
|
||||
function fixImageUrl(url: string | null): string {
|
||||
if (url == null) return ''
|
||||
@@ -424,6 +421,16 @@ export type ShopOrderParams = {
|
||||
discountAmount: number
|
||||
}
|
||||
|
||||
function emptyProductPage(page: number, limit: number): PaginatedResponse<Product> {
|
||||
return {
|
||||
data: [] as Product[],
|
||||
total: 0,
|
||||
page,
|
||||
limit,
|
||||
hasmore: false
|
||||
}
|
||||
}
|
||||
|
||||
export type ShopOrderResponse = {
|
||||
success: boolean
|
||||
orderIds: string[]
|
||||
@@ -1730,25 +1737,26 @@ class SupabaseService {
|
||||
}
|
||||
|
||||
// 获取按销量排序的商品(所有商品,不限制 is_hot)
|
||||
async getProductsBySales(limit: number = 10): Promise<Product[]> {
|
||||
async getProductsBySales(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
|
||||
try {
|
||||
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')
|
||||
.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' })
|
||||
.eq('status', '1')
|
||||
.order('sale_count', { ascending: false })
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.execute()
|
||||
|
||||
if (response.error != null) {
|
||||
console.error('获取销量排序商品失败:', response.error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const rawData = response.data
|
||||
if (rawData == null) {
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const products: Product[] = []
|
||||
@@ -1758,32 +1766,39 @@ class SupabaseService {
|
||||
products.push(parseProductFromRaw(item))
|
||||
}
|
||||
console.log('[getProductsBySales] 返回商品数:', products.length)
|
||||
return products
|
||||
return {
|
||||
data: products,
|
||||
total: response.total ?? products.length,
|
||||
page,
|
||||
limit,
|
||||
hasmore: response.hasmore ?? false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取销量排序商品异常:', error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取按价格排序的商品(升序:从低到高)
|
||||
async getProductsByPrice(limit: number = 10, ascending: boolean = true): Promise<Product[]> {
|
||||
async getProductsByPrice(page: number = 1, limit: number = 10, ascending: boolean = true): Promise<PaginatedResponse<Product>> {
|
||||
try {
|
||||
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('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' })
|
||||
.eq('status', '1') // 在数据库层面过滤
|
||||
.order('base_price', { ascending })
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.execute()
|
||||
|
||||
if (response.error != null) {
|
||||
console.error('获取价格排序商品失败:', response.error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const rawData = response.data
|
||||
if (rawData == null) {
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const products: Product[] = []
|
||||
@@ -1792,33 +1807,40 @@ class SupabaseService {
|
||||
const item = rawList[i]
|
||||
products.push(parseProductFromRaw(item))
|
||||
}
|
||||
return products
|
||||
return {
|
||||
data: products,
|
||||
total: response.total ?? products.length,
|
||||
page,
|
||||
limit,
|
||||
hasmore: response.hasmore ?? false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取价格排序商品异常:', error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取新品(按创建时间排序,最新的在前)
|
||||
async getProductsByNewest(limit: number = 10): Promise<Product[]> {
|
||||
async getProductsByNewest(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
|
||||
try {
|
||||
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')
|
||||
.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' })
|
||||
.eq('status', '1')
|
||||
.order('created_at', { ascending: false })
|
||||
.page(page)
|
||||
.limit(limit * 5)
|
||||
.execute()
|
||||
|
||||
if (response.error != null) {
|
||||
console.error('获取新品失败:', response.error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const rawData = response.data
|
||||
if (rawData == null) {
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
|
||||
const products: Product[] = []
|
||||
@@ -1864,10 +1886,17 @@ class SupabaseService {
|
||||
}
|
||||
|
||||
console.log('[getProductsByNewest] 返回商品数:', products.length)
|
||||
return products
|
||||
const pageData = products.slice(0, limit)
|
||||
return {
|
||||
data: pageData,
|
||||
total: response.total ?? products.length,
|
||||
page,
|
||||
limit,
|
||||
hasmore: products.length > limit || (response.hasmore ?? false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取新品异常:', error)
|
||||
return []
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5821,12 +5850,13 @@ class SupabaseService {
|
||||
}
|
||||
|
||||
// 智能推荐:综合用户搜索历史、浏览历史、热销商品
|
||||
async getSmartRecommendations(limit: number = 10): Promise<Product[]> {
|
||||
async getSmartRecommendations(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Product>> {
|
||||
try {
|
||||
console.log('[getSmartRecommendations] 开始获取智能推荐...')
|
||||
|
||||
const products: Product[] = []
|
||||
const addedIds = new Set<string>()
|
||||
const requiredCount = page * limit + 1
|
||||
|
||||
// 1. 根据用户搜索历史推荐商品(权重最高)
|
||||
const searchHistory = await this.getUserSearchHistory(5)
|
||||
@@ -5834,7 +5864,7 @@ class SupabaseService {
|
||||
|
||||
if (searchHistory.length > 0) {
|
||||
// 根据搜索关键词查找商品
|
||||
const keywordProducts = await this.searchProductsByKeywords(searchHistory, limit)
|
||||
const keywordProducts = await this.searchProductsByKeywords(searchHistory, requiredCount)
|
||||
for (let i = 0; i < keywordProducts.length; i++) {
|
||||
const prod = keywordProducts[i]
|
||||
if (!addedIds.has(prod.id)) {
|
||||
@@ -5845,53 +5875,63 @@ class SupabaseService {
|
||||
}
|
||||
|
||||
// 2. 根据用户浏览历史推荐相似分类商品
|
||||
if (products.length < limit) {
|
||||
if (products.length < requiredCount) {
|
||||
const browseCategories = await this.getUserBrowseCategories(3)
|
||||
console.log('[getSmartRecommendations] 用户浏览分类:', browseCategories)
|
||||
|
||||
if (browseCategories.length > 0) {
|
||||
const categoryProducts = await this.getProductsByCategories(browseCategories, limit - products.length)
|
||||
const categoryProducts = await this.getProductsByCategories(browseCategories, requiredCount - products.length)
|
||||
for (let i = 0; i < categoryProducts.length; i++) {
|
||||
const prod = categoryProducts[i]
|
||||
if (!addedIds.has(prod.id)) {
|
||||
products.push(prod)
|
||||
addedIds.add(prod.id)
|
||||
if (products.length >= requiredCount) break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 补充热销商品
|
||||
if (products.length < limit) {
|
||||
const hotProducts = await this.getHotProducts(limit - products.length + 5)
|
||||
if (products.length < requiredCount) {
|
||||
const hotProducts = await this.getHotProducts(requiredCount - products.length + 5)
|
||||
for (let i = 0; i < hotProducts.length; i++) {
|
||||
const prod = hotProducts[i]
|
||||
if (!addedIds.has(prod.id)) {
|
||||
products.push(prod)
|
||||
addedIds.add(prod.id)
|
||||
if (products.length >= limit) break
|
||||
if (products.length >= requiredCount) break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 如果还不够,用普通商品补充
|
||||
if (products.length < limit) {
|
||||
const moreProducts = await this.getProductsByPrice(limit - products.length + 5, false)
|
||||
for (let i = 0; i < moreProducts.length; i++) {
|
||||
const prod = moreProducts[i]
|
||||
if (products.length < requiredCount) {
|
||||
const moreProducts = await this.getProductsByPrice(1, requiredCount - products.length + 5, false)
|
||||
for (let i = 0; i < moreProducts.data.length; i++) {
|
||||
const prod = moreProducts.data[i]
|
||||
if (!addedIds.has(prod.id)) {
|
||||
products.push(prod)
|
||||
addedIds.add(prod.id)
|
||||
if (products.length >= limit) break
|
||||
if (products.length >= requiredCount) break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[getSmartRecommendations] 返回商品数量:', products.length)
|
||||
return products.slice(0, limit)
|
||||
const startIndex = (page - 1) * limit
|
||||
const endIndex = startIndex + limit
|
||||
const pageData = products.slice(startIndex, endIndex)
|
||||
console.log('[getSmartRecommendations] 返回商品数量:', pageData.length)
|
||||
return {
|
||||
data: pageData,
|
||||
total: products.length,
|
||||
page,
|
||||
limit,
|
||||
hasmore: products.length > endIndex
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取智能推荐失败:', e)
|
||||
return [] as Product[]
|
||||
return emptyProductPage(page, limit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user