From 4e6974cab9ee8c488b8460e75778b9426db7fc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=A3=9E=E6=B4=8B?= <15778543+xufeiyang6017@user.noreply.gitee.com> Date: Wed, 7 Jan 2026 17:35:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=AF=B9=E6=AF=94=E4=BB=B7?= =?UTF-8?q?=E6=A0=BC=E5=BC=B9=E7=AA=97=E7=9A=84=E5=9B=BE=E7=89=87=E5=92=8C?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/goods-detail/goods-detail.js | 249 +++++++++++++++++++++++++++ pages/goods-detail/goods-detail.wxml | 123 ++++++++++++- pages/goods-detail/goods-detail.wxss | 218 +++++++++++++++++++++++ utils/api.js | 2 +- 4 files changed, 589 insertions(+), 3 deletions(-) diff --git a/pages/goods-detail/goods-detail.js b/pages/goods-detail/goods-detail.js index d4d18d3..797e7de 100644 --- a/pages/goods-detail/goods-detail.js +++ b/pages/goods-detail/goods-detail.js @@ -462,6 +462,13 @@ Page({ offsetX: 0, // X轴偏移量 offsetY: 0, // Y轴偏移量 initialTouch: null, // 初始触摸点 + // 对比价格相关状态 + showCompareModal: false, // 是否显示对比价格弹窗 + activeTab: 'home', // 当前激活的选项卡,'home'表示首页数据,'favorite'表示收藏数据 + homeGoods: [], // 首页商品数据 + favoriteGoods: [], // 收藏商品数据 + loadingHome: false, // 首页数据加载状态 + loadingFavorite: false, // 收藏数据加载状态 }, onLoad: function (options) { @@ -2028,6 +2035,248 @@ Page({ }); }, + // 对比价格功能:处理按钮点击事件 + onCompareClick: function () { + console.log('用户点击了对比价格按钮,准备显示弹窗'); + // 立即显示弹窗,不等待数据加载 + this.setData({ + showCompareModal: true, + activeTab: 'home' // 默认显示首页数据选项卡 + }); + + // 打印弹窗状态,用于调试 + console.log('弹窗状态设置为:', this.data.showCompareModal); + + // 加载首页数据 + this.loadHomeGoods(); + + // 加载收藏数据 + this.loadFavoriteGoods(); + }, + + // 关闭对比价格弹窗 + closeCompareModal: function () { + this.setData({ + showCompareModal: false + }); + }, + + // 阻止事件冒泡 + stopPropagation: function () { + // 空函数,用于阻止事件冒泡 + }, + + // 切换选项卡 + switchTab: function (e) { + const tab = e.currentTarget.dataset.tab; + this.setData({ + activeTab: tab + }); + + // 如果切换到收藏选项卡且收藏数据为空,则加载收藏数据 + if (tab === 'favorite' && this.data.favoriteGoods.length === 0) { + this.loadFavoriteGoods(); + } + }, + + // 加载首页商品数据 + loadHomeGoods: function () { + this.setData({ loadingHome: true }); + + // 调用API获取首页商品列表 + API.getProducts() + .then(res => { + console.log('获取首页商品数据成功:', res); + // API.getProducts()直接返回商品数组,而不是包含data字段的对象 + if (Array.isArray(res)) { + // 为每个商品添加mediaItems字段 + const processedGoods = res.map(goods => { + return { + ...goods, + mediaItems: processMediaUrls(goods.imageUrls) + }; + }); + + this.setData({ + homeGoods: processedGoods, + loadingHome: false + }); + } else { + this.setData({ loadingHome: false }); + wx.showToast({ + title: '获取首页数据失败', + icon: 'none', + duration: 2000 + }); + } + }) + .catch(err => { + console.error('获取首页商品数据失败:', err); + this.setData({ loadingHome: false }); + wx.showToast({ + title: '获取首页数据失败', + icon: 'none', + duration: 2000 + }); + }); + }, + + // 加载已收藏商品数据 + loadFavoriteGoods: function () { + this.setData({ loadingFavorite: true }); + + // 获取用户手机号 + let userPhone = ''; + try { + // 打印所有可能的存储位置内容,用于调试 + console.log('调试信息 - 获取收藏数据前的存储状态:'); + console.log('userId:', wx.getStorageSync('userId')); + console.log('users:', wx.getStorageSync('users')); + console.log('userInfo:', wx.getStorageSync('userInfo')); + console.log('phoneNumber:', wx.getStorageSync('phoneNumber')); + + // 先尝试从最新的存储位置获取 + const userInfo = wx.getStorageSync('userInfo'); + if (userInfo && userInfo.phoneNumber) { + userPhone = userInfo.phoneNumber; + console.log('从userInfo获取到手机号:', userPhone); + } else { + // 然后尝试从users对象获取 + const users = wx.getStorageSync('users') || {}; + const userId = wx.getStorageSync('userId'); + if (userId && users[userId] && users[userId].phoneNumber) { + userPhone = users[userId].phoneNumber; + console.log('从users[' + userId + ']获取到手机号:', userPhone); + } else { + // 最后尝试从单独的phoneNumber字段获取 + userPhone = wx.getStorageSync('phoneNumber'); + console.log('从phoneNumber字段获取到手机号:', userPhone); + } + } + } catch (e) { + console.error('获取用户手机号失败:', e); + } + + // 验证手机号是否有效 + if (!userPhone) { + this.setData({ loadingFavorite: false }); + console.log('用户未登录或未获取手机号,无法加载收藏数据'); + wx.showToast({ + title: '请先登录获取手机号', + icon: 'none', + duration: 2000 + }); + return; + } + + // 确保手机号格式正确 + if (typeof userPhone !== 'string' || userPhone.length < 11) { + this.setData({ loadingFavorite: false }); + console.error('手机号格式不正确:', userPhone); + return; + } + + console.log('准备调用API获取收藏数据,手机号:', userPhone); + + // 调用API获取收藏商品列表 + API.getFavorites(userPhone) + .then(res => { + console.log('获取收藏商品数据成功:', res); + + // 处理API返回的数据结构 + let favoritesList = []; + if (res) { + if (Array.isArray(res.data)) { + favoritesList = res.data; + } else if (res.data && Array.isArray(res.data.favorites)) { + favoritesList = res.data.favorites; + } else if (res.data && Array.isArray(res.data.data)) { + favoritesList = res.data.data; + } else if (Array.isArray(res)) { + // 直接返回数组的情况 + favoritesList = res; + } + + console.log('解析后的收藏商品列表:', favoritesList); + } + + // 检查收藏列表是否只包含productId + const hasOnlyProductId = favoritesList.length > 0 && + favoritesList.every(item => + (typeof item === 'string' || typeof item === 'number') || + (typeof item === 'object' && item.productId && !item.name) + ); + + if (hasOnlyProductId) { + console.log('收藏列表只包含productId,需要获取商品详情'); + // 转换为productId数组 + const productIds = favoritesList.map(item => + typeof item === 'object' ? item.productId : item + ); + + console.log('提取的productId列表:', productIds); + + // 并行获取所有商品详情 + const productPromises = productIds.map(productId => + API.getProductDetail({ productId: productId }) + .then(detailRes => { + console.log('获取商品详情成功:', productId, detailRes); + return detailRes && detailRes.data ? detailRes.data : null; + }) + .catch(err => { + console.error('获取商品详情失败:', productId, err); + return null; + }) + ); + + // 等待所有商品详情获取完成 + Promise.all(productPromises) + .then(products => { + // 过滤掉获取失败的商品,并为每个商品添加mediaItems字段 + const validProducts = products + .filter(product => product !== null) + .map(product => ({ + ...product, + mediaItems: processMediaUrls(product.imageUrls) + })); + console.log('所有商品详情获取完成,有效商品数量:', validProducts.length); + + this.setData({ + favoriteGoods: validProducts, + loadingFavorite: false + }); + }) + .catch(err => { + console.error('获取商品详情列表失败:', err); + this.setData({ + favoriteGoods: [], + loadingFavorite: false + }); + }); + } else { + // 收藏列表已经包含完整商品信息,为每个商品添加mediaItems字段 + const processedFavorites = favoritesList.map(product => ({ + ...product, + mediaItems: processMediaUrls(product.imageUrls) + })); + + this.setData({ + favoriteGoods: processedFavorites, + loadingFavorite: false + }); + } + }) + .catch(err => { + console.error('获取收藏商品数据失败:', err); + this.setData({ loadingFavorite: false }); + wx.showToast({ + title: '获取收藏数据失败: ' + (err && err.message ? err.message : '未知错误'), + icon: 'none', + duration: 3000 + }); + }); + }, + // 返回上一页 goBack() { wx.navigateBack(); diff --git a/pages/goods-detail/goods-detail.wxml b/pages/goods-detail/goods-detail.wxml index aad362c..cb723a9 100644 --- a/pages/goods-detail/goods-detail.wxml +++ b/pages/goods-detail/goods-detail.wxml @@ -71,6 +71,14 @@ {{goodsDetail.price}} (可议价) + + 对比价格 + > + - + + @@ -176,7 +185,117 @@ - + + + + + + 对比价格 + × + + + + + + 首页数据 + + + 已收藏数据 + + + + + + + + + + + + + + + {{item.name}} + {{item.specification || item.spec || item.specs || '暂无规格'}} + {{item.quantity || '暂无件数'}}件 + 价格: {{item.price}} + {{item.region || '暂无地区'}} + + + + + 暂无首页数据 + + + + + + + + + + + + {{item.name}} + {{item.specification || item.spec || item.specs || '暂无规格'}} + {{item.quantity || '暂无件数'}}件 + 价格: {{item.price}} + {{item.region || '暂无地区'}} + + + + + 暂无收藏商品 + + + + diff --git a/pages/goods-detail/goods-detail.wxss b/pages/goods-detail/goods-detail.wxss index 1c4248e..ea4c809 100644 --- a/pages/goods-detail/goods-detail.wxss +++ b/pages/goods-detail/goods-detail.wxss @@ -748,4 +748,222 @@ video.slider-media .wx-video-volume-icon { color: #595959; line-height: 1.5; font-weight: 500; +} + +/* 对比价格弹窗样式 */ +.compare-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: flex-end; + z-index: 9999; + animation: fadeIn 0.3s ease-out; +} + +.compare-modal-container { + width: 100%; + background-color: #fff; + border-top-left-radius: 32rpx; + border-top-right-radius: 32rpx; + padding-bottom: 20rpx; + max-height: 70vh; + animation: slideUp 0.3s ease-out; + display: flex; + flex-direction: column; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes slideUp { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } +} + +.compare-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 24rpx 32rpx; + border-bottom: 1rpx solid #f0f0f0; + position: relative; +} + +.compare-modal-title { + font-size: 36rpx; + font-weight: bold; + color: #222; + text-align: center; + flex: 1; +} + +.compare-modal-close { + font-size: 48rpx; + color: #999; + width: 60rpx; + height: 60rpx; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: all 0.3s ease; +} + +.compare-modal-close:active { + background-color: #f0f0f0; + transform: scale(0.9); +} + +.compare-tabs { + display: flex; + background-color: #f8f9fa; + padding: 12rpx; + border-radius: 0; +} + +.compare-tab { + flex: 1; + text-align: center; + padding: 16rpx 0; + font-size: 32rpx; + color: #666; + border-radius: 12rpx; + transition: all 0.3s ease; + font-weight: 500; +} + +.compare-tab.active { + background-color: #fff; + color: #4a90e2; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); + font-weight: bold; +} + +.compare-goods-list { + flex: 1; + overflow-y: auto; + padding: 16rpx; +} + +.compare-goods-item { + display: flex; + background-color: #fff; + border-radius: 16rpx; + padding: 16rpx; + margin-bottom: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08); + transition: all 0.3s ease; + border: 1rpx solid #f0f0f0; +} + +.compare-goods-item:active { + transform: translateY(2rpx); + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.12); +} + +.compare-goods-image { + width: 120rpx; + height: 120rpx; + border-radius: 12rpx; + margin-right: 16rpx; + object-fit: cover; + background: linear-gradient(135deg, #f0f4ff 0%, #d9e4ff 100%); +} + +/* 视频和图片容器样式 */ +.product-image-wrapper { + width: 120rpx; + height: 120rpx; + border-radius: 12rpx; + margin-right: 16rpx; + overflow: hidden; + position: relative; + background: linear-gradient(135deg, #f0f4ff 0%, #d9e4ff 100%); +} + +/* 视频和图片样式 */ +.product-media { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + object-fit: cover; +} + +.compare-goods-info { + flex: 1; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.compare-goods-name { + font-size: 32rpx; + color: #222; + font-weight: 600; + line-height: 1.4; + margin-bottom: 8rpx; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.compare-goods-spec { + font-size: 28rpx; + color: #666; + margin-bottom: 4rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.compare-goods-quantity { + font-size: 28rpx; + color: #666; + margin-bottom: 4rpx; +} + +.compare-goods-price { + font-size: 36rpx; + color: #ff4d4f; + font-weight: bold; + margin-bottom: 4rpx; +} + +.compare-goods-region { + font-size: 26rpx; + color: #999; +} + +.compare-empty { + text-align: center; + padding: 80rpx 0; + color: #999; + font-size: 32rpx; +} + +/* 修复样式冲突 */ +.goods-detail-page { + position: relative; + z-index: 1; } \ No newline at end of file diff --git a/utils/api.js b/utils/api.js index c2d1134..5c9a4df 100644 --- a/utils/api.js +++ b/utils/api.js @@ -754,7 +754,7 @@ module.exports = { request('/api/product/list', 'POST', { openid: openid, status: 'all', // 请求所有状态的商品(除了hidden) - viewMode: 'seller', // 添加viewMode参数,限制只能查看当前用户的商品 + viewMode: 'buyer', // 使用buyer模式获取所有商品,而非仅当前用户的商品 page: 1, pageSize: 100 // 获取足够多的商品 }).then(res => {