|
|
@ -65,11 +65,14 @@ Page({ |
|
|
showTips: true, |
|
|
showTips: true, |
|
|
goods: [], |
|
|
goods: [], |
|
|
loading: false, |
|
|
loading: false, |
|
|
|
|
|
loadingMore: false, |
|
|
selectedOption: '', |
|
|
selectedOption: '', |
|
|
selectedCategory: '', |
|
|
selectedCategory: '', |
|
|
selectedSpec: '', |
|
|
selectedSpec: '', |
|
|
currentGoods: null, |
|
|
currentGoods: null, |
|
|
currentSwiperIndex: 0 |
|
|
currentSwiperIndex: 0, |
|
|
|
|
|
currentPage: 1, |
|
|
|
|
|
hasMore: true |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
onLoad: function (options) { |
|
|
onLoad: function (options) { |
|
|
@ -146,132 +149,141 @@ Page({ |
|
|
currentGoods: goodsData |
|
|
currentGoods: goodsData |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 调用 API 获取符合条件的商品
|
|
|
// 初始化商品数据
|
|
|
API.getProducts(1, 20, 'all', '') |
|
|
this.setData({ |
|
|
.then(res => { |
|
|
goods: [], |
|
|
console.log('获取商品列表成功:', res); |
|
|
currentPage: 1, |
|
|
console.log('选择的种类:', selectedCategory); |
|
|
hasMore: true |
|
|
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 => { |
|
|
this.loadGoodsData(1, selectedCategory, specWeight, goodsData); |
|
|
// 1. 排除当前商品
|
|
|
} catch (error) { |
|
|
const itemId = item.productId || item.id || item._id; |
|
|
console.error('解析商品数据失败:', error); |
|
|
if (currentGoodsId && itemId && currentGoodsId === itemId) { |
|
|
this.setData({ |
|
|
console.log('排除当前商品:', itemId); |
|
|
loading: false |
|
|
return false; |
|
|
}); |
|
|
|
|
|
wx.showToast({ |
|
|
|
|
|
title: '数据解析失败,请重试', |
|
|
|
|
|
icon: 'none', |
|
|
|
|
|
duration: 2000 |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 2. 检查商品状态和价格
|
|
|
|
|
|
if (item.status !== 'published' || item.price === null || item.price === undefined) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
// 3. 过滤种类
|
|
|
onShow: function () { |
|
|
if (selectedCategory && selectedCategory !== '全部' && item.category !== selectedCategory) { |
|
|
// 页面显示
|
|
|
return false; |
|
|
}, |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4. 过滤规格
|
|
|
onHide: function () { |
|
|
if (specWeight) { |
|
|
// 页面隐藏
|
|
|
// 检查多个可能存储重量信息的字段
|
|
|
}, |
|
|
const fieldsToCheck = [ |
|
|
|
|
|
item.specification, |
|
|
|
|
|
item.grossWeight, |
|
|
|
|
|
item.weightQuantityData, |
|
|
|
|
|
item.spec // 检查spec字段
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
let hasMatchingSpec = false; |
|
|
onUnload: function () { |
|
|
for (const field of fieldsToCheck) { |
|
|
// 页面卸载
|
|
|
if (!field) continue; |
|
|
}, |
|
|
|
|
|
|
|
|
if (typeof field === 'string') { |
|
|
onPullDownRefresh: function () { |
|
|
// 处理字符串格式的规格数据
|
|
|
// 下拉刷新
|
|
|
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; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 如果没有找到匹配的规格,尝试进行更宽松的匹配
|
|
|
onReachBottom: function () { |
|
|
if (!hasMatchingSpec) { |
|
|
// 上拉触底
|
|
|
console.log('尝试更宽松的匹配...'); |
|
|
}, |
|
|
// 提取规格中的数字部分进行匹配
|
|
|
|
|
|
const weightNum = specWeight.replace(/[^0-9-]/g, ''); |
|
|
|
|
|
console.log('提取的重量数字:', weightNum); |
|
|
|
|
|
|
|
|
|
|
|
for (const field of fieldsToCheck) { |
|
|
// 图片加载完成事件
|
|
|
if (!field) continue; |
|
|
onImageLoad: function (e) { |
|
|
|
|
|
// 图片加载完成后的处理逻辑
|
|
|
|
|
|
console.log('图片加载完成:', e); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
if (typeof field === 'string') { |
|
|
// 跳转到商品详情页面
|
|
|
if (field.includes(weightNum)) { |
|
|
navigateToGoodsDetail: function (e) { |
|
|
hasMatchingSpec = true; |
|
|
const item = e.currentTarget.dataset.item; |
|
|
break; |
|
|
if (!item) { |
|
|
} |
|
|
console.error('商品信息为空'); |
|
|
} else if (Array.isArray(field)) { |
|
|
return; |
|
|
if (field.some(spec => { |
|
|
|
|
|
const specStr = typeof spec === 'string' ? spec : (spec.weightSpec || spec.display || ''); |
|
|
|
|
|
return specStr.includes(weightNum); |
|
|
|
|
|
})) { |
|
|
|
|
|
hasMatchingSpec = true; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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' |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
if (!hasMatchingSpec) { |
|
|
// 重置选择,返回首页
|
|
|
return false; |
|
|
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); |
|
|
} |
|
|
} |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
return true; |
|
|
// 关闭提示弹窗
|
|
|
|
|
|
closeTips: function () { |
|
|
|
|
|
this.setData({ |
|
|
|
|
|
showTips: false |
|
|
}); |
|
|
}); |
|
|
console.log('过滤后的商品数量:', filteredGoods.length); |
|
|
}, |
|
|
console.log('过滤后的商品:', filteredGoods); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理商品数据
|
|
|
// 选择选项
|
|
|
const processedGoods = filteredGoods.map(item => { |
|
|
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 字段(如果存在)
|
|
|
// 首先清理 imageUrls 字段(如果存在)
|
|
|
if (item.imageUrls && Array.isArray(item.imageUrls)) { |
|
|
if (item.imageUrls && Array.isArray(item.imageUrls)) { |
|
|
item.imageUrls = item.imageUrls.map(url => { |
|
|
item.imageUrls = item.imageUrls.map(url => { |
|
|
@ -304,23 +316,6 @@ Page({ |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 处理商品价格,使用选中规格的价格
|
|
|
|
|
|
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 (item.price) { |
|
|
// 如果价格是字符串且包含逗号,只取第一个价格
|
|
|
// 如果价格是字符串且包含逗号,只取第一个价格
|
|
|
@ -331,6 +326,22 @@ Page({ |
|
|
if (Array.isArray(item.price)) { |
|
|
if (Array.isArray(item.price)) { |
|
|
item.price = item.price[0]; |
|
|
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); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 处理规格信息,将多个净重信息分割成数组
|
|
|
// 处理规格信息,将多个净重信息分割成数组
|
|
|
@ -341,11 +352,9 @@ Page({ |
|
|
item.processedSpecs = processSpecifications(item.weightSpec); |
|
|
item.processedSpecs = processSpecifications(item.weightSpec); |
|
|
} else if (item.grossWeight) { |
|
|
} else if (item.grossWeight) { |
|
|
item.processedSpecs = processSpecifications(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 quantity = item.quantity || item.minOrder || item.stock || item.inventory || item.availableStock || item.totalAvailable; |
|
|
const totalStock = quantity; |
|
|
const totalStock = quantity; |
|
|
|
|
|
|
|
|
@ -365,52 +374,18 @@ Page({ |
|
|
item.totalStock = displayStock; |
|
|
item.totalStock = displayStock; |
|
|
item.originalTotalStock = totalStock; |
|
|
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; |
|
|
return item; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 显示提示信息
|
|
|
console.log('过滤后的商品列表:', cleanedGoods); |
|
|
wx.showToast({ |
|
|
// 检查商品数据结构
|
|
|
title: `找到${processedGoods.length}个符合条件的商品`, |
|
|
if (cleanedGoods.length > 0) { |
|
|
icon: 'success', |
|
|
console.log('第一个商品的媒体数据:', cleanedGoods[0].mediaItems); |
|
|
duration: 2000 |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 设置商品数据
|
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
goods: processedGoods, |
|
|
goods: cleanedGoods, |
|
|
loading: false, |
|
|
loading: false |
|
|
selectedOption: selectedCategory || '对比价格', |
|
|
|
|
|
showTips: false |
|
|
|
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
console.log('对比价格数据加载完成:', processedGoods); |
|
|
|
|
|
}) |
|
|
}) |
|
|
.catch(err => { |
|
|
.catch(err => { |
|
|
console.error('获取商品列表失败:', err); |
|
|
console.error('获取商品列表失败:', err); |
|
|
@ -422,132 +397,163 @@ Page({ |
|
|
icon: 'none' |
|
|
icon: 'none' |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
} 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 () { |
|
|
onSwiperChange: function (e) { |
|
|
wx.switchTab({ |
|
|
this.setData({ |
|
|
url: '/pages/index/index', |
|
|
currentSwiperIndex: e.detail.current |
|
|
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 () { |
|
|
onVideoEnded: function () { |
|
|
|
|
|
const { currentGoods, currentSwiperIndex } = this.data; |
|
|
|
|
|
if (currentGoods && currentGoods.mediaItems) { |
|
|
|
|
|
const totalItems = currentGoods.mediaItems.length; |
|
|
|
|
|
const nextIndex = (currentSwiperIndex + 1) % totalItems; |
|
|
this.setData({ |
|
|
this.setData({ |
|
|
showTips: false |
|
|
currentSwiperIndex: nextIndex |
|
|
}); |
|
|
}); |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 选择选项
|
|
|
// 加载商品数据
|
|
|
selectOption: function (e) { |
|
|
loadGoodsData: function (page, selectedCategory, specWeight, goodsData) { |
|
|
const option = e.currentTarget.dataset.option; |
|
|
if (this.data.loadingMore || (page !== 1 && !this.data.hasMore)) { |
|
|
console.log('选择了:', option); |
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 显示加载状态
|
|
|
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
loading: true, |
|
|
loading: page === 1 ? true : false, |
|
|
selectedOption: option |
|
|
loadingMore: page > 1 ? true : false |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 调用 API 获取符合条件的商品
|
|
|
API.getProducts(page, 20, 'all', '') |
|
|
API.getProducts(1, 20, 'all', '') |
|
|
|
|
|
.then(res => { |
|
|
.then(res => { |
|
|
console.log('获取商品列表成功:', res); |
|
|
console.log('获取商品列表成功:', res); |
|
|
// 过滤出 category 匹配且 price 不为 null 的商品
|
|
|
console.log('选择的种类:', selectedCategory); |
|
|
const filteredGoods = res.products.filter(item => |
|
|
console.log('选择的规格:', specWeight); |
|
|
item.category === option && |
|
|
|
|
|
item.status === 'published' && |
|
|
|
|
|
item.price !== null && |
|
|
|
|
|
item.price !== undefined |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// 清理 mediaItems 中的 URL,去除反引号和空格
|
|
|
let filteredGoods = []; |
|
|
// 同时处理 imageUrls 字段,将其转换为 mediaItems 格式
|
|
|
if (res && res.products) { |
|
|
// 处理库存显示逻辑
|
|
|
console.log('原始商品数量:', res.products.length); |
|
|
const cleanedGoods = filteredGoods.map(item => { |
|
|
// 获取当前商品的唯一标识符
|
|
|
|
|
|
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 字段(如果存在)
|
|
|
// 首先清理 imageUrls 字段(如果存在)
|
|
|
if (item.imageUrls && Array.isArray(item.imageUrls)) { |
|
|
if (item.imageUrls && Array.isArray(item.imageUrls)) { |
|
|
item.imageUrls = item.imageUrls.map(url => { |
|
|
item.imageUrls = item.imageUrls.map(url => { |
|
|
@ -580,6 +586,23 @@ Page({ |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理商品价格,使用选中规格的价格
|
|
|
|
|
|
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 (item.price) { |
|
|
// 如果价格是字符串且包含逗号,只取第一个价格
|
|
|
// 如果价格是字符串且包含逗号,只取第一个价格
|
|
|
@ -590,22 +613,6 @@ Page({ |
|
|
if (Array.isArray(item.price)) { |
|
|
if (Array.isArray(item.price)) { |
|
|
item.price = item.price[0]; |
|
|
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); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 处理规格信息,将多个净重信息分割成数组
|
|
|
// 处理规格信息,将多个净重信息分割成数组
|
|
|
@ -616,9 +623,11 @@ Page({ |
|
|
item.processedSpecs = processSpecifications(item.weightSpec); |
|
|
item.processedSpecs = processSpecifications(item.weightSpec); |
|
|
} else if (item.grossWeight) { |
|
|
} else if (item.grossWeight) { |
|
|
item.processedSpecs = processSpecifications(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 quantity = item.quantity || item.minOrder || item.stock || item.inventory || item.availableStock || item.totalAvailable; |
|
|
const totalStock = quantity; |
|
|
const totalStock = quantity; |
|
|
|
|
|
|
|
|
@ -638,23 +647,68 @@ Page({ |
|
|
item.totalStock = displayStock; |
|
|
item.totalStock = displayStock; |
|
|
item.originalTotalStock = totalStock; |
|
|
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; |
|
|
return item; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
console.log('过滤后的商品列表:', cleanedGoods); |
|
|
// 合并商品数据
|
|
|
// 检查商品数据结构
|
|
|
const newGoods = page === 1 ? processedGoods : [...this.data.goods, ...processedGoods]; |
|
|
if (cleanedGoods.length > 0) { |
|
|
|
|
|
console.log('第一个商品的媒体数据:', cleanedGoods[0].mediaItems); |
|
|
// 检查是否还有更多数据
|
|
|
} |
|
|
const hasMore = res && res.products && res.products.length >= 20; |
|
|
|
|
|
|
|
|
|
|
|
// 设置商品数据
|
|
|
this.setData({ |
|
|
this.setData({ |
|
|
goods: cleanedGoods, |
|
|
goods: newGoods, |
|
|
loading: false |
|
|
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 => { |
|
|
.catch(err => { |
|
|
console.error('获取商品列表失败:', err); |
|
|
console.error('获取商品列表失败:', err); |
|
|
this.setData({ |
|
|
this.setData({ |
|
|
loading: false |
|
|
loading: false, |
|
|
|
|
|
loadingMore: false |
|
|
}); |
|
|
}); |
|
|
wx.showToast({ |
|
|
wx.showToast({ |
|
|
title: '获取商品失败,请稍后重试', |
|
|
title: '获取商品失败,请稍后重试', |
|
|
@ -663,23 +717,16 @@ Page({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 轮播图切换事件
|
|
|
// 加载更多数据
|
|
|
onSwiperChange: function (e) { |
|
|
loadMore: function () { |
|
|
this.setData({ |
|
|
if (this.data.loadingMore || !this.data.hasMore) { |
|
|
currentSwiperIndex: e.detail.current |
|
|
return; |
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 视频播放结束事件
|
|
|
|
|
|
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 |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const { currentPage, selectedCategory, selectedSpec, currentGoods } = this.data; |
|
|
|
|
|
const specWeight = selectedSpec; |
|
|
|
|
|
|
|
|
|
|
|
this.loadGoodsData(currentPage + 1, selectedCategory, specWeight, currentGoods); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 返回上一页
|
|
|
// 返回上一页
|
|
|
|