// pages/compare_price/index.js const API = require('../../utils/api.js'); // 媒体类型判断函数 function isVideoUrl(url) { if (!url || typeof url !== 'string') { return false; } // 转换为小写,确保大小写不敏感 const lowerUrl = url.toLowerCase(); // 支持的视频格式 const videoExtensions = ['.mp4', '.mov', '.avi', '.wmv', '.flv', '.webm', '.m4v', '.3gp']; // 检查URL是否以视频扩展名结尾 for (const ext of videoExtensions) { if (lowerUrl.endsWith(ext)) { return true; } } return false; } // 预处理媒体URL,返回包含type字段的媒体对象数组 function processMediaUrls(urls) { if (!urls || !Array.isArray(urls)) { return []; } return urls.map(url => { return { url: url, type: isVideoUrl(url) ? 'video' : 'image' }; }); } // 处理规格信息,将多个净重信息分割成数组 function processSpecifications(spec) { if (!spec || typeof spec !== 'string') { return []; } // 分割规格字符串,支持多种分隔符 const specs = spec.split(/[,,、]/).map(s => s.trim()).filter(s => s); return specs; } // 格式化价格,最多显示一位小数 function formatPrice(price) { if (price === null || price === undefined) { return price; } // 转换为数字 const numPrice = parseFloat(price); if (isNaN(numPrice)) { return price; } // 格式化到一位小数 return numPrice.toFixed(1); } // 计算单位价格 function calculateUnitPrice(price, spec) { if (!price || !spec) { return null; } // 转换价格为数字 const numPrice = parseFloat(price); if (isNaN(numPrice)) { return null; } // 检查是否需要计算单位价格(价格低于10元) if (numPrice >= 10) { return null; } // 提取重量范围 const weightMatch = spec.match(/(\d+)-(\d+)/); if (!weightMatch) { return null; } const minWeight = parseFloat(weightMatch[1]); const maxWeight = parseFloat(weightMatch[2]); if (isNaN(minWeight) || isNaN(maxWeight)) { return null; } // 计算平均重量 const avgWeight = (minWeight + maxWeight) / 2; // 检查是否是毛重 const isGrossWeight = spec.includes('毛重'); // 计算单位价格 let unitPrice; if (isGrossWeight) { unitPrice = (avgWeight - 5) * numPrice; } else { unitPrice = avgWeight * numPrice; } return unitPrice.toFixed(1); } // 获取商品状态信息 function getStatusInfo(status) { switch (status) { case 'published': return { text: '在售', color: '#10B981' }; case 'sold_out': return { text: '售罄', color: '#666666' }; default: return { text: '未知', color: '#666666' }; } } Page({ data: { // 页面数据 showTips: true, goods: [], loading: false, loadingMore: false, selectedOption: '', selectedCategory: '', selectedSpec: '', currentGoods: null, currentSwiperIndex: 0, currentPage: 1, pageSize: 10, // 每页展示10条数据 hasMore: true, allGoods: [] // 存储所有符合条件的商品 }, onLoad: function (options) { // 页面加载 console.log('对比价格页面加载,接收参数:', options); // 检查是否有传递过来的商品数据 if (options.goodsData) { try { // 解析传递过来的商品数据 const goodsData = JSON.parse(decodeURIComponent(options.goodsData)); console.log('解析得到的商品数据:', goodsData); // 显示加载状态 this.setData({ loading: true }); // 提取选择的种类和规格 const selectedCategory = goodsData.category || ''; const selectedSpec = goodsData.selectedSpec || null; const specWeight = selectedSpec ? selectedSpec.weightSpec.trim() : ''; console.log('选择的种类:', selectedCategory); console.log('选择的规格:', selectedSpec); // 处理当前商品的价格,使用选中规格的价格 let currentPrice = goodsData.price; if (selectedSpec && selectedSpec.price) { // 如果selectedSpec包含价格信息,使用它 currentPrice = selectedSpec.price; } else if (goodsData.weightQuantityData && Array.isArray(goodsData.weightQuantityData)) { // 如果weightQuantityData存在,尝试从中找到对应规格的价格 const matchingSpec = goodsData.weightQuantityData.find(spec => { if (spec.weightSpec) { return spec.weightSpec.trim() === specWeight; } return false; }); if (matchingSpec && matchingSpec.price) { currentPrice = matchingSpec.price; } } // 更新currentGoods的价格 goodsData.price = currentPrice; // 清理价格字段,确保只显示单一价格 if (goodsData.price) { // 如果价格是字符串且包含逗号,只取第一个价格 if (typeof goodsData.price === 'string' && goodsData.price.includes(',')) { goodsData.price = goodsData.price.split(',')[0].trim(); } // 如果价格是数组,只取第一个价格 if (Array.isArray(goodsData.price)) { goodsData.price = goodsData.price[0]; } } // 处理当前商品的地区信息,只显示省份 if (goodsData.region) { // 提取省份信息 const provinceRegex = /^([^省]+省|[^自治区]+自治区|[^直辖市]+直辖市|[^特别行政区]+特别行政区)/; const match = goodsData.region.match(provinceRegex); if (match) { goodsData.region = match[1]; } } // 计算当前商品的单位价格 goodsData.unitPrice = calculateUnitPrice(goodsData.price, specWeight || goodsData.specification); // 保存选择的种类、规格和当前商品数据到页面数据 this.setData({ selectedCategory: selectedCategory, selectedSpec: specWeight, currentGoods: goodsData }); // 初始化商品数据 this.setData({ goods: [], currentPage: 1, hasMore: true }); // 加载商品数据 this.loadGoodsData(1, selectedCategory, specWeight, goodsData); } catch (error) { console.error('解析商品数据失败:', error); this.setData({ loading: false }); wx.showToast({ title: '数据解析失败,请重试', icon: 'none', duration: 2000 }); } } }, onShow: function () { // 页面显示 }, onHide: function () { // 页面隐藏 }, onUnload: function () { // 页面卸载 }, onPullDownRefresh: function () { // 下拉刷新 }, onReachBottom: function () { // 上拉触底 }, // 图片加载完成事件 onImageLoad: function (e) { // 图片加载完成后的处理逻辑 console.log('图片加载完成:', e); }, // 跳转到商品详情页面 navigateToGoodsDetail: function (e) { const item = e.currentTarget.dataset.item; if (!item) { console.error('商品信息为空'); return; } console.log('跳转到商品详情页面,商品信息:', item); // 传递完整的商品数据,避免API调用失败 const goodsData = encodeURIComponent(JSON.stringify(item)); // 跳转到商品详情页面,传递完整的商品数据 wx.navigateTo({ url: `/pages/goods-detail/goods-detail?goodsData=${goodsData}`, success: function () { console.log('成功跳转到商品详情页面'); }, fail: function (error) { console.error('跳转到商品详情页面失败:', error); wx.showToast({ title: '跳转失败,请稍后重试', icon: 'none' }); } }); }, // 重置选择,返回首页 resetSelection: function () { wx.switchTab({ url: '/pages/index/index', success: function() { console.log('成功返回首页'); }, fail: function(error) { console.error('返回首页失败:', error); // 如果switchTab失败,尝试使用navigateTo wx.navigateTo({ url: '/pages/index/index', success: function() { console.log('使用navigateTo成功返回首页'); }, fail: function(error) { console.error('使用navigateTo返回首页也失败:', error); } }); } }); }, // 关闭提示弹窗 closeTips: function () { this.setData({ showTips: false }); }, // 选择选项 selectOption: function (e) { const option = e.currentTarget.dataset.option; console.log('选择了:', option); // 显示加载状态 this.setData({ loading: true, selectedOption: option }); // 调用 API 获取符合条件的商品 API.getProducts(1, 20, 'all', '') .then(res => { console.log('获取商品列表成功:', res); // 过滤出 category 匹配且 price 不为 null 的商品 const filteredGoods = res.products.filter(item => item.category === option && (item.status === 'published' || item.status === 'sold_out') && item.price !== null && item.price !== undefined ); // 清理 mediaItems 中的 URL,去除反引号和空格 // 同时处理 imageUrls 字段,将其转换为 mediaItems 格式 // 处理库存显示逻辑 const cleanedGoods = 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 (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.price = formatPrice(item.price); } // 处理原始价格 if (item.originalPrice) { // 如果原始价格是字符串且包含逗号,只取第一个价格 if (typeof item.originalPrice === 'string' && item.originalPrice.includes(',')) { item.originalPrice = item.originalPrice.split(',')[0].trim(); } // 如果原始价格是数组,只取第一个价格 if (Array.isArray(item.originalPrice)) { item.originalPrice = item.originalPrice[0]; } // 格式化原始价格,最多显示一位小数 item.originalPrice = formatPrice(item.originalPrice); } // 处理规格信息,将多个净重信息分割成数组 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); } // 处理库存显示逻辑(参考首页的处理方式) 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; return item; }); console.log('过滤后的商品列表:', cleanedGoods); // 检查商品数据结构 if (cleanedGoods.length > 0) { console.log('第一个商品的媒体数据:', cleanedGoods[0].mediaItems); } this.setData({ goods: cleanedGoods, loading: false }); }) .catch(err => { console.error('获取商品列表失败:', err); this.setData({ loading: false }); wx.showToast({ title: '获取商品失败,请稍后重试', icon: 'none' }); }); }, // 轮播图切换事件 onSwiperChange: function (e) { this.setData({ currentSwiperIndex: e.detail.current }); }, // 视频播放结束事件 onVideoEnded: function () { const { currentGoods, currentSwiperIndex } = this.data; if (currentGoods && currentGoods.mediaItems) { const totalItems = currentGoods.mediaItems.length; const nextIndex = (currentSwiperIndex + 1) % totalItems; this.setData({ currentSwiperIndex: nextIndex }); } }, // 加载商品数据 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 }); // 如果是第一页,获取所有符合条件的商品 if (page === 1) { // 使用新的API接口获取相同规格的商品数据 API.getProductsBySpecification(specWeight) .then(comparisonProducts => { console.log('获取到的对比商品数据:', comparisonProducts); console.log('选择的种类:', selectedCategory); console.log('选择的规格:', specWeight); let filteredGoods = []; if (comparisonProducts && Array.isArray(comparisonProducts)) { console.log('原始商品数量:', comparisonProducts.length); // 获取当前商品的唯一标识符 const currentGoodsId = goodsData.productId || goodsData.id || goodsData._id; console.log('当前商品ID:', currentGoodsId); // 过滤商品 filteredGoods = comparisonProducts.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; } 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) { // 确保价格是一个单一的值,而不是多个价格的组合 if (matchingSpec.price) { item.price = matchingSpec.price; } // 确保库存是对应规格的库存 if (matchingSpec.quantity) { item.specStock = matchingSpec.quantity; } } } } // 清理价格字段,确保只显示单一价格 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); } // 处理库存显示逻辑 // 优先使用对应规格的库存,如果没有则使用默认库存 let quantity = item.specStock || item.quantity || item.minOrder || item.stock || item.inventory || item.availableStock || item.totalAvailable; // 清理库存字段,确保只显示单一值 if (quantity) { // 如果库存是字符串且包含逗号,只取第一个库存 if (typeof quantity === 'string' && quantity.includes(',')) { quantity = quantity.split(',')[0].trim(); } // 如果库存是数组,只取第一个库存 if (Array.isArray(quantity)) { quantity = quantity[0]; } // 转换为数字 quantity = Number(quantity); } 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]; } } // 计算单位价格 item.unitPrice = calculateUnitPrice(item.price, item.currentSpec || item.specification || (item.processedSpecs && item.processedSpecs.length > 0 ? item.processedSpecs.join(' | ') : '')); // 计算价格涨幅 if (goodsData.price) { // 获取当前商品的价格(使用单位价格如果低于10元) let currentPrice = parseFloat(goodsData.price); if (goodsData.unitPrice) { currentPrice = parseFloat(goodsData.unitPrice); } // 获取对比商品的价格(根据规则使用合适的价格) let itemPrice = parseFloat(item.price); if (currentPrice >= 10 && item.unitPrice) { // 如果当前商品价格高于10元,对比商品使用单位价格 itemPrice = parseFloat(item.unitPrice); } else if (currentPrice < 10 && itemPrice < 10) { // 如果两者都低于10元,使用原始价格 itemPrice = parseFloat(item.price); } else if (currentPrice < 10 && itemPrice >= 10) { // 如果当前商品低于10元,对比商品高于10元,当前商品使用单位价格 currentPrice = parseFloat(goodsData.unitPrice || goodsData.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; }); // 存储所有符合条件的商品 this.setData({ allGoods: processedGoods }); // 计算当前页应该显示的商品 const { pageSize } = this.data; const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; const currentPageGoods = processedGoods.slice(startIndex, endIndex); // 检查是否还有更多数据 const hasMore = endIndex < processedGoods.length; // 设置商品数据 this.setData({ goods: currentPageGoods, loading: false, loadingMore: false, currentPage: page, hasMore: hasMore, selectedOption: selectedCategory || '对比价格', showTips: false }); console.log('对比价格数据加载完成:', currentPageGoods); // 显示提示信息 wx.showToast({ title: `找到${processedGoods.length}个符合条件的商品`, icon: 'success', duration: 2000 }); }) .catch(err => { console.error('获取商品列表失败:', err); this.setData({ loading: false, loadingMore: false }); wx.showToast({ title: '获取商品失败,请稍后重试', icon: 'none' }); }); } else { // 如果不是第一页,从allGoods中获取数据 const { allGoods, pageSize } = this.data; const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; const currentPageGoods = allGoods.slice(startIndex, endIndex); // 检查是否还有更多数据 const hasMore = endIndex < allGoods.length; // 合并商品数据 const newGoods = [...this.data.goods, ...currentPageGoods]; // 设置商品数据 this.setData({ goods: newGoods, loading: false, loadingMore: false, currentPage: page, hasMore: hasMore }); console.log('加载更多数据完成:', currentPageGoods); } }, // 加载更多数据 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({ delta: 1 }); }, // 选择规格 selectSpec: function (e) { const selectedSpec = e.currentTarget.dataset.spec; if (!selectedSpec) { return; } const specWeight = selectedSpec.weightSpec.trim(); const currentGoods = this.data.currentGoods; // 更新选中的规格 this.setData({ selectedSpec: specWeight, loading: true }); // 处理当前商品的价格,使用选中规格的价格 let currentPrice = currentGoods.price; if (selectedSpec && selectedSpec.price) { // 如果selectedSpec包含价格信息,使用它 currentPrice = selectedSpec.price; } else if (currentGoods.weightQuantityData && Array.isArray(currentGoods.weightQuantityData)) { // 如果weightQuantityData存在,尝试从中找到对应规格的价格 const matchingSpec = currentGoods.weightQuantityData.find(spec => { if (spec.weightSpec) { return spec.weightSpec.trim() === specWeight; } return false; }); if (matchingSpec && matchingSpec.price) { currentPrice = matchingSpec.price; } } // 更新currentGoods的价格 currentGoods.price = currentPrice; // 清理价格字段,确保只显示单一价格 if (currentGoods.price) { // 如果价格是字符串且包含逗号,只取第一个价格 if (typeof currentGoods.price === 'string' && currentGoods.price.includes(',')) { currentGoods.price = currentGoods.price.split(',')[0].trim(); } // 如果价格是数组,只取第一个价格 if (Array.isArray(currentGoods.price)) { currentGoods.price = currentGoods.price[0]; } } // 计算当前商品的单位价格 currentGoods.unitPrice = calculateUnitPrice(currentGoods.price, specWeight || currentGoods.specification); // 更新currentGoods this.setData({ currentGoods: currentGoods }); // 初始化商品数据 this.setData({ goods: [], currentPage: 1, hasMore: true }); // 加载商品数据 this.loadGoodsData(1, this.data.selectedCategory, specWeight, currentGoods); } });