|
|
@ -25,7 +25,6 @@ Page({ |
|
|
searchSectionVisible: true, |
|
|
searchSectionVisible: true, |
|
|
lastScrollTop: 0, |
|
|
lastScrollTop: 0, |
|
|
isScrollLocked: false, |
|
|
isScrollLocked: false, |
|
|
isSearchBarFullyHidden: false, |
|
|
|
|
|
|
|
|
|
|
|
// 回到顶部按钮
|
|
|
// 回到顶部按钮
|
|
|
showBackToTop: false, |
|
|
showBackToTop: false, |
|
|
@ -43,10 +42,15 @@ Page({ |
|
|
leftColumnGoods: [], |
|
|
leftColumnGoods: [], |
|
|
rightColumnGoods: [], |
|
|
rightColumnGoods: [], |
|
|
selectedCategory: '全部', |
|
|
selectedCategory: '全部', |
|
|
|
|
|
categories: ['全部', '粉壳', '红壳', '绿壳', '白壳'], |
|
|
loadingMore: false, |
|
|
loadingMore: false, |
|
|
hasMoreData: true, |
|
|
hasMoreData: true, |
|
|
page: 1, |
|
|
page: 1, |
|
|
pageSize: 8, |
|
|
pageSize: 8, |
|
|
|
|
|
|
|
|
|
|
|
// 防抖定时器
|
|
|
|
|
|
searchDebounceTimer: null, |
|
|
|
|
|
scrollDebounceTimer: null, |
|
|
isRefreshing: false, |
|
|
isRefreshing: false, |
|
|
isLoading: true, |
|
|
isLoading: true, |
|
|
|
|
|
|
|
|
@ -219,9 +223,12 @@ Page({ |
|
|
|
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
sidebarBtnTop: defaultTop, |
|
|
sidebarBtnTop: defaultTop, |
|
|
sidebarBtnHidden: savedBtnHidden || false |
|
|
sidebarBtnHidden: false, |
|
|
|
|
|
isSearchBarFullyHidden: false, |
|
|
|
|
|
lastScrollTop: 0 |
|
|
}); |
|
|
}); |
|
|
this.checkAndRestoreLoginStatus() |
|
|
this.checkAndRestoreLoginStatus() |
|
|
|
|
|
this.loadCategories() |
|
|
this.loadGoods() |
|
|
this.loadGoods() |
|
|
|
|
|
|
|
|
// 计算搜索区域高度
|
|
|
// 计算搜索区域高度
|
|
|
@ -279,6 +286,9 @@ Page({ |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
onShow: function () { |
|
|
onShow: function () { |
|
|
|
|
|
console.log('===== onShow 执行 ====='); |
|
|
|
|
|
console.log('onShow - 进入时的isSearchBarFullyHidden:', this.data.isSearchBarFullyHidden); |
|
|
|
|
|
|
|
|
if (typeof this.getTabBar === 'function' && this.getTabBar()) { |
|
|
if (typeof this.getTabBar === 'function' && this.getTabBar()) { |
|
|
this.getTabBar().setData({ |
|
|
this.getTabBar().setData({ |
|
|
selected: 0 |
|
|
selected: 0 |
|
|
@ -289,10 +299,16 @@ Page({ |
|
|
app.globalData.showTabBar = true; |
|
|
app.globalData.showTabBar = true; |
|
|
|
|
|
|
|
|
const savedBtnHidden = wx.getStorageSync('sidebarBtnHidden'); |
|
|
const savedBtnHidden = wx.getStorageSync('sidebarBtnHidden'); |
|
|
|
|
|
console.log('onShow - savedBtnHidden:', savedBtnHidden); |
|
|
|
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
sidebarBtnHidden: savedBtnHidden || false |
|
|
sidebarBtnHidden: savedBtnHidden || false, |
|
|
|
|
|
isSearchBarFullyHidden: false, |
|
|
|
|
|
lastScrollTop: 0 |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
console.log('onShow - 设置后的isSearchBarFullyHidden:', this.data.isSearchBarFullyHidden); |
|
|
|
|
|
|
|
|
this.checkAndRestoreLoginStatus() |
|
|
this.checkAndRestoreLoginStatus() |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
@ -423,6 +439,7 @@ Page({ |
|
|
|
|
|
|
|
|
return { |
|
|
return { |
|
|
...product, |
|
|
...product, |
|
|
|
|
|
category: product.category || '', |
|
|
fullRegion: product.region || '', |
|
|
fullRegion: product.region || '', |
|
|
region: product.region ? this.extractProvince(product.region) : '', |
|
|
region: product.region ? this.extractProvince(product.region) : '', |
|
|
grossWeight: product.grossWeight || product.weight || '', |
|
|
grossWeight: product.grossWeight || product.weight || '', |
|
|
@ -484,9 +501,16 @@ Page({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const filteredGoods = this.applyFilters(updatedGoods, false) |
|
|
const filteredGoods = this.applyFilters(updatedGoods, false) |
|
|
|
|
|
console.log('===== 筛选结果 =====') |
|
|
|
|
|
console.log('当前选中的分类:', this.data.selectedCategory) |
|
|
console.log('filteredGoods 数量:', filteredGoods.length) |
|
|
console.log('filteredGoods 数量:', filteredGoods.length) |
|
|
console.log('filteredGoods[0]:', filteredGoods[0]) |
|
|
console.log('filteredGoods[0]:', filteredGoods[0] ? JSON.stringify(filteredGoods[0], null, 2) : 'N/A') |
|
|
console.log('filteredGoods[1]:', filteredGoods[1]) |
|
|
if (filteredGoods.length > 0) { |
|
|
|
|
|
console.log('filteredGoods[0].category:', filteredGoods[0] ? filteredGoods[0].category : 'N/A') |
|
|
|
|
|
} |
|
|
|
|
|
if (filteredGoods.length > 1) { |
|
|
|
|
|
console.log('filteredGoods[1].category:', filteredGoods[1] ? filteredGoods[1].category : 'N/A') |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods) |
|
|
const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods) |
|
|
console.log('leftColumnGoods 数量:', leftColumnGoods.length) |
|
|
console.log('leftColumnGoods 数量:', leftColumnGoods.length) |
|
|
@ -513,6 +537,7 @@ Page({ |
|
|
|
|
|
|
|
|
return { |
|
|
return { |
|
|
...product, |
|
|
...product, |
|
|
|
|
|
category: product.category || '', |
|
|
fullRegion: product.region || '', |
|
|
fullRegion: product.region || '', |
|
|
region: product.region ? this.extractProvince(product.region) : '', |
|
|
region: product.region ? this.extractProvince(product.region) : '', |
|
|
grossWeight: product.grossWeight || product.weight || '', |
|
|
grossWeight: product.grossWeight || product.weight || '', |
|
|
@ -614,6 +639,24 @@ Page({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 加载商品分类列表
|
|
|
|
|
|
loadCategories: function() { |
|
|
|
|
|
console.log('===== 开始加载分类 ====='); |
|
|
|
|
|
API.getProductCategories().then(categories => { |
|
|
|
|
|
console.log('加载分类成功, categories:', JSON.stringify(categories)); |
|
|
|
|
|
if (categories && categories.length > 0) { |
|
|
|
|
|
this.setData({ |
|
|
|
|
|
categories: categories |
|
|
|
|
|
}); |
|
|
|
|
|
console.log('分类列表已设置到data, categories:', this.data.categories); |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('分类列表为空,使用默认分类'); |
|
|
|
|
|
} |
|
|
|
|
|
}).catch(err => { |
|
|
|
|
|
console.error('加载分类失败:', err); |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
// 加载商品数据 - 淘宝风格优化
|
|
|
// 加载商品数据 - 淘宝风格优化
|
|
|
loadGoods: function(isLoadMore = false) { |
|
|
loadGoods: function(isLoadMore = false) { |
|
|
if (isLoadMore && !this.data.hasMoreData) { |
|
|
if (isLoadMore && !this.data.hasMoreData) { |
|
|
@ -640,6 +683,14 @@ Page({ |
|
|
.then(res => { |
|
|
.then(res => { |
|
|
wx.hideLoading(); |
|
|
wx.hideLoading(); |
|
|
|
|
|
|
|
|
|
|
|
console.log('===== API 返回的完整数据 ====='); |
|
|
|
|
|
console.log('res:', res); |
|
|
|
|
|
console.log('res.products:', res.products); |
|
|
|
|
|
if (res.products && res.products.length > 0) { |
|
|
|
|
|
console.log('第一个商品的完整字段:', JSON.stringify(res.products[0], null, 2)); |
|
|
|
|
|
console.log('第一个商品的所有键:', Object.keys(res.products[0])); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (res.success && res.products) { |
|
|
if (res.success && res.products) { |
|
|
const totalGoods = res.total || 0; |
|
|
const totalGoods = res.total || 0; |
|
|
const totalPages = res.totalPages || Math.ceil(totalGoods / this.data.pageSize); |
|
|
const totalPages = res.totalPages || Math.ceil(totalGoods / this.data.pageSize); |
|
|
@ -715,25 +766,41 @@ Page({ |
|
|
// 瀑布流布局 - 淘宝风格左右交替
|
|
|
// 瀑布流布局 - 淘宝风格左右交替
|
|
|
distributeToColumns: function(goods) { |
|
|
distributeToColumns: function(goods) { |
|
|
if (!goods || goods.length === 0) { |
|
|
if (!goods || goods.length === 0) { |
|
|
|
|
|
console.log('distributeToColumns: 商品列表为空') |
|
|
return { leftColumnGoods: [], rightColumnGoods: [] } |
|
|
return { leftColumnGoods: [], rightColumnGoods: [] } |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log('distributeToColumns 开始分发,总商品数:', goods.length) |
|
|
|
|
|
|
|
|
const leftColumn = [] |
|
|
const leftColumn = [] |
|
|
const rightColumn = [] |
|
|
const rightColumn = [] |
|
|
|
|
|
|
|
|
|
|
|
// 统计广告和普通商品
|
|
|
|
|
|
const adCount = goods.filter(item => item.isAd).length |
|
|
|
|
|
const productCount = goods.filter(item => !item.isAd).length |
|
|
|
|
|
console.log('广告数量:', adCount, '普通商品数量:', productCount) |
|
|
|
|
|
|
|
|
for (let i = 0; i < goods.length; i += 2) { |
|
|
for (let i = 0; i < goods.length; i += 2) { |
|
|
const currentRow = Math.floor(i / 2) |
|
|
const currentRow = Math.floor(i / 2) |
|
|
const isEvenRow = currentRow % 2 === 0 |
|
|
const isEvenRow = currentRow % 2 === 0 |
|
|
|
|
|
|
|
|
if (i < goods.length) { |
|
|
if (i < goods.length) { |
|
|
leftColumn.push({ ...goods[i], isLong: isEvenRow }) |
|
|
const item = { ...goods[i], isLong: isEvenRow } |
|
|
|
|
|
leftColumn.push(item) |
|
|
|
|
|
console.log(`左列添加[${i}]:`, item.isAd ? '广告' : item.name, 'isLong:', item.isLong) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (i + 1 < goods.length) { |
|
|
if (i + 1 < goods.length) { |
|
|
rightColumn.push({ ...goods[i + 1], isLong: !isEvenRow }) |
|
|
const item = { ...goods[i + 1], isLong: !isEvenRow } |
|
|
|
|
|
rightColumn.push(item) |
|
|
|
|
|
console.log(`右列添加[${i+1}]:`, item.isAd ? '广告' : item.name, 'isLong:', item.isLong) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log('分发结果 - 左列:', leftColumn.length, '右列:', rightColumn.length) |
|
|
|
|
|
console.log('左列商品:', leftColumn.filter(i => !i.isAd).length, '广告:', leftColumn.filter(i => i.isAd).length) |
|
|
|
|
|
console.log('右列商品:', rightColumn.filter(i => !i.isAd).length, '广告:', rightColumn.filter(i => i.isAd).length) |
|
|
|
|
|
|
|
|
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn } |
|
|
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn } |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
@ -806,13 +873,26 @@ Page({ |
|
|
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn } |
|
|
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn } |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 搜索输入(实时搜索)
|
|
|
// 搜索输入(带防抖)
|
|
|
onSearchInput: function(e) { |
|
|
onSearchInput: function(e) { |
|
|
|
|
|
const keyword = e.detail.value |
|
|
this.setData({ |
|
|
this.setData({ |
|
|
searchKeyword: e.detail.value |
|
|
searchKeyword: keyword |
|
|
}) |
|
|
}) |
|
|
// 实时应用筛选条件
|
|
|
|
|
|
|
|
|
// 清除之前的定时器
|
|
|
|
|
|
if (this.data.searchDebounceTimer) { |
|
|
|
|
|
clearTimeout(this.data.searchDebounceTimer) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 设置新的定时器,300ms防抖
|
|
|
|
|
|
const timer = setTimeout(() => { |
|
|
this.searchGoods() |
|
|
this.searchGoods() |
|
|
|
|
|
}, 300) |
|
|
|
|
|
|
|
|
|
|
|
this.setData({ |
|
|
|
|
|
searchDebounceTimer: timer |
|
|
|
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 搜索商品
|
|
|
// 搜索商品
|
|
|
@ -889,19 +969,24 @@ Page({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const category = e.currentTarget.dataset.category |
|
|
const category = e.currentTarget.dataset.category |
|
|
this.setData({ |
|
|
if (category === this.data.selectedCategory) { |
|
|
selectedCategory: category |
|
|
return // 如果选择的分类和当前相同,不重复加载
|
|
|
}) |
|
|
} |
|
|
|
|
|
|
|
|
const filteredGoods = this.applyFilters(this.data.goods, false) |
|
|
|
|
|
const groupedGoods = this.groupGoodsForStaggeredLayout(filteredGoods) |
|
|
|
|
|
const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods) |
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
filteredGoods: filteredGoods, |
|
|
selectedCategory: category, |
|
|
groupedGoods: groupedGoods, |
|
|
page: 1, |
|
|
leftColumnGoods: leftColumnGoods, |
|
|
hasMoreData: true, |
|
|
rightColumnGoods: rightColumnGoods |
|
|
goods: [], |
|
|
|
|
|
filteredGoods: [], |
|
|
|
|
|
leftColumnGoods: [], |
|
|
|
|
|
rightColumnGoods: [], |
|
|
|
|
|
loadingMore: false, |
|
|
|
|
|
isLoading: true |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 重新从服务器加载数据
|
|
|
|
|
|
this.loadGoods(false) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 查看商品详情
|
|
|
// 查看商品详情
|
|
|
@ -999,51 +1084,60 @@ Page({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 滚动事件处理 - 简化并修复iOS兼容性问题
|
|
|
// 滚动事件处理 - 优化性能
|
|
|
onScroll: function(e) { |
|
|
onScroll: function(e) { |
|
|
const { scrollTop } = e.detail; |
|
|
const { scrollTop } = e.detail; |
|
|
|
|
|
|
|
|
// 使用更平滑的阈值判断
|
|
|
// 清除之前的防抖定时器
|
|
|
const threshold = 50; // 降低阈值,让隐藏更早触发
|
|
|
if (this.data.scrollDebounceTimer) { |
|
|
|
|
|
clearTimeout(this.data.scrollDebounceTimer) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 检查滚动方向
|
|
|
// 设置防抖,32ms约等于30fps,限制高速滑动时的处理频率
|
|
|
const scrollingDown = scrollTop > this.data.lastScrollTop; |
|
|
const timer = setTimeout(() => { |
|
|
const scrollingUp = scrollTop < this.data.lastScrollTop; |
|
|
this.handleScroll(scrollTop) |
|
|
|
|
|
}, 32) |
|
|
|
|
|
|
|
|
// 只在滚动超过阈值且方向改变时才更新状态
|
|
|
|
|
|
if (scrollingDown && scrollTop > threshold && !this.data.isSearchBarFullyHidden) { |
|
|
|
|
|
this.setData({ |
|
|
|
|
|
isSearchBarFullyHidden: true, |
|
|
|
|
|
lastScrollTop: scrollTop |
|
|
|
|
|
}); |
|
|
|
|
|
} else if (scrollingUp && scrollTop <= threshold && this.data.isSearchBarFullyHidden) { |
|
|
|
|
|
this.setData({ |
|
|
|
|
|
isSearchBarFullyHidden: false, |
|
|
|
|
|
lastScrollTop: scrollTop |
|
|
|
|
|
}); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 其他情况只更新滚动位置
|
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
|
|
|
scrollDebounceTimer: timer |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 实际的滚动处理逻辑
|
|
|
|
|
|
handleScroll: function(scrollTop) { |
|
|
|
|
|
const threshold = 50; |
|
|
|
|
|
const backToTopThreshold = 300; |
|
|
|
|
|
|
|
|
|
|
|
let needUpdate = false; |
|
|
|
|
|
const updates = { |
|
|
lastScrollTop: scrollTop |
|
|
lastScrollTop: scrollTop |
|
|
}); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 搜索框始终固定显示,不做隐藏处理
|
|
|
|
|
|
|
|
|
|
|
|
// 侧边栏按钮显示逻辑
|
|
|
|
|
|
if (scrollTop <= threshold && this.data.sidebarBtnHidden) { |
|
|
|
|
|
updates.sidebarBtnHidden = false; |
|
|
|
|
|
needUpdate = true; |
|
|
|
|
|
wx.setStorageSync('sidebarBtnHidden', false); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 回到顶部按钮显示逻辑
|
|
|
// 回到顶部按钮显示逻辑
|
|
|
if (scrollTop > 300 && !this.data.showBackToTop) { |
|
|
const shouldShowBackToTop = scrollTop > backToTopThreshold; |
|
|
this.setData({ showBackToTop: true }); |
|
|
if (shouldShowBackToTop !== this.data.showBackToTop) { |
|
|
} else if (scrollTop <= 300 && this.data.showBackToTop) { |
|
|
updates.showBackToTop = shouldShowBackToTop; |
|
|
this.setData({ showBackToTop: false }); |
|
|
needUpdate = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const { scrollHeight, clientHeight } = e.detail; |
|
|
if (needUpdate) { |
|
|
const distanceToBottom = scrollHeight - scrollTop - clientHeight; |
|
|
this.setData(updates); |
|
|
|
|
|
|
|
|
const app = getApp(); |
|
|
|
|
|
if (!app || !app.globalData) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TabBar显示
|
|
|
|
|
|
const app = getApp(); |
|
|
|
|
|
if (app && app.globalData) { |
|
|
app.globalData.showTabBar = true; |
|
|
app.globalData.showTabBar = true; |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 更新商品的收藏状态
|
|
|
// 更新商品的收藏状态
|
|
|
|