完善下单逻辑及其ui展示,修复支付倒计时显示错误bug
This commit is contained in:
@@ -436,68 +436,6 @@ function buildServiceImageText(categoryId: string): string {
|
||||
return '服'
|
||||
}
|
||||
|
||||
function buildMockServiceProducts(): Array<HomeCareServiceProductType> {
|
||||
// TODO: 后续替换为服务首页专用接口,当前仅在真实服务目录为空时兜底。
|
||||
return [
|
||||
{
|
||||
id: 'svc-001',
|
||||
title: '基础上门照护',
|
||||
subtitle: '协助起居、日常陪护、健康观察',
|
||||
categoryId: 'basic_care',
|
||||
price: 99,
|
||||
unit: '次',
|
||||
tags: ['平台认证', '可预约'],
|
||||
salesText: '已服务230+',
|
||||
imageText: '护',
|
||||
coverGradient: getServiceGradient('basic_care'),
|
||||
detailPath: '/pages/mall/consumer/home-service/service-detail?id=svc-001',
|
||||
bookingPath: '/pages/mall/consumer/home-service/service-detail?id=svc-001&mode=booking'
|
||||
},
|
||||
{
|
||||
id: 'svc-002',
|
||||
title: '居家康复指导',
|
||||
subtitle: '术后恢复、动作训练、康复评估',
|
||||
categoryId: 'rehab',
|
||||
price: 129,
|
||||
unit: '次',
|
||||
tags: ['康复指导', '上门服务'],
|
||||
salesText: '已服务180+',
|
||||
imageText: '康',
|
||||
coverGradient: getServiceGradient('rehab'),
|
||||
detailPath: '/pages/mall/consumer/home-service/service-detail?id=svc-002',
|
||||
bookingPath: '/pages/mall/consumer/home-service/service-detail?id=svc-002&mode=booking'
|
||||
},
|
||||
{
|
||||
id: 'svc-mock-escort',
|
||||
title: '陪诊陪护服务',
|
||||
subtitle: '挂号陪同、检查陪同、取药协助',
|
||||
categoryId: 'escort',
|
||||
price: 168,
|
||||
unit: '次',
|
||||
tags: ['陪诊服务', '安心陪护'],
|
||||
salesText: '已服务320+',
|
||||
imageText: '陪',
|
||||
coverGradient: getServiceGradient('escort'),
|
||||
detailPath: '',
|
||||
bookingPath: ''
|
||||
},
|
||||
{
|
||||
id: 'svc-003',
|
||||
title: '慢病随访服务',
|
||||
subtitle: '血压血糖记录、健康建议、定期回访',
|
||||
categoryId: 'chronic',
|
||||
price: 79,
|
||||
unit: '次',
|
||||
tags: ['慢病管理', '健康随访'],
|
||||
salesText: '已服务150+',
|
||||
imageText: '访',
|
||||
coverGradient: getServiceGradient('chronic'),
|
||||
detailPath: '/pages/mall/consumer/home-service/service-detail?id=svc-003',
|
||||
bookingPath: '/pages/mall/consumer/home-service/service-detail?id=svc-003&mode=booking'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function buildServiceProductsFromCatalog(catalog: Array<HomeServiceCatalogType>): Array<HomeCareServiceProductType> {
|
||||
const result: Array<HomeCareServiceProductType> = []
|
||||
for (let i = 0; i < catalog.length; i++) {
|
||||
@@ -525,14 +463,10 @@ async function loadServiceHomeData(): Promise<void> {
|
||||
serviceLoading.value = true
|
||||
try {
|
||||
const catalog = await fetchHomeServiceCatalog()
|
||||
if (catalog.length > 0) {
|
||||
allServiceProducts.value = buildServiceProductsFromCatalog(catalog)
|
||||
} else {
|
||||
allServiceProducts.value = buildMockServiceProducts()
|
||||
}
|
||||
allServiceProducts.value = buildServiceProductsFromCatalog(catalog)
|
||||
} catch (error) {
|
||||
console.error('加载服务首页数据失败', error)
|
||||
allServiceProducts.value = buildMockServiceProducts()
|
||||
allServiceProducts.value = [] as Array<HomeCareServiceProductType>
|
||||
} finally {
|
||||
serviceLoading.value = false
|
||||
}
|
||||
@@ -620,6 +554,8 @@ const hotProducts = ref<Product[]>([])
|
||||
const recommendedProducts = ref<Product[]>([])
|
||||
const hotKeywords = ref<string[]>([])
|
||||
const defaultLoadLimit: number = 6
|
||||
const recommendChannelLoadLimit: number = 16
|
||||
const categoryChannelLoadLimit: number = 12
|
||||
|
||||
// 屏幕尺寸检测
|
||||
const isMobile = ref(false)
|
||||
@@ -922,10 +858,376 @@ function buildSimpleChannelCoverImages(startIndex: number): string[] {
|
||||
return covers
|
||||
}
|
||||
|
||||
function buildSimpleCategoryChannels(categoryId: string): SimpleCategoryChannel[] {
|
||||
return []
|
||||
function getRealProductImage(product: Product): string {
|
||||
if (product.main_image_url != null && product.main_image_url !== '') {
|
||||
return product.main_image_url
|
||||
}
|
||||
if (product.images != null && product.images.length > 0 && product.images[0] !== '') {
|
||||
return product.images[0]
|
||||
}
|
||||
if (product.image_url != null && product.image_url !== '') {
|
||||
return product.image_url
|
||||
}
|
||||
return '/static/images/default.png'
|
||||
}
|
||||
|
||||
function getRealSalePrice(product: Product): number {
|
||||
return product.base_price ?? product.price ?? 0
|
||||
}
|
||||
|
||||
|
||||
function getRealMarketPrice(product: Product): number {
|
||||
return product.market_price ?? product.original_price ?? 0
|
||||
}
|
||||
|
||||
function toChannelProduct(product: Product, labelPrefix: string): ChannelProduct {
|
||||
const salePrice = getRealSalePrice(product)
|
||||
const marketPrice = getRealMarketPrice(product)
|
||||
const shortName = product.short_title != null && product.short_title !== ''
|
||||
? product.short_title
|
||||
: (product.name != null && product.name !== '' ? product.name : product.id)
|
||||
return {
|
||||
id: product.id,
|
||||
name: product.name != null && product.name !== '' ? product.name : product.id,
|
||||
shortName,
|
||||
image: getRealProductImage(product),
|
||||
price: salePrice,
|
||||
marketPrice,
|
||||
tag: labelPrefix
|
||||
} as ChannelProduct
|
||||
}
|
||||
|
||||
function getProductDiscountScore(product: Product): number {
|
||||
const salePrice = getRealSalePrice(product)
|
||||
const marketPrice = getRealMarketPrice(product)
|
||||
if (marketPrice <= salePrice || marketPrice <= 0) {
|
||||
return 0
|
||||
}
|
||||
const discountValue = marketPrice - salePrice
|
||||
const discountRate = discountValue / marketPrice
|
||||
return discountRate * 100000 + discountValue
|
||||
}
|
||||
|
||||
function getProductQualityScore(product: Product): number {
|
||||
let score = 0
|
||||
if (product.is_featured == true) {
|
||||
score = score + 100000
|
||||
}
|
||||
if (product.is_hot == true) {
|
||||
score = score + 50000
|
||||
}
|
||||
score = score + (product.sale_count ?? 0)
|
||||
return score
|
||||
}
|
||||
|
||||
function getProductHotScore(product: Product): number {
|
||||
let score = product.sale_count ?? 0
|
||||
if (product.is_hot == true) {
|
||||
score = score + 100000
|
||||
}
|
||||
if (product.is_featured == true) {
|
||||
score = score + 50000
|
||||
}
|
||||
score = score + getProductDiscountScore(product)
|
||||
return score
|
||||
}
|
||||
|
||||
function cloneProductArray(source: Array<Product>): Array<Product> {
|
||||
const result: Array<Product> = []
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
result.push(source[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function sortProductsByScoreDesc(source: Array<Product>, scoreType: string): Array<Product> {
|
||||
const result = cloneProductArray(source)
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let j = i + 1; j < result.length; j++) {
|
||||
let leftScore = 0
|
||||
let rightScore = 0
|
||||
if (scoreType == 'discount') {
|
||||
leftScore = getProductDiscountScore(result[i])
|
||||
rightScore = getProductDiscountScore(result[j])
|
||||
} else if (scoreType == 'quality') {
|
||||
leftScore = getProductQualityScore(result[i])
|
||||
rightScore = getProductQualityScore(result[j])
|
||||
} else {
|
||||
leftScore = getProductHotScore(result[i])
|
||||
rightScore = getProductHotScore(result[j])
|
||||
}
|
||||
if (rightScore > leftScore) {
|
||||
const temp = result[i]
|
||||
result[i] = result[j]
|
||||
result[j] = temp
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function sortProductsByPriceAsc(source: Array<Product>): Array<Product> {
|
||||
const result = cloneProductArray(source)
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let j = i + 1; j < result.length; j++) {
|
||||
const leftPrice = getRealSalePrice(result[i])
|
||||
const rightPrice = getRealSalePrice(result[j])
|
||||
if (rightPrice < leftPrice) {
|
||||
const temp = result[i]
|
||||
result[i] = result[j]
|
||||
result[j] = temp
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function filterProductsByMode(source: Array<Product>, mode: string): Array<Product> {
|
||||
const result: Array<Product> = []
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
const item = source[i]
|
||||
const salePrice = getRealSalePrice(item)
|
||||
const marketPrice = getRealMarketPrice(item)
|
||||
if (mode == 'discount' && marketPrice > salePrice) {
|
||||
result.push(item)
|
||||
continue
|
||||
}
|
||||
if (mode == 'quality' && (item.is_featured == true || item.is_hot == true)) {
|
||||
result.push(item)
|
||||
continue
|
||||
}
|
||||
if (mode == 'cheap-9' && salePrice > 0 && salePrice <= 9.9) {
|
||||
result.push(item)
|
||||
continue
|
||||
}
|
||||
if (mode == 'cheap-19' && salePrice > 0 && salePrice <= 19.9) {
|
||||
result.push(item)
|
||||
continue
|
||||
}
|
||||
if (mode == 'live' && (item.is_hot == true || (item.sale_count ?? 0) > 0)) {
|
||||
result.push(item)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function mergeUniqueProductLists(first: Array<Product>, second: Array<Product>, third: Array<Product>): Array<Product> {
|
||||
const result: Array<Product> = []
|
||||
const seenIds: Array<string> = []
|
||||
const sources: Array<Array<Product>> = [first, second, third]
|
||||
for (let sourceIndex = 0; sourceIndex < sources.length; sourceIndex++) {
|
||||
const source = sources[sourceIndex]
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
const item = source[i]
|
||||
const productId = item.id ?? ''
|
||||
if (productId != '' && seenIds.indexOf(productId) != -1) {
|
||||
continue
|
||||
}
|
||||
if (productId != '') {
|
||||
seenIds.push(productId)
|
||||
}
|
||||
result.push(item)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function appendChannelProducts(source: Array<Product>, result: Array<Product>, selectedIds: Array<string>, desiredCount: number, allowRepeat: boolean): void {
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
if (result.length >= desiredCount) {
|
||||
return
|
||||
}
|
||||
const item = source[i]
|
||||
const productId = item.id ?? ''
|
||||
let existsInResult = false
|
||||
for (let j = 0; j < result.length; j++) {
|
||||
if (result[j].id == productId) {
|
||||
existsInResult = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (existsInResult) {
|
||||
continue
|
||||
}
|
||||
if (!allowRepeat && productId != '' && selectedIds.indexOf(productId) != -1) {
|
||||
continue
|
||||
}
|
||||
result.push(item)
|
||||
if (!allowRepeat && productId != '') {
|
||||
selectedIds.push(productId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectChannelProducts(primary: Array<Product>, secondary: Array<Product>, fallback: Array<Product>, selectedIds: Array<string>, desiredCount: number): Array<Product> {
|
||||
const result: Array<Product> = []
|
||||
appendChannelProducts(primary, result, selectedIds, desiredCount, false)
|
||||
appendChannelProducts(secondary, result, selectedIds, desiredCount, false)
|
||||
appendChannelProducts(fallback, result, selectedIds, desiredCount, false)
|
||||
appendChannelProducts(primary, result, selectedIds, desiredCount, true)
|
||||
appendChannelProducts(secondary, result, selectedIds, desiredCount, true)
|
||||
appendChannelProducts(fallback, result, selectedIds, desiredCount, true)
|
||||
return result
|
||||
}
|
||||
|
||||
function buildChannelFromTemplate(template: MarketingChannel, products: Array<Product>, labelPrefix: string): MarketingChannel {
|
||||
const mappedProducts: Array<ChannelProduct> = []
|
||||
for (let i = 0; i < products.length; i++) {
|
||||
mappedProducts.push(toChannelProduct(products[i], labelPrefix))
|
||||
}
|
||||
return {
|
||||
id: template.id,
|
||||
title: template.title,
|
||||
subtitle: template.subtitle,
|
||||
badge: template.badge,
|
||||
themeColor: template.themeColor,
|
||||
bgColor: template.bgColor,
|
||||
routeType: template.routeType,
|
||||
layoutType: template.layoutType,
|
||||
products: mappedProducts,
|
||||
moreProducts: mappedProducts
|
||||
} as MarketingChannel
|
||||
}
|
||||
|
||||
function logChannelProducts(channelTitle: string, products: Array<Product>): void {
|
||||
for (let i = 0; i < products.length; i++) {
|
||||
const item = products[i]
|
||||
console.log('[home-channel] ' + channelTitle + ' product:', item.id, item.name ?? '', getRealProductImage(item), getRealSalePrice(item), getRealMarketPrice(item))
|
||||
}
|
||||
}
|
||||
|
||||
function buildRealRecommendMarketingChannels(products: Array<Product>): MarketingChannel[] {
|
||||
console.log('[home-channel] buildRealRecommendMarketingChannels input count:', products.length)
|
||||
const templates = getRecommendMarketingChannels()
|
||||
if (products.length == 0 || templates.length == 0) {
|
||||
console.log('[home-channel] fallback to mock channel data')
|
||||
return templates
|
||||
}
|
||||
const uniqueProducts = dedupeProducts(products)
|
||||
if (uniqueProducts.length == 0) {
|
||||
console.log('[home-channel] fallback to mock channel data')
|
||||
return templates
|
||||
}
|
||||
const selectedIds: Array<string> = []
|
||||
const discountCandidates = sortProductsByScoreDesc(filterProductsByMode(uniqueProducts, 'discount'), 'discount')
|
||||
const qualityCandidates = sortProductsByScoreDesc(filterProductsByMode(uniqueProducts, 'quality'), 'quality')
|
||||
const cheapCandidates = mergeUniqueProductLists(
|
||||
sortProductsByPriceAsc(filterProductsByMode(uniqueProducts, 'cheap-9')),
|
||||
sortProductsByPriceAsc(filterProductsByMode(uniqueProducts, 'cheap-19')),
|
||||
sortProductsByPriceAsc(uniqueProducts)
|
||||
)
|
||||
const liveCandidates = mergeUniqueProductLists(
|
||||
sortProductsByScoreDesc(filterProductsByMode(uniqueProducts, 'live'), 'hot'),
|
||||
sortProductsByScoreDesc(discountCandidates, 'discount'),
|
||||
sortProductsByScoreDesc(uniqueProducts, 'hot')
|
||||
)
|
||||
const hotFallback = sortProductsByScoreDesc(uniqueProducts, 'hot')
|
||||
const cheapFallback = sortProductsByPriceAsc(uniqueProducts)
|
||||
|
||||
const subsidyProducts = selectChannelProducts(discountCandidates, hotFallback, hotFallback, selectedIds, 2)
|
||||
const qualityProducts = selectChannelProducts(qualityCandidates, hotFallback, hotFallback, selectedIds, 2)
|
||||
const cheapProducts = selectChannelProducts(cheapCandidates, cheapFallback, hotFallback, selectedIds, 2)
|
||||
const liveProducts = selectChannelProducts(liveCandidates, discountCandidates, hotFallback, selectedIds, 2)
|
||||
|
||||
logChannelProducts('百亿补贴', subsidyProducts)
|
||||
logChannelProducts('品质生活', qualityProducts)
|
||||
logChannelProducts('9.9包邮', cheapProducts)
|
||||
logChannelProducts('直播低价', liveProducts)
|
||||
|
||||
const mappedChannels: Array<MarketingChannel> = []
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
const template = templates[i]
|
||||
if (template.id == 'subsidy') {
|
||||
mappedChannels.push(buildChannelFromTemplate(template, subsidyProducts, '补贴价'))
|
||||
continue
|
||||
}
|
||||
if (template.id == 'quality-life') {
|
||||
mappedChannels.push(buildChannelFromTemplate(template, qualityProducts, '实惠'))
|
||||
continue
|
||||
}
|
||||
if (template.id == 'cheap-mail') {
|
||||
const cheapMappedProducts: Array<ChannelProduct> = []
|
||||
for (let j = 0; j < cheapProducts.length; j++) {
|
||||
const cheapProduct = cheapProducts[j]
|
||||
const label = getRealSalePrice(cheapProduct) <= 9.9 ? '9.9包邮' : '特价'
|
||||
cheapMappedProducts.push(toChannelProduct(cheapProduct, label))
|
||||
}
|
||||
mappedChannels.push({
|
||||
id: template.id,
|
||||
title: template.title,
|
||||
subtitle: template.subtitle,
|
||||
badge: template.badge,
|
||||
themeColor: template.themeColor,
|
||||
bgColor: template.bgColor,
|
||||
routeType: template.routeType,
|
||||
layoutType: template.layoutType,
|
||||
products: cheapMappedProducts,
|
||||
moreProducts: cheapMappedProducts
|
||||
} as MarketingChannel)
|
||||
continue
|
||||
}
|
||||
if (template.id == 'live-low-price') {
|
||||
mappedChannels.push(buildChannelFromTemplate(template, liveProducts, '直播价'))
|
||||
continue
|
||||
}
|
||||
mappedChannels.push(template)
|
||||
}
|
||||
return mappedChannels
|
||||
}
|
||||
|
||||
function buildSimpleCategoryChannels(categoryId: string, products: Array<Product> = []): SimpleCategoryChannel[] {
|
||||
const dedupedProducts = dedupeProducts(products)
|
||||
if (dedupedProducts.length == 0) {
|
||||
return [] as Array<SimpleCategoryChannel>
|
||||
}
|
||||
const hotProductsForCategory = sortProductsByScoreDesc(dedupedProducts, 'hot')
|
||||
const qualityProductsForCategory = sortProductsByScoreDesc(dedupedProducts, 'quality')
|
||||
const firstChannelCovers: Array<string> = []
|
||||
const secondChannelCovers: Array<string> = []
|
||||
for (let i = 0; i < hotProductsForCategory.length && firstChannelCovers.length < 2; i++) {
|
||||
firstChannelCovers.push(getRealProductImage(hotProductsForCategory[i]))
|
||||
}
|
||||
for (let i = 0; i < qualityProductsForCategory.length && secondChannelCovers.length < 2; i++) {
|
||||
secondChannelCovers.push(getRealProductImage(qualityProductsForCategory[i]))
|
||||
}
|
||||
while (firstChannelCovers.length < 2) {
|
||||
firstChannelCovers.push('/static/images/default.png')
|
||||
}
|
||||
while (secondChannelCovers.length < 2) {
|
||||
secondChannelCovers.push('/static/images/default.png')
|
||||
}
|
||||
return [
|
||||
{
|
||||
id: categoryId + '-rank',
|
||||
title: '热销榜',
|
||||
subtitle: '真实商品热度精选',
|
||||
routeType: 'rank',
|
||||
icon: '热',
|
||||
coverImages: firstChannelCovers,
|
||||
categoryId
|
||||
} as SimpleCategoryChannel,
|
||||
{
|
||||
id: categoryId + '-quality',
|
||||
title: '品质优选',
|
||||
subtitle: '真实好物口碑推荐',
|
||||
routeType: 'quality',
|
||||
icon: '精',
|
||||
coverImages: secondChannelCovers,
|
||||
categoryId
|
||||
} as SimpleCategoryChannel
|
||||
]
|
||||
}
|
||||
|
||||
async function loadCategoryChannelCards(categoryId: string): Promise<void> {
|
||||
try {
|
||||
const channelResult = await supabaseService.getMedicalMallProductsByCategory(categoryId, 1, categoryChannelLoadLimit)
|
||||
categorySimpleChannels.value = buildSimpleCategoryChannels(categoryId, channelResult.data)
|
||||
} catch (error) {
|
||||
console.error('[home-channel] 加载分类频道卡片失败', categoryId, error)
|
||||
categorySimpleChannels.value = [] as Array<SimpleCategoryChannel>
|
||||
}
|
||||
}
|
||||
|
||||
function buildVisibleRecommendChannels(): MarketingChannel[] {
|
||||
const source = getRecommendMarketingChannels()
|
||||
const visible: MarketingChannel[] = []
|
||||
@@ -937,16 +1239,16 @@ function buildVisibleRecommendChannels(): MarketingChannel[] {
|
||||
visible.push(channel)
|
||||
}
|
||||
return visible
|
||||
}
|
||||
}
|
||||
|
||||
function applyChannelDisplay(categoryId: string): void {
|
||||
if (categoryId === 'recommend') {
|
||||
marketingChannels.value = buildVisibleRecommendChannels()
|
||||
categorySimpleChannels.value = []
|
||||
marketingChannels.value = [] as Array<MarketingChannel>
|
||||
categorySimpleChannels.value = [] as Array<SimpleCategoryChannel>
|
||||
return
|
||||
}
|
||||
marketingChannels.value = []
|
||||
categorySimpleChannels.value = buildSimpleCategoryChannels(categoryId)
|
||||
marketingChannels.value = [] as Array<MarketingChannel>
|
||||
categorySimpleChannels.value = [] as Array<SimpleCategoryChannel>
|
||||
}
|
||||
|
||||
function buildChannelDetailUrl(channelId: string, routeType: string, categoryId: string): string {
|
||||
@@ -1440,11 +1742,18 @@ async function loadHotProducts(page: number, limit: number): Promise<void> {
|
||||
}
|
||||
}
|
||||
setHotProducts(products)
|
||||
if (currentFeedCategoryId.value === 'recommend' && page <= 1) {
|
||||
marketingChannels.value = buildRealRecommendMarketingChannels(products)
|
||||
}
|
||||
hasMore.value = result.hasmore
|
||||
currentPage.value = page
|
||||
} catch (error) {
|
||||
console.error('加载热销商品失败:', error)
|
||||
hotProducts.value = []
|
||||
if (currentFeedCategoryId.value === 'recommend') {
|
||||
console.log('[home-channel] fallback to mock channel data')
|
||||
marketingChannels.value = buildVisibleRecommendChannels()
|
||||
}
|
||||
hasMore.value = false
|
||||
}
|
||||
}
|
||||
@@ -1476,14 +1785,18 @@ async function loadCategoryGoods(categoryId: string): Promise<void> {
|
||||
await syncCategoryLayout(categoryId)
|
||||
if (categoryId === 'recommend') {
|
||||
try {
|
||||
const result = await supabaseService.getMedicalMallSmartRecommendations(1, defaultLoadLimit)
|
||||
const result = await supabaseService.getMedicalMallSmartRecommendations(1, recommendChannelLoadLimit)
|
||||
console.log('[home-channel] 推荐商品接口返回数量:', result.data.length)
|
||||
failedProductImageIds.value = []
|
||||
setHotProducts(result.data)
|
||||
marketingChannels.value = buildRealRecommendMarketingChannels(result.data)
|
||||
hasMore.value = result.hasmore
|
||||
currentPage.value = 1
|
||||
} catch (error) {
|
||||
console.error('加载热销商品失败:', error)
|
||||
hotProducts.value = []
|
||||
console.log('[home-channel] fallback to mock channel data')
|
||||
marketingChannels.value = buildVisibleRecommendChannels()
|
||||
hasMore.value = false
|
||||
}
|
||||
} else {
|
||||
@@ -1492,10 +1805,12 @@ async function loadCategoryGoods(categoryId: string): Promise<void> {
|
||||
const result = await supabaseService.getMedicalMallProductsByCategory(categoryId, 1, defaultLoadLimit)
|
||||
failedProductImageIds.value = []
|
||||
setHotProducts(result.data)
|
||||
await loadCategoryChannelCards(categoryId)
|
||||
hasMore.value = result.hasmore
|
||||
} catch (e) {
|
||||
console.error('分类商品加载失败', e)
|
||||
hotProducts.value = []
|
||||
categorySimpleChannels.value = [] as Array<SimpleCategoryChannel>
|
||||
hasMore.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -1520,12 +1835,16 @@ async function refreshHomeCategory(item: CategoryItem): Promise<void> {
|
||||
secondaryCategoryDisplay.value = buildSecondaryCategoryDisplay(item.id)
|
||||
applyChannelDisplay(item.id)
|
||||
try {
|
||||
const result = await supabaseService.getMedicalMallSmartRecommendations(1, defaultLoadLimit)
|
||||
const result = await supabaseService.getMedicalMallSmartRecommendations(1, recommendChannelLoadLimit)
|
||||
console.log('[home-channel] 推荐商品接口返回数量:', result.data.length)
|
||||
setHotProducts(result.data)
|
||||
marketingChannels.value = buildRealRecommendMarketingChannels(result.data)
|
||||
hasMore.value = result.hasmore
|
||||
} catch (error) {
|
||||
console.error('加载推荐商品失败:', error)
|
||||
hotProducts.value = []
|
||||
console.log('[home-channel] fallback to mock channel data')
|
||||
marketingChannels.value = buildVisibleRecommendChannels()
|
||||
hasMore.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -1545,10 +1864,12 @@ async function refreshHomeCategory(item: CategoryItem): Promise<void> {
|
||||
try {
|
||||
const result = await supabaseService.getMedicalMallProductsByCategory(item.id, 1, defaultLoadLimit)
|
||||
setHotProducts(result.data)
|
||||
await loadCategoryChannelCards(item.id)
|
||||
hasMore.value = result.hasmore
|
||||
} catch (error) {
|
||||
console.error('分类商品加载失败', error)
|
||||
hotProducts.value = []
|
||||
categorySimpleChannels.value = [] as Array<SimpleCategoryChannel>
|
||||
hasMore.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -1857,7 +2178,8 @@ const switchSort = (sortId: string) => {
|
||||
}
|
||||
hasMore.value = true // 重置加载更多状态
|
||||
// 重新加载热销商品,排序由 Supabase 服务处理
|
||||
loadHotProducts(1, defaultLoadLimit)
|
||||
const nextLimit = currentFeedCategoryId.value === 'recommend' ? recommendChannelLoadLimit : defaultLoadLimit
|
||||
loadHotProducts(1, nextLimit)
|
||||
}
|
||||
|
||||
// 切换筛选器
|
||||
@@ -1909,12 +2231,13 @@ const loadMore = async () => {
|
||||
showLoadMore.value = true
|
||||
loading.value = true
|
||||
try {
|
||||
const pageLimit = currentFeedCategoryId.value === 'recommend' ? recommendChannelLoadLimit : defaultLoadLimit
|
||||
const nextPage = currentPage.value + 1
|
||||
const currentCount = hotProducts.value.length
|
||||
console.log('开始加载更多,当前数量:', currentCount, '页码:', nextPage, '分类:', currentFeedCategoryId.value)
|
||||
|
||||
if (currentFeedCategoryId.value === 'recommend') {
|
||||
const result = await fetchSortedProductsPage(nextPage, defaultLoadLimit)
|
||||
const result = await fetchSortedProductsPage(nextPage, pageLimit)
|
||||
const newProducts = result.data
|
||||
|
||||
if (newProducts.length == 0) {
|
||||
@@ -2025,7 +2348,7 @@ const onScan = (): void => {
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('扫码失败:', err)
|
||||
console.error('扫码失败:', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user