diff --git a/pages/index/index.js b/pages/index/index.js
index 04c5ea9..15b2d23 100644
--- a/pages/index/index.js
+++ b/pages/index/index.js
@@ -25,7 +25,6 @@ Page({
searchSectionVisible: true,
lastScrollTop: 0,
isScrollLocked: false,
- isSearchBarFullyHidden: false,
// 回到顶部按钮
showBackToTop: false,
@@ -43,10 +42,15 @@ Page({
leftColumnGoods: [],
rightColumnGoods: [],
selectedCategory: '全部',
+ categories: ['全部', '粉壳', '红壳', '绿壳', '白壳'],
loadingMore: false,
hasMoreData: true,
page: 1,
pageSize: 8,
+
+ // 防抖定时器
+ searchDebounceTimer: null,
+ scrollDebounceTimer: null,
isRefreshing: false,
isLoading: true,
@@ -219,9 +223,12 @@ Page({
this.setData({
sidebarBtnTop: defaultTop,
- sidebarBtnHidden: savedBtnHidden || false
+ sidebarBtnHidden: false,
+ isSearchBarFullyHidden: false,
+ lastScrollTop: 0
});
this.checkAndRestoreLoginStatus()
+ this.loadCategories()
this.loadGoods()
// 计算搜索区域高度
@@ -279,6 +286,9 @@ Page({
},
onShow: function () {
+ console.log('===== onShow 执行 =====');
+ console.log('onShow - 进入时的isSearchBarFullyHidden:', this.data.isSearchBarFullyHidden);
+
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().setData({
selected: 0
@@ -289,10 +299,16 @@ Page({
app.globalData.showTabBar = true;
const savedBtnHidden = wx.getStorageSync('sidebarBtnHidden');
+ console.log('onShow - savedBtnHidden:', savedBtnHidden);
+
this.setData({
- sidebarBtnHidden: savedBtnHidden || false
+ sidebarBtnHidden: savedBtnHidden || false,
+ isSearchBarFullyHidden: false,
+ lastScrollTop: 0
});
+ console.log('onShow - 设置后的isSearchBarFullyHidden:', this.data.isSearchBarFullyHidden);
+
this.checkAndRestoreLoginStatus()
},
@@ -423,6 +439,7 @@ Page({
return {
...product,
+ category: product.category || '',
fullRegion: product.region || '',
region: product.region ? this.extractProvince(product.region) : '',
grossWeight: product.grossWeight || product.weight || '',
@@ -484,9 +501,16 @@ Page({
}
const filteredGoods = this.applyFilters(updatedGoods, false)
+ console.log('===== 筛选结果 =====')
+ console.log('当前选中的分类:', this.data.selectedCategory)
console.log('filteredGoods 数量:', filteredGoods.length)
- console.log('filteredGoods[0]:', filteredGoods[0])
- console.log('filteredGoods[1]:', filteredGoods[1])
+ console.log('filteredGoods[0]:', filteredGoods[0] ? JSON.stringify(filteredGoods[0], null, 2) : 'N/A')
+ 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)
console.log('leftColumnGoods 数量:', leftColumnGoods.length)
@@ -513,6 +537,7 @@ Page({
return {
...product,
+ category: product.category || '',
fullRegion: product.region || '',
region: product.region ? this.extractProvince(product.region) : '',
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) {
if (isLoadMore && !this.data.hasMoreData) {
@@ -640,6 +683,14 @@ Page({
.then(res => {
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) {
const totalGoods = res.total || 0;
const totalPages = res.totalPages || Math.ceil(totalGoods / this.data.pageSize);
@@ -715,25 +766,41 @@ Page({
// 瀑布流布局 - 淘宝风格左右交替
distributeToColumns: function(goods) {
if (!goods || goods.length === 0) {
+ console.log('distributeToColumns: 商品列表为空')
return { leftColumnGoods: [], rightColumnGoods: [] }
}
+ console.log('distributeToColumns 开始分发,总商品数:', goods.length)
+
const leftColumn = []
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) {
const currentRow = Math.floor(i / 2)
const isEvenRow = currentRow % 2 === 0
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) {
- 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 }
},
@@ -806,13 +873,26 @@ Page({
return { leftColumnGoods: leftColumn, rightColumnGoods: rightColumn }
},
- // 搜索输入(实时搜索)
+ // 搜索输入(带防抖)
onSearchInput: function(e) {
+ const keyword = e.detail.value
+ this.setData({
+ searchKeyword: keyword
+ })
+
+ // 清除之前的定时器
+ if (this.data.searchDebounceTimer) {
+ clearTimeout(this.data.searchDebounceTimer)
+ }
+
+ // 设置新的定时器,300ms防抖
+ const timer = setTimeout(() => {
+ this.searchGoods()
+ }, 300)
+
this.setData({
- searchKeyword: e.detail.value
+ searchDebounceTimer: timer
})
- // 实时应用筛选条件
- this.searchGoods()
},
// 搜索商品
@@ -889,19 +969,24 @@ Page({
}
const category = e.currentTarget.dataset.category
- this.setData({
- selectedCategory: category
- })
+ if (category === this.data.selectedCategory) {
+ return // 如果选择的分类和当前相同,不重复加载
+ }
- const filteredGoods = this.applyFilters(this.data.goods, false)
- const groupedGoods = this.groupGoodsForStaggeredLayout(filteredGoods)
- const { leftColumnGoods, rightColumnGoods } = this.distributeToColumns(filteredGoods)
this.setData({
- filteredGoods: filteredGoods,
- groupedGoods: groupedGoods,
- leftColumnGoods: leftColumnGoods,
- rightColumnGoods: rightColumnGoods
+ selectedCategory: category,
+ page: 1,
+ hasMoreData: true,
+ goods: [],
+ filteredGoods: [],
+ leftColumnGoods: [],
+ rightColumnGoods: [],
+ loadingMore: false,
+ isLoading: true
})
+
+ // 重新从服务器加载数据
+ this.loadGoods(false)
},
// 查看商品详情
@@ -999,51 +1084,60 @@ Page({
});
},
- // 滚动事件处理 - 简化并修复iOS兼容性问题
+ // 滚动事件处理 - 优化性能
onScroll: function(e) {
const { scrollTop } = e.detail;
- // 使用更平滑的阈值判断
- const threshold = 50; // 降低阈值,让隐藏更早触发
+ // 清除之前的防抖定时器
+ if (this.data.scrollDebounceTimer) {
+ clearTimeout(this.data.scrollDebounceTimer)
+ }
- // 检查滚动方向
- const scrollingDown = scrollTop > this.data.lastScrollTop;
- const scrollingUp = scrollTop < this.data.lastScrollTop;
+ // 设置防抖,32ms约等于30fps,限制高速滑动时的处理频率
+ const timer = setTimeout(() => {
+ 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({
- lastScrollTop: scrollTop
- });
+ this.setData({
+ scrollDebounceTimer: timer
+ })
+ },
+
+ // 实际的滚动处理逻辑
+ handleScroll: function(scrollTop) {
+ const threshold = 50;
+ const backToTopThreshold = 300;
+
+ let needUpdate = false;
+ const updates = {
+ lastScrollTop: scrollTop
+ };
+
+ // 搜索框始终固定显示,不做隐藏处理
+
+ // 侧边栏按钮显示逻辑
+ if (scrollTop <= threshold && this.data.sidebarBtnHidden) {
+ updates.sidebarBtnHidden = false;
+ needUpdate = true;
+ wx.setStorageSync('sidebarBtnHidden', false);
}
// 回到顶部按钮显示逻辑
- if (scrollTop > 300 && !this.data.showBackToTop) {
- this.setData({ showBackToTop: true });
- } else if (scrollTop <= 300 && this.data.showBackToTop) {
- this.setData({ showBackToTop: false });
+ const shouldShowBackToTop = scrollTop > backToTopThreshold;
+ if (shouldShowBackToTop !== this.data.showBackToTop) {
+ updates.showBackToTop = shouldShowBackToTop;
+ needUpdate = true;
}
- const { scrollHeight, clientHeight } = e.detail;
- const distanceToBottom = scrollHeight - scrollTop - clientHeight;
+ if (needUpdate) {
+ this.setData(updates);
+ }
+ // TabBar显示
const app = getApp();
- if (!app || !app.globalData) {
- return;
+ if (app && app.globalData) {
+ app.globalData.showTabBar = true;
}
-
- app.globalData.showTabBar = true;
},
// 更新商品的收藏状态
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index 62683c6..b7219fd 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -1,8 +1,6 @@
-
-
+
+
专业的鸡蛋交易平台
@@ -13,7 +11,7 @@
{{selectedRegion || '全国'}}
- ▼
+
🔍
@@ -25,7 +23,6 @@
bindinput="onSearchInput"
/>
-
@@ -52,39 +49,13 @@
- 全部
-
-
- 粉壳
-
-
- 红壳
-
-
- 绿壳
-
-
- 白壳
+ {{item}}
@@ -163,7 +134,7 @@
-
+
+
+
+
@@ -244,6 +218,9 @@
+
+
+
diff --git a/pages/index/index.wxss b/pages/index/index.wxss
index 9731679..aeea7fa 100644
--- a/pages/index/index.wxss
+++ b/pages/index/index.wxss
@@ -37,12 +37,8 @@ page {
right: 0;
z-index: 1000;
background: linear-gradient(180deg, #f8f8f8 0%, #f0f0f0 50%, #e8e8e8 100%);
- transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
- transform: translateY(0);
- will-change: transform;
- -webkit-transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
- padding: 10rpx 0; /* 减少内边距 */
- min-height: 120rpx; /* 降低最小高度 */
+ padding: 10rpx 0;
+ min-height: 120rpx;
}
/* 确保所有主要区域背景一致 */
@@ -60,19 +56,13 @@ page {
flex-direction: column;
overflow: hidden;
position: relative;
- padding-top: 0; /* 移除顶部内边距,让瀑布流自然显示 */
+ padding-top: 0;
margin: 0;
border-radius: 0;
box-shadow: none;
background: transparent;
}
-/* 隐藏时的状态 */
-.top-section-container.top-hidden {
- transform: translateY(-100%);
- opacity: 0;
-}
-
/* 标题样式调整 */
.top-section-container .title {
padding: 10rpx 0;
@@ -80,25 +70,12 @@ page {
font-weight: bold;
text-align: center;
color: #333;
- transition: all 0.3s ease;
margin: 0;
}
-.top-section-container.top-hidden .title {
- padding: 0;
- font-size: 0;
- opacity: 0;
-}
-
/* 搜索区域样式调整 */
.top-section-container .search-section {
padding: 0 30rpx 15rpx;
- transition: all 0.3s ease;
-}
-
-.top-section-container.top-hidden .search-section {
- padding: 0 30rpx;
- opacity: 0;
}
/* 搜索框样式 */
@@ -109,19 +86,13 @@ page {
border-radius: 50rpx;
padding: 5rpx 15rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
min-height: 60rpx;
}
-.top-section-container.top-hidden .search-bar {
- transform: scale(0.9);
- opacity: 0;
-}
-
/* 修复商品列表区域 */
.goods-list {
flex: 1;
- padding-top: 240rpx; /* 根据新的分类区域位置调整,确保不被覆盖 */
+ padding-top: 280rpx;
height: 100%;
min-height: 100vh;
box-sizing: border-box;
@@ -130,20 +101,14 @@ page {
background: transparent;
}
-/* 当搜索框隐藏时调整商品列表位置 */
-.top-section-container.top-hidden ~ .goods-section .goods-list {
- padding-top: 80rpx; /* 搜索框隐藏时减少顶部间距 */
-}
-
/* 品种筛选区域调整 */
.category-section {
position: fixed;
- top: 160rpx; /* 进一步增大top值,确保完全不被搜索框覆盖 */
+ top: 160rpx;
left: 0;
right: 0;
z-index: 999;
background: linear-gradient(180deg, #f8f8f8 0%, #f0f0f0 50%, #e8e8e8 100%);
- transition: top 0.3s ease;
padding: 10rpx 0;
height: 70rpx;
box-sizing: border-box;
@@ -152,11 +117,6 @@ page {
margin: 0;
}
-/* 搜索框隐藏时,分类区域上移 */
-.top-section-container.top-hidden ~ .category-section {
- top: 0;
-}
-
/* iOS专用修复 */
@media screen and (-webkit-min-device-pixel-ratio:0) {
.top-section-container {
@@ -164,11 +124,6 @@ page {
transform: translateZ(0);
}
- .top-section-container.top-hidden {
- -webkit-transform: translate3d(0, -100%, 0);
- transform: translate3d(0, -100%, 0);
- }
-
/* 防止iOS弹性滚动导致的视觉问题 */
.goods-list {
-webkit-overflow-scrolling: touch;
@@ -258,24 +213,23 @@ page {
gap: 5rpx;
font-size: 24rpx;
font-weight: 500;
- color: white;
+ color: #333;
padding: 10rpx 15rpx;
- background: linear-gradient(135deg, #1677ff 0%, #4096ff 100%);
- border-radius: 40rpx;
- box-shadow: 0 2rpx 8rpx rgba(22, 119, 255, 0.3);
+ background: transparent;
+ border: none;
transition: all 0.3s ease;
margin-right: 10rpx;
}
.region-selector:hover {
transform: translateY(-2rpx);
- box-shadow: 0 4rpx 12rpx rgba(22, 119, 255, 0.4);
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.region-arrow {
font-size: 22rpx;
font-weight: bold;
- color: white;
+ color: #333;
}
.search-button {
@@ -620,16 +574,16 @@ wx-button:not([size=mini]) {
font-weight: bold;
}
-/* 商品区域样式 - 调整为占据70%空间 */
+/* 商品区域样式 */
.goods-section {
- background-color: white;
- padding: 20rpx;
- border-radius: 10rpx;
- margin: 0 20rpx 20rpx 20rpx;
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
- flex: 7;
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+ border-radius: 0;
+ box-shadow: none;
+ flex: 1;
overflow-y: auto;
- width: calc(100% - 40rpx);
+ width: 100%;
box-sizing: border-box;
}
@@ -1470,30 +1424,39 @@ wx-button:not([size=mini]) {
overflow: hidden;
background: #fff;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
- margin-bottom: 16rpx; /* 确保有下边距 */
- z-index: 1; /* 设置z-index确保在最上层 */
+ margin-bottom: 16rpx;
+ z-index: 1;
+ /* 修复真机遮挡问题:确保广告不被fixed元素遮挡 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
}
/* 完整卡片广告 */
.ad-full-card {
width: 100%;
- height: 350rpx; /* 稍微降低高度,避免被遮挡 */
+ height: 350rpx;
+ /* 修复遮挡:增加层级 */
+ position: relative;
+ z-index: 1001;
}
.ad-image {
width: 100%;
- height: 350rpx; /* 相应调整 */
+ height: 350rpx;
}
/* 半高图片广告 */
.ad-half-image {
width: 100%;
- height: 180rpx; /* 稍微降低高度 */
+ height: 180rpx;
+ /* 修复遮挡:增加层级 */
+ position: relative;
+ z-index: 1001;
}
.ad-image-half {
width: 100%;
- height: 180rpx; /* 相应调整 */
+ height: 180rpx;
}
/* 广告标签 */
diff --git a/pages/profile/index.js b/pages/profile/index.js
index 1eea16b..75d944d 100644
--- a/pages/profile/index.js
+++ b/pages/profile/index.js
@@ -520,7 +520,7 @@ Page({
const that = this;
wx.showModal({
title: '登录成功',
- content: '🥚 想快速找到离你最近的新鲜鸡蛋供应商、支持自提的门店,或享受精准配送服务?允许获取位置后,我们会为你优先展示周边优质货源、计算最快配送时效,省去手动输入地址的麻烦~隐私安全有保障,位置信息仅用于优化你的购物体验,放心点击【允许】吧!',
+ content: '🥚 允许获取位置,为你优先展示附近新鲜鸡蛋供应商、自提门店及精准配送时效,无需手动填地址,位置信息仅用于优化购物体验,隐私有保障,放心开启~',
showCancel: true,
cancelText: '取消',
confirmText: '允许',
diff --git a/pages/settlement/index.wxml b/pages/settlement/index.wxml
index ad06f76..cffebca 100644
--- a/pages/settlement/index.wxml
+++ b/pages/settlement/index.wxml
@@ -276,7 +276,7 @@
你可以撤回备案
-
+
@@ -364,7 +364,7 @@
-
+
{{selectedCooperationDetail.title}}
diff --git a/server-example/server-mysql.js b/server-example/server-mysql.js
index 26d4589..ee23be9 100644
--- a/server-example/server-mysql.js
+++ b/server-example/server-mysql.js
@@ -1779,6 +1779,45 @@ app.post('/api/user/update', async (req, res) => {
}
});
+// 获取商品分类列表 - 返回不重复的分类
+app.get('/api/product/categories', async (req, res) => {
+ try {
+ const { openid } = req.query;
+
+ console.log('获取商品分类列表, openid:', openid || '未提供');
+
+ // 使用 Sequelize 的 distinct 查询获取不重复的分类
+ const products = await Product.findAll({
+ attributes: [
+ [Sequelize.col('category'), 'category']
+ ],
+ where: {
+ category: {
+ [Sequelize.Op.ne]: null,
+ [Sequelize.Op.ne]: ''
+ }
+ },
+ group: ['category']
+ });
+
+ // 提取分类数组
+ const categories = products.map(p => p.category).filter(c => c);
+
+ console.log('获取到的分类列表:', categories);
+
+ res.json({
+ success: true,
+ categories: ['全部', ...categories] // 添加"全部"选项
+ });
+ } catch (error) {
+ console.error('获取分类列表失败:', error);
+ res.status(500).json({
+ success: false,
+ message: '获取分类列表失败: ' + error.message
+ });
+ }
+});
+
// 获取商品列表 - 优化版本确保状态筛选正确应用
app.post('/api/product/list', async (req, res) => {
try {
diff --git a/utils/api.js b/utils/api.js
index c2c7779..6037937 100644
--- a/utils/api.js
+++ b/utils/api.js
@@ -3909,6 +3909,30 @@ module.exports = {
resolve({});
});
});
+ },
+
+ // 获取商品分类列表 - 从product表的category字段去重获取
+ getProductCategories: function () {
+ return new Promise((resolve, reject) => {
+ const openid = wx.getStorageSync('openid') || '';
+
+ request('/api/product/categories', 'GET', {
+ openid: openid
+ }).then(res => {
+ console.log('获取商品分类列表成功:', res);
+ if (res && res.success && res.categories) {
+ resolve(res.categories);
+ } else {
+ // 如果接口不存在,返回默认分类
+ console.warn('获取分类接口未实现,返回默认分类');
+ resolve(['全部', '粉壳', '红壳', '绿壳', '白壳']);
+ }
+ }).catch(err => {
+ console.error('获取商品分类列表失败:', err);
+ // 失败时返回默认分类
+ resolve(['全部', '粉壳', '红壳', '绿壳', '白壳']);
+ });
+ });
}
};
\ No newline at end of file