diff --git a/pages/compare_price/index.js b/pages/compare_price/index.js index 060abbe..20c889f 100644 --- a/pages/compare_price/index.js +++ b/pages/compare_price/index.js @@ -65,11 +65,14 @@ Page({ showTips: true, goods: [], loading: false, + loadingMore: false, selectedOption: '', selectedCategory: '', selectedSpec: '', currentGoods: null, - currentSwiperIndex: 0 + currentSwiperIndex: 0, + currentPage: 1, + hasMore: true }, onLoad: function (options) { @@ -146,282 +149,15 @@ Page({ currentGoods: goodsData }); - // 调用 API 获取符合条件的商品 - API.getProducts(1, 20, 'all', '') - .then(res => { - console.log('获取商品列表成功:', res); - console.log('选择的种类:', selectedCategory); - console.log('选择的规格:', specWeight); - - let filteredGoods = []; - if (res && res.products) { - console.log('原始商品数量:', res.products.length); - // 获取当前商品的唯一标识符 - const currentGoodsId = goodsData.productId || goodsData.id || goodsData._id; - console.log('当前商品ID:', currentGoodsId); - - // 过滤商品 - filteredGoods = res.products.filter(item => { - // 1. 排除当前商品 - const itemId = item.productId || item.id || item._id; - if (currentGoodsId && itemId && currentGoodsId === itemId) { - console.log('排除当前商品:', itemId); - return false; - } - - // 2. 检查商品状态和价格 - if (item.status !== 'published' || item.price === null || item.price === undefined) { - return false; - } - - // 3. 过滤种类 - if (selectedCategory && selectedCategory !== '全部' && item.category !== selectedCategory) { - return false; - } - - // 4. 过滤规格 - if (specWeight) { - // 检查多个可能存储重量信息的字段 - const fieldsToCheck = [ - item.specification, - item.grossWeight, - item.weightQuantityData, - item.spec // 检查spec字段 - ]; - - let hasMatchingSpec = false; - for (const field of fieldsToCheck) { - if (!field) continue; - - if (typeof field === 'string') { - // 处理字符串格式的规格数据 - console.log('检查字符串规格:', field, '是否包含', specWeight); - // 处理逗号分隔的规格字符串 - const specs = field.split(/[,,、]/).map(s => s.trim()); - if (specs.some(spec => spec.includes(specWeight))) { - hasMatchingSpec = true; - break; - } - } else if (Array.isArray(field)) { - // 处理数组格式的规格数据 - console.log('检查数组规格:', field); - if (field.some(spec => { - if (typeof spec === 'string') { - console.log('检查数组元素(字符串):', spec, '是否包含', specWeight); - return spec.includes(specWeight); - } else if (typeof spec === 'object') { - // 检查对象格式的规格数据 - const specStr = spec.weightSpec || spec.display || spec.spec || ''; - console.log('检查数组元素(对象):', specStr, '是否包含', specWeight); - return specStr.includes(specWeight); - } - return false; - })) { - hasMatchingSpec = true; - break; - } - } else if (typeof field === 'object') { - // 处理对象格式的规格数据 - console.log('检查对象规格:', field); - const specStr = field.weightSpec || field.display || field.spec || ''; - console.log('检查对象规格值:', specStr, '是否包含', specWeight); - if (specStr.includes(specWeight)) { - hasMatchingSpec = true; - break; - } - } - } - - // 如果没有找到匹配的规格,尝试进行更宽松的匹配 - if (!hasMatchingSpec) { - console.log('尝试更宽松的匹配...'); - // 提取规格中的数字部分进行匹配 - const weightNum = specWeight.replace(/[^0-9-]/g, ''); - console.log('提取的重量数字:', weightNum); - - for (const field of fieldsToCheck) { - if (!field) continue; - - if (typeof field === 'string') { - if (field.includes(weightNum)) { - hasMatchingSpec = true; - break; - } - } else if (Array.isArray(field)) { - if (field.some(spec => { - const specStr = typeof spec === 'string' ? spec : (spec.weightSpec || spec.display || ''); - return specStr.includes(weightNum); - })) { - hasMatchingSpec = true; - break; - } - } - } - } - - if (!hasMatchingSpec) { - return false; - } - } - - return true; - }); - console.log('过滤后的商品数量:', filteredGoods.length); - console.log('过滤后的商品:', filteredGoods); - } - - // 处理商品数据 - const processedGoods = filteredGoods.map(item => { - // 首先清理 imageUrls 字段(如果存在) - if (item.imageUrls && Array.isArray(item.imageUrls)) { - item.imageUrls = item.imageUrls.map(url => { - return url.trim().replace(/[`]/g, ''); + // 初始化商品数据 + this.setData({ + goods: [], + currentPage: 1, + hasMore: true }); - // 使用processMediaUrls函数处理媒体数据 - item.mediaItems = processMediaUrls(item.imageUrls); - - // 确保图片优先显示:将图片类型的媒体项移到数组前面 - if (item.mediaItems && item.mediaItems.length > 1) { - const imageItems = item.mediaItems.filter(media => media.type === 'image'); - const videoItems = item.mediaItems.filter(media => media.type === 'video'); - item.mediaItems = [...imageItems, ...videoItems]; - } - } - - // 清理 mediaItems 中的 URL - if (item.mediaItems && Array.isArray(item.mediaItems)) { - item.mediaItems = item.mediaItems.map(media => { - if (media.url) { - // 去除 URL 中的反引号和空格 - media.url = media.url.trim().replace(/[`]/g, ''); - // 确保媒体类型正确 - if (!media.type) { - media.type = isVideoUrl(media.url) ? 'video' : 'image'; - } - } - return media; - }); - } - - // 处理商品价格,使用选中规格的价格 - if (specWeight) { - if (item.weightQuantityData && Array.isArray(item.weightQuantityData)) { - // 尝试从weightQuantityData中找到对应规格的价格 - const matchingSpec = item.weightQuantityData.find(spec => { - if (spec.weightSpec) { - return spec.weightSpec.trim() === specWeight; - } - return false; - }); - if (matchingSpec && matchingSpec.price) { - // 确保价格是一个单一的值,而不是多个价格的组合 - item.price = matchingSpec.price; - } - } - } - - // 清理价格字段,确保只显示单一价格 - if (item.price) { - // 如果价格是字符串且包含逗号,只取第一个价格 - if (typeof item.price === 'string' && item.price.includes(',')) { - item.price = item.price.split(',')[0].trim(); - } - // 如果价格是数组,只取第一个价格 - if (Array.isArray(item.price)) { - item.price = item.price[0]; - } - } - - // 处理规格信息,将多个净重信息分割成数组 - item.processedSpecs = []; - if (item.specification) { - item.processedSpecs = processSpecifications(item.specification); - } else if (item.weightSpec) { - item.processedSpecs = processSpecifications(item.weightSpec); - } else if (item.grossWeight) { - item.processedSpecs = processSpecifications(item.grossWeight); - } else if (selectedSpec) { - item.processedSpecs = processSpecifications(selectedSpec); - } - - // 处理库存显示逻辑 - const quantity = item.quantity || item.minOrder || item.stock || item.inventory || item.availableStock || item.totalAvailable; - const totalStock = quantity; - - let displayStock; - if (totalStock >= 10000) { - // 库存>=10000时显示"库存充足" - displayStock = '充足'; - } else if (totalStock === 0) { - // 库存=0时显示"暂无" - displayStock = '暂无'; - } else { - // 其他情况显示具体数字 - displayStock = totalStock; - } - - // 更新商品的库存显示 - item.totalStock = displayStock; - item.originalTotalStock = totalStock; - - // 添加当前对比的规格信息 - if (specWeight) { - item.currentSpec = specWeight; - } - - // 处理地区信息,只显示省份 - if (item.region) { - // 提取省份信息 - const provinceRegex = /^([^省]+省|[^自治区]+自治区|[^直辖市]+直辖市|[^特别行政区]+特别行政区)/; - const match = item.region.match(provinceRegex); - if (match) { - item.region = match[1]; - } - } - - // 计算价格涨幅 - if (goodsData.price) { - const currentPrice = parseFloat(goodsData.price); - const itemPrice = parseFloat(item.price); - if (!isNaN(currentPrice) && !isNaN(itemPrice)) { - const priceDiff = itemPrice - currentPrice; - const pricePercent = ((priceDiff / currentPrice) * 100).toFixed(1); - item.priceDiff = priceDiff; - item.pricePercent = pricePercent; - } - } - - return item; - }); - - // 显示提示信息 - wx.showToast({ - title: `找到${processedGoods.length}个符合条件的商品`, - icon: 'success', - duration: 2000 - }); - - // 设置商品数据 - this.setData({ - goods: processedGoods, - loading: false, - selectedOption: selectedCategory || '对比价格', - showTips: false - }); - - console.log('对比价格数据加载完成:', processedGoods); - }) - .catch(err => { - console.error('获取商品列表失败:', err); - this.setData({ - loading: false - }); - wx.showToast({ - title: '获取商品失败,请稍后重试', - icon: 'none' - }); - }); + // 加载商品数据 + this.loadGoodsData(1, selectedCategory, specWeight, goodsData); } catch (error) { console.error('解析商品数据失败:', error); this.setData({ @@ -539,7 +275,7 @@ Page({ // 过滤出 category 匹配且 price 不为 null 的商品 const filteredGoods = res.products.filter(item => item.category === option && - item.status === 'published' && + (item.status === 'published' || item.status === 'sold_out') && item.price !== null && item.price !== undefined ); @@ -682,6 +418,317 @@ Page({ } }, + // 加载商品数据 + loadGoodsData: function (page, selectedCategory, specWeight, goodsData) { + if (this.data.loadingMore || (page !== 1 && !this.data.hasMore)) { + return; + } + + this.setData({ + loading: page === 1 ? true : false, + loadingMore: page > 1 ? true : false + }); + + API.getProducts(page, 20, 'all', '') + .then(res => { + console.log('获取商品列表成功:', res); + console.log('选择的种类:', selectedCategory); + console.log('选择的规格:', specWeight); + + let filteredGoods = []; + if (res && res.products) { + console.log('原始商品数量:', res.products.length); + // 获取当前商品的唯一标识符 + const currentGoodsId = goodsData.productId || goodsData.id || goodsData._id; + console.log('当前商品ID:', currentGoodsId); + + // 过滤商品 + filteredGoods = res.products.filter(item => { + // 1. 排除当前商品 + const itemId = item.productId || item.id || item._id; + if (currentGoodsId && itemId && currentGoodsId === itemId) { + console.log('排除当前商品:', itemId); + return false; + } + + // 2. 检查商品状态和价格 + if ((item.status !== 'published' && item.status !== 'sold_out') || item.price === null || item.price === undefined) { + return false; + } + + // 3. 过滤种类 + if (selectedCategory && selectedCategory !== '全部' && item.category !== selectedCategory) { + return false; + } + + // 4. 过滤规格 + if (specWeight) { + // 检查多个可能存储重量信息的字段 + const fieldsToCheck = [ + item.specification, + item.grossWeight, + item.weightQuantityData, + item.spec // 检查spec字段 + ]; + + let hasMatchingSpec = false; + for (const field of fieldsToCheck) { + if (!field) continue; + + if (typeof field === 'string') { + // 处理字符串格式的规格数据 + console.log('检查字符串规格:', field, '是否包含', specWeight); + // 处理逗号分隔的规格字符串 + const specs = field.split(/[,,、]/).map(s => s.trim()); + if (specs.some(spec => spec.includes(specWeight))) { + hasMatchingSpec = true; + break; + } + } else if (Array.isArray(field)) { + // 处理数组格式的规格数据 + console.log('检查数组规格:', field); + if (field.some(spec => { + if (typeof spec === 'string') { + console.log('检查数组元素(字符串):', spec, '是否包含', specWeight); + return spec.includes(specWeight); + } else if (typeof spec === 'object') { + // 检查对象格式的规格数据 + const specStr = spec.weightSpec || spec.display || spec.spec || ''; + console.log('检查数组元素(对象):', specStr, '是否包含', specWeight); + return specStr.includes(specWeight); + } + return false; + })) { + hasMatchingSpec = true; + break; + } + } else if (typeof field === 'object') { + // 处理对象格式的规格数据 + console.log('检查对象规格:', field); + const specStr = field.weightSpec || field.display || field.spec || ''; + console.log('检查对象规格值:', specStr, '是否包含', specWeight); + if (specStr.includes(specWeight)) { + hasMatchingSpec = true; + break; + } + } + } + + // 如果没有找到匹配的规格,尝试进行更宽松的匹配 + if (!hasMatchingSpec) { + console.log('尝试更宽松的匹配...'); + // 提取规格中的数字部分进行匹配 + const weightNum = specWeight.replace(/[^0-9-]/g, ''); + console.log('提取的重量数字:', weightNum); + + for (const field of fieldsToCheck) { + if (!field) continue; + + if (typeof field === 'string') { + if (field.includes(weightNum)) { + hasMatchingSpec = true; + break; + } + } else if (Array.isArray(field)) { + if (field.some(spec => { + const specStr = typeof spec === 'string' ? spec : (spec.weightSpec || spec.display || ''); + return specStr.includes(weightNum); + })) { + hasMatchingSpec = true; + break; + } + } + } + } + + if (!hasMatchingSpec) { + return false; + } + } + + return true; + }); + console.log('过滤后的商品数量:', filteredGoods.length); + console.log('过滤后的商品:', filteredGoods); + } + + // 处理商品数据 + const processedGoods = filteredGoods.map(item => { + // 首先清理 imageUrls 字段(如果存在) + if (item.imageUrls && Array.isArray(item.imageUrls)) { + item.imageUrls = item.imageUrls.map(url => { + return url.trim().replace(/[`]/g, ''); + }); + + // 使用processMediaUrls函数处理媒体数据 + item.mediaItems = processMediaUrls(item.imageUrls); + + // 确保图片优先显示:将图片类型的媒体项移到数组前面 + if (item.mediaItems && item.mediaItems.length > 1) { + const imageItems = item.mediaItems.filter(media => media.type === 'image'); + const videoItems = item.mediaItems.filter(media => media.type === 'video'); + item.mediaItems = [...imageItems, ...videoItems]; + } + } + + // 清理 mediaItems 中的 URL + if (item.mediaItems && Array.isArray(item.mediaItems)) { + item.mediaItems = item.mediaItems.map(media => { + if (media.url) { + // 去除 URL 中的反引号和空格 + media.url = media.url.trim().replace(/[`]/g, ''); + // 确保媒体类型正确 + if (!media.type) { + media.type = isVideoUrl(media.url) ? 'video' : 'image'; + } + } + return media; + }); + } + + // 处理商品价格,使用选中规格的价格 + if (specWeight) { + if (item.weightQuantityData && Array.isArray(item.weightQuantityData)) { + // 尝试从weightQuantityData中找到对应规格的价格 + const matchingSpec = item.weightQuantityData.find(spec => { + if (spec.weightSpec) { + return spec.weightSpec.trim() === specWeight; + } + return false; + }); + if (matchingSpec && matchingSpec.price) { + // 确保价格是一个单一的值,而不是多个价格的组合 + item.price = matchingSpec.price; + } + } + } + + // 清理价格字段,确保只显示单一价格 + if (item.price) { + // 如果价格是字符串且包含逗号,只取第一个价格 + if (typeof item.price === 'string' && item.price.includes(',')) { + item.price = item.price.split(',')[0].trim(); + } + // 如果价格是数组,只取第一个价格 + if (Array.isArray(item.price)) { + item.price = item.price[0]; + } + } + + // 处理规格信息,将多个净重信息分割成数组 + item.processedSpecs = []; + if (item.specification) { + item.processedSpecs = processSpecifications(item.specification); + } else if (item.weightSpec) { + item.processedSpecs = processSpecifications(item.weightSpec); + } else if (item.grossWeight) { + item.processedSpecs = processSpecifications(item.grossWeight); + } else if (selectedSpec) { + item.processedSpecs = processSpecifications(selectedSpec); + } + + // 处理库存显示逻辑 + const quantity = item.quantity || item.minOrder || item.stock || item.inventory || item.availableStock || item.totalAvailable; + const totalStock = quantity; + + let displayStock; + if (totalStock >= 10000) { + // 库存>=10000时显示"库存充足" + displayStock = '充足'; + } else if (totalStock === 0) { + // 库存=0时显示"暂无" + displayStock = '暂无'; + } else { + // 其他情况显示具体数字 + displayStock = totalStock; + } + + // 更新商品的库存显示 + item.totalStock = displayStock; + item.originalTotalStock = totalStock; + + // 处理地区信息,只显示省份 + if (item.region) { + // 提取省份信息 + const provinceRegex = /^([^省]+省|[^自治区]+自治区|[^直辖市]+直辖市|[^特别行政区]+特别行政区)/; + const match = item.region.match(provinceRegex); + if (match) { + item.region = match[1]; + } + } + + // 计算价格涨幅 + if (goodsData.price) { + const currentPrice = parseFloat(goodsData.price); + const itemPrice = parseFloat(item.price); + if (!isNaN(currentPrice) && !isNaN(itemPrice)) { + const priceDiff = itemPrice - currentPrice; + const pricePercent = ((priceDiff / currentPrice) * 100).toFixed(1); + item.priceDiff = priceDiff; + item.pricePercent = pricePercent; + } + } + + return item; + }); + + // 合并商品数据 + const newGoods = page === 1 ? processedGoods : [...this.data.goods, ...processedGoods]; + + // 检查是否还有更多数据 + const hasMore = res && res.products && res.products.length >= 20; + + // 设置商品数据 + this.setData({ + goods: newGoods, + loading: false, + loadingMore: false, + currentPage: page, + hasMore: hasMore, + selectedOption: selectedCategory || '对比价格', + showTips: false + }); + + console.log('对比价格数据加载完成:', newGoods); + + // 如果符合条件的数据少于5条,自动加载更多数据 + if (newGoods.length < 5 && hasMore) { + console.log('符合条件的数据少于5条,自动加载更多数据'); + this.loadGoodsData(page + 1, selectedCategory, specWeight, goodsData); + } else if (page === 1) { + // 显示提示信息 + wx.showToast({ + title: `找到${newGoods.length}个符合条件的商品`, + icon: 'success', + duration: 2000 + }); + } + }) + .catch(err => { + console.error('获取商品列表失败:', err); + this.setData({ + loading: false, + loadingMore: false + }); + wx.showToast({ + title: '获取商品失败,请稍后重试', + icon: 'none' + }); + }); + }, + + // 加载更多数据 + loadMore: function () { + if (this.data.loadingMore || !this.data.hasMore) { + return; + } + + const { currentPage, selectedCategory, selectedSpec, currentGoods } = this.data; + const specWeight = selectedSpec; + + this.loadGoodsData(currentPage + 1, selectedCategory, specWeight, currentGoods); + }, + // 返回上一页 navigateBack: function () { wx.navigateBack({ diff --git a/pages/compare_price/index.wxml b/pages/compare_price/index.wxml index ed9e77d..453f2ef 100644 --- a/pages/compare_price/index.wxml +++ b/pages/compare_price/index.wxml @@ -88,6 +88,13 @@ + + + + + @@ -115,7 +122,7 @@ - + 已经加载全部符合的商品 diff --git a/pages/compare_price/index.wxss b/pages/compare_price/index.wxss index f0cb551..3ce9042 100644 --- a/pages/compare_price/index.wxss +++ b/pages/compare_price/index.wxss @@ -470,6 +470,30 @@ color: #666666; } +/* 加载更多按钮 */ +.load-more { + margin-top: 20px; + margin-bottom: 10px; + text-align: center; +} + +.load-more-btn { + width: 80%; + height: 40px; + background-color: #FFFFFF; + border: 1px solid #D1D5DB; + border-radius: 20px; + font-size: 14px; + color: #374151; + display: flex; + align-items: center; + justify-content: center; +} + +.load-more-btn:active { + background-color: #F3F4F6; +} + /* 加载完成提示 */ .load-complete { margin-top: 15px; diff --git a/pages/goods-detail/goods-detail.wxml b/pages/goods-detail/goods-detail.wxml index 8395185..3e14f2a 100644 --- a/pages/goods-detail/goods-detail.wxml +++ b/pages/goods-detail/goods-detail.wxml @@ -100,7 +100,7 @@ 对比价格 >