Trae AI 7 days ago
parent
commit
5cd065ee5d
  1. 189
      miniprogram_npm/@socket.io/component-emitter/index.js
  2. 1
      miniprogram_npm/@socket.io/component-emitter/index.js.map
  3. 8
      miniprogram_npm/accepts/miniprogram_npm/mime-db/index.js
  4. 386
      pages/compare_price/index.js
  5. 216
      pages/compare_price/index.wxml
  6. 21
      pages/compare_price/index.wxss
  7. 127
      pages/goods-detail/goods-detail.js

189
miniprogram_npm/@socket.io/component-emitter/index.js

@ -0,0 +1,189 @@
module.exports = (function() {
var __MODS__ = {};
var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
__DEFINE__(1772256867255, function(require, module, exports) {
/**
* Expose `Emitter`.
*/
exports.Emitter = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
}
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
// Remove event specific arrays for event types that no
// one is subscribed for to avoid memory leak.
if (callbacks.length === 0) {
delete this._callbacks['$' + event];
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = new Array(arguments.length - 1)
, callbacks = this._callbacks['$' + event];
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
// alias used for reserved events (protected method)
Emitter.prototype.emitReserved = Emitter.prototype.emit;
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
}, function(modId) {var map = {}; return __REQUIRE__(map[modId], modId); })
return __REQUIRE__(1772256867255);
})()
//miniprogram-npm-outsideDeps=[]
//# sourceMappingURL=index.js.map

1
miniprogram_npm/@socket.io/component-emitter/index.js.map

@ -0,0 +1 @@
{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":["\n/**\n * Expose `Emitter`.\n */\n\nexports.Emitter = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n if (obj) return mixin(obj);\n}\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n (this._callbacks['$' + event] = this._callbacks['$' + event] || [])\n .push(fn);\n return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n function on() {\n this.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks['$' + event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks['$' + event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n\n // Remove event specific arrays for event types that no\n // one is subscribed for to avoid memory leak.\n if (callbacks.length === 0) {\n delete this._callbacks['$' + event];\n }\n\n return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n this._callbacks = this._callbacks || {};\n\n var args = new Array(arguments.length - 1)\n , callbacks = this._callbacks['$' + event];\n\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n};\n\n// alias used for reserved events (protected method)\nEmitter.prototype.emitReserved = Emitter.prototype.emit;\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n this._callbacks = this._callbacks || {};\n return this._callbacks['$' + event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n return !! this.listeners(event).length;\n};\n"]}

8
miniprogram_npm/accepts/miniprogram_npm/mime-db/index.js

@ -4,7 +4,7 @@ var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexport
var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
__DEFINE__(1761637667903, function(require, module, exports) {
__DEFINE__(1772256867256, function(require, module, exports) {
/*!
* mime-db
* Copyright(c) 2014 Jonathan Ong
@ -18,8 +18,8 @@ __DEFINE__(1761637667903, function(require, module, exports) {
module.exports = require('./db.json')
}, function(modId) {var map = {"./db.json":1761637667904}; return __REQUIRE__(map[modId], modId); })
__DEFINE__(1761637667904, function(require, module, exports) {
}, function(modId) {var map = {"./db.json":1772256867257}; return __REQUIRE__(map[modId], modId); })
__DEFINE__(1772256867257, function(require, module, exports) {
module.exports = {
"application/1d-interleaved-parityfec": {
"source": "iana"
@ -9364,7 +9364,7 @@ module.exports = {
}
}, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
return __REQUIRE__(1761637667903);
return __REQUIRE__(1772256867256);
})()
//miniprogram-npm-outsideDeps=[]
//# sourceMappingURL=index.js.map

386
pages/compare_price/index.js

@ -1,18 +1,363 @@
// 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'
};
});
}
Page({
data: {
// 页面数据
showTips: true,
goods: [],
loading: false,
selectedOption: ''
selectedOption: '',
selectedCategory: '',
selectedSpec: '',
currentGoods: null,
currentSwiperIndex: 0
},
onLoad: function (options) {
// 页面加载
console.log('对比价格页面加载');
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];
}
}
// 保存选择的种类、规格和当前商品数据到页面数据
this.setData({
selectedCategory: selectedCategory,
selectedSpec: specWeight,
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, '');
});
// 使用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];
}
}
// 处理库存显示逻辑
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;
});
// 显示提示信息
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'
});
});
} catch (error) {
console.error('解析商品数据失败:', error);
this.setData({
loading: false
});
wx.showToast({
title: '数据解析失败,请重试',
icon: 'none',
duration: 2000
});
}
}
},
onShow: function () {
@ -120,12 +465,14 @@ Page({
return url.trim().replace(/[`]/g, '');
});
// 如果没有 mediaItems 字段,将 imageUrls 转换为 mediaItems 格式
if (!item.mediaItems || !Array.isArray(item.mediaItems) || item.mediaItems.length === 0) {
item.mediaItems = item.imageUrls.map(url => ({
type: 'image',
url: url
}));
// 使用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];
}
}
@ -135,6 +482,10 @@ Page({
if (media.url) {
// 去除 URL 中的反引号和空格
media.url = media.url.trim().replace(/[`]/g, '');
// 确保媒体类型正确
if (!media.type) {
media.type = isVideoUrl(media.url) ? 'video' : 'image';
}
}
return media;
});
@ -183,5 +534,24 @@ Page({
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
});
}
}
});

216
pages/compare_price/index.wxml

@ -3,38 +3,19 @@
<view style="position: relative; width: 100%; height: 100vh; overflow: hidden;">
<image src="../../images/background.png" mode="aspectFill" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></image>
<scroll-view style="position: relative; z-index: 10; width: 100%; height: 100%;" scroll-y="true" enable-back-to-top="true">
<view style="width: 100%; display: flex; flex-direction: column; align-items: center; padding: 20rpx; padding-bottom: 100rpx;">
<view style="width: 100%; display: flex; flex-direction: column; align-items: center; padding: 0; padding-bottom: 20rpx;">
<!-- 类别选择区域 -->
<view wx:if="{{!selectedOption}}">
<view style="background-color: rgba(255, 255, 255, 0.8); border-radius: 10rpx; padding: 20rpx; margin-bottom: 20rpx;">
<text style="font-size: 32rpx; font-weight: bold; color: #333; text-align: center;">请选择想要了解的商品</text>
<text style="font-size: 32rpx; font-weight: bold; color: #333; text-align: center;">请从商品详情页点击对比价格</text>
</view>
<view style="display: flex; flex-direction: column; gap: 24rpx; width: 100%; max-width: 400rpx;">
<view style="position: relative; width: 100%; height: 140rpx; border-radius: 12rpx; overflow: hidden; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); transition: all 0.3s ease;" bindtap="selectOption" data-option="绿壳">
<image src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=fresh%20green%20shell%20eggs%20in%20a%20wooden%20box%2C%20natural%20light%2C%20soft%20focus%2C%20warm%20tones&image_size=landscape_4_3" mode="aspectFill" style="width: 100%; height: 100%;"></image>
<view style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.6)); display: flex; justify-content: center; align-items: center;">
<text style="font-size: 36rpx; font-weight: bold; color: #333; text-shadow: 0 2rpx 4rpx rgba(255, 255, 255, 0.8);">绿壳</text>
</view>
</view>
<view style="position: relative; width: 100%; height: 140rpx; border-radius: 12rpx; overflow: hidden; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); transition: all 0.3s ease;" bindtap="selectOption" data-option="粉壳">
<image src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=fresh%20pink%20shell%20eggs%20in%20a%20wooden%20box%2C%20natural%20light%2C%20soft%20focus%2C%20warm%20tones&image_size=landscape_4_3" mode="aspectFill" style="width: 100%; height: 100%;"></image>
<view style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.6)); display: flex; justify-content: center; align-items: center;">
<text style="font-size: 36rpx; font-weight: bold; color: #333; text-shadow: 0 2rpx 4rpx rgba(255, 255, 255, 0.8);">粉壳</text>
</view>
</view>
<view style="position: relative; width: 100%; height: 140rpx; border-radius: 12rpx; overflow: hidden; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); transition: all 0.3s ease;" bindtap="selectOption" data-option="褐壳">
<image src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=fresh%20brown%20shell%20eggs%20in%20a%20wooden%20box%2C%20natural%20light%2C%20soft%20focus%2C%20warm%20tones&image_size=landscape_4_3" mode="aspectFill" style="width: 100%; height: 100%;"></image>
<view style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.6)); display: flex; justify-content: center; align-items: center;">
<text style="font-size: 36rpx; font-weight: bold; color: #333; text-shadow: 0 2rpx 4rpx rgba(255, 255, 255, 0.8);">褐壳</text>
</view>
</view>
<view style="display: flex; flex-direction: column; gap: 24rpx; width: 100%; max-width: 400rpx; align-items: center;">
<text style="font-size: 28rpx; color: #666; text-align: center; line-height: 40rpx;">此页面仅用于展示对比价格数据</text>
<text style="font-size: 28rpx; color: #666; text-align: center; line-height: 40rpx;">请返回商品详情页</text>
<text style="font-size: 28rpx; color: #666; text-align: center; line-height: 40rpx;">点击对比价格按钮</text>
</view>
</view>
<!-- 返回按钮(选择后显示) -->
<view wx:else style="margin-bottom: 20rpx; width: 100%; max-width: 400rpx;">
<button style="background-color: rgba(255, 255, 255, 0.8); color: #333; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx;" bindtap="resetSelection">返回选择</button>
</view>
<!-- 商品列表 -->
<view wx:if="{{loading}}" style="margin-top: 40rpx; color: #fff; text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);">
@ -42,13 +23,53 @@
</view>
<view wx:else>
<view wx:if="{{goods.length > 0 && selectedOption}}" style="margin-top: 40rpx; width: 100%; max-width: 750rpx;">
<view style="background-color: rgba(255, 255, 255, 0.8); border-radius: 10rpx; padding: 20rpx; margin-bottom: 20rpx;">
<text style="font-size: 28rpx; font-weight: bold; color: #333; text-align: center; display: block;">{{selectedOption}}在售商品</text>
<view wx:if="{{(selectedOption || selectedCategory)}}" style="margin-top: 10rpx; width: 100%; box-sizing: border-box;">
<!-- 当前商品信息 -->
<view wx:if="{{currentGoods}}" style="background-color: rgba(255, 255, 255, 0.8); border-radius: 10rpx; padding: 20rpx; margin-bottom: 20rpx; width: 100%; box-sizing: border-box;">
<text style="font-size: 30rpx; font-weight: bold; color: #333; text-align: center; display: block; margin-bottom: 10rpx;">当前商品</text>
<view style="display: flex; flex-direction: column; gap: 16rpx;">
<!-- 商品图片/视频轮播 -->
<view style="width: 100%; height: 400rpx; border-radius: 10rpx; overflow: hidden; position: relative;">
<swiper wx:if="{{currentGoods.mediaItems && currentGoods.mediaItems.length > 0}}" indicator-dots="{{true}}" autoplay="{{false}}" interval="10000" duration="500" style="width: 100%; height: 100%;" current="{{currentSwiperIndex}}" bindchange="onSwiperChange">
<swiper-item wx:for="{{currentGoods.mediaItems}}" wx:key="index">
<image wx:if="{{item.type === 'image'}}" src="{{item.url}}" mode="aspectFill" style="width: 100%; height: 100%;"></image>
<video wx:else src="{{item.url}}" mode="aspectFill" style="width: 100%; height: 100%;" controls="{{true}}" autoplay="{{true}}" loop="{{false}}" bindended="onVideoEnded"></video>
</swiper-item>
</swiper>
<image wx:else src="https://via.placeholder.com/300x300.png?text=No+Image" mode="aspectFill" style="width: 100%; height: 100%;"></image>
</view>
<!-- 商品信息 -->
<view style="display: flex; flex-direction: column; gap: 12rpx;">
<view style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
<view style="display: flex; align-items: center; gap: 15rpx; flex: 1;">
<text style="font-size: 36rpx; font-weight: bold; color: #333; word-break: break-word;">{{currentGoods.name}}</text>
<view style="display: flex; gap: 15rpx; flex-wrap: wrap;">
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666;">{{selectedSpec}}</view>
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666;">{{currentGoods.yolk || '无'}}</view>
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666;">库存:{{currentGoods.totalStock || '充足'}}</view>
</view>
</view>
<view style="display: flex; flex-direction: column; align-items: flex-end; margin-left: 12rpx; flex-shrink: 0;">
<text style="font-size: 40rpx; font-weight: bold; color: #ff4d4f;">¥{{currentGoods.price}}</text>
<text wx:if="{{currentGoods.originalPrice}}" style="font-size: 28rpx; color: #999; text-decoration: line-through; margin-top: 4rpx;">¥{{currentGoods.originalPrice}}</text>
</view>
</view>
<view style="display: flex; flex-wrap: wrap; gap: 15rpx; margin-top: 8rpx; justify-content: space-around;">
</view>
</view>
</view>
</view>
<!-- 选择信息 -->
<view style="background-color: rgba(255, 255, 255, 0.8); border-radius: 10rpx; padding: 15rpx; margin-bottom: 15rpx; width: 100%; box-sizing: border-box;">
<view style="display: flex; justify-content: center; align-items: center; gap: 30rpx; flex-wrap: wrap;">
<text style="font-size: 32rpx; font-weight: bold; color: #333;">选择的种类: {{selectedCategory}}</text>
<text style="font-size: 32rpx; font-weight: bold; color: #333;">规格: {{selectedSpec}}</text>
</view>
</view>
<!-- 商品卡片列表 -->
<view class="waterfall-container">
<view class="waterfall-container" style="width: 100%; box-sizing: border-box;">
<view class="waterfall-column">
<view
class="waterfall-item"
@ -62,26 +83,39 @@
<!-- 售空商品白色覆盖层 -->
<view wx:if="{{item.status === 'sold_out'}}" class="sold-out-overlay-full"></view>
<view class="product-image-wrapper">
<!-- 视频处理:根据mediaItems中的类型字段判断 -->
<video
wx:if="{{item.mediaItems && item.mediaItems.length > 0 && item.mediaItems[0].type === 'video'}}"
id="video-{{item.id}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{false}}"
loop="{{true}}"
muted="{{true}}"
poster=""
></video>
<!-- 图片处理 -->
<!-- 媒体处理:优先展示图片 -->
<block wx:if="{{item.mediaItems && item.mediaItems.length > 0}}">
<!-- 图片处理 -->
<image
wx:if="{{item.mediaItems[0].type === 'image'}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
lazy-load="true"
bindload="onImageLoad"
data-index="{{index}}"
></image>
<!-- 视频处理:如果没有图片再展示视频 -->
<video
wx:else
id="video-{{item.id}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{true}}"
loop="{{true}}"
muted="{{true}}"
poster=""
></video>
</block>
<!-- 占位图:如果没有媒体数据 -->
<image
wx:else
class="product-media"
src="{{item.mediaItems && item.mediaItems.length > 0 ? item.mediaItems[0].url : 'https://via.placeholder.com/300x300.png?text=No+Image'}}"
src="https://via.placeholder.com/300x300.png?text=No+Image"
mode="aspectFill"
lazy-load="true"
bindload="onImageLoad"
@ -97,7 +131,11 @@
{{item.sourceType || ''}}
</view>
<text class="product-title">{{item.name}}</text>
<text class="product-description">{{item.description || ''}}</text>
<view style="display: flex; flex-wrap: nowrap; gap: 8rpx; margin-top: 8rpx; overflow-x: auto; padding-bottom: 8rpx;">
<view wx:if="{{item.category || selectedCategory}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.category || selectedCategory || '无'}}</view>
<view wx:if="{{item.specification || item.weightSpec || item.grossWeight || selectedSpec}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.specification || item.weightSpec || item.grossWeight || selectedSpec || '无'}}</view>
<view wx:if="{{item.yolk}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.yolk}}</view>
</view>
</view>
<view class="product-stock-row" style="margin-top: 8rpx;">
<view wx:if="{{item.status !== 'sold_out'}}" class="status-tag item-count">库存:{{item.totalStock && item.totalStock !== '充足' ? item.totalStock + '件' : (item.totalStock || '充足')}}</view>
@ -105,7 +143,10 @@
</view>
<view class="product-meta">
<text class="sales-count">已有{{item.frequency || 0}}人浏览</text>
<text class="product-price">¥{{item.price}}</text>
<view style="display: flex; flex-direction: column; align-items: flex-end;">
<text class="product-price">¥{{item.price}}</text>
<text wx:if="{{item.originalPrice}}" style="font-size: 20rpx; color: #999; text-decoration: line-through; margin-top: 2rpx;">¥{{item.originalPrice}}</text>
</view>
</view>
</view>
</view>
@ -124,26 +165,39 @@
<!-- 售空商品白色覆盖层 -->
<view wx:if="{{item.status === 'sold_out'}}" class="sold-out-overlay-full"></view>
<view class="product-image-wrapper">
<!-- 视频处理:根据mediaItems中的类型字段判断 -->
<video
wx:if="{{item.mediaItems && item.mediaItems.length > 0 && item.mediaItems[0].type === 'video'}}"
id="video-{{item.id}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{false}}"
loop="{{true}}"
muted="{{true}}"
poster=""
></video>
<!-- 图片处理 -->
<!-- 媒体处理:优先展示图片 -->
<block wx:if="{{item.mediaItems && item.mediaItems.length > 0}}">
<!-- 图片处理 -->
<image
wx:if="{{item.mediaItems[0].type === 'image'}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
lazy-load="true"
bindload="onImageLoad"
data-index="{{index}}"
></image>
<!-- 视频处理:如果没有图片再展示视频 -->
<video
wx:else
id="video-{{item.id}}"
class="product-media"
src="{{item.mediaItems[0].url}}"
mode="aspectFill"
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{true}}"
loop="{{true}}"
muted="{{true}}"
poster=""
></video>
</block>
<!-- 占位图:如果没有媒体数据 -->
<image
wx:else
class="product-media"
src="{{item.mediaItems && item.mediaItems.length > 0 ? item.mediaItems[0].url : 'https://via.placeholder.com/300x300.png?text=No+Image'}}"
src="https://via.placeholder.com/300x300.png?text=No+Image"
mode="aspectFill"
lazy-load="true"
bindload="onImageLoad"
@ -159,7 +213,11 @@
{{item.sourceType || ''}}
</view>
<text class="product-title">{{item.name}}</text>
<text class="product-description">{{item.description || ''}}</text>
<view style="display: flex; flex-wrap: nowrap; gap: 8rpx; margin-top: 8rpx; overflow-x: auto; padding-bottom: 8rpx;">
<view wx:if="{{item.category || selectedCategory}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.category || selectedCategory || '无'}}</view>
<view wx:if="{{item.specification || item.weightSpec || item.grossWeight || selectedSpec}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.specification || item.weightSpec || item.grossWeight || selectedSpec || '无'}}</view>
<view wx:if="{{item.yolk}}" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item.yolk}}</view>
</view>
</view>
<view class="product-stock-row" style="margin-top: 8rpx;">
<view wx:if="{{item.status !== 'sold_out'}}" class="status-tag item-count">库存:{{item.totalStock && item.totalStock !== '充足' ? item.totalStock + '件' : (item.totalStock || '充足')}}</view>
@ -167,13 +225,21 @@
</view>
<view class="product-meta">
<text class="sales-count">已有{{item.frequency || 0}}人浏览</text>
<text class="product-price">¥{{item.price}}</text>
<view style="display: flex; flex-direction: column; align-items: flex-end;">
<text class="product-price">¥{{item.price}}</text>
<text wx:if="{{item.originalPrice}}" style="font-size: 20rpx; color: #999; text-decoration: line-through; margin-top: 2rpx;">¥{{item.originalPrice}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 加载完成提示 -->
<view wx:if="{{!loading && goods.length > 0}}" style="margin-top: 15rpx; width: 100%; box-sizing: border-box;">
<text style="font-size: 28rpx; color: #333; text-align: center; display: block;">已经加载全部符合的商品</text>
</view>
</view>
<view wx:if="{{goods.length === 0 && selectedOption}}" style="margin-top: 40rpx; color: #fff; text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);">
@ -182,19 +248,5 @@
</view>
</view>
</scroll-view>
<!-- 透明弹窗提示 -->
<view wx:if="{{showTips}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 100; background-color: rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;">
<view style="background-color: rgba(255, 255, 255, 0.9); border-radius: 16rpx; padding: 40rpx; width: 80%; max-width: 500rpx; text-align: center;">
<text style="font-size: 32rpx; font-weight: bold; color: #333; margin-bottom: 20rpx; display: block;">欢迎使用对比价格功能</text>
<text style="font-size: 28rpx; color: #666; line-height: 40rpx;">此页面用于对比不同商品的价格信息。</text>
<text style="font-size: 28rpx; color: #f10b0bff; line-height: 40rpx;">对比同种商品,不同规格</text>
<text style="font-size: 28rpx; color: #666; line-height: 40rpx;">的商品价格信息。</text>
<text style="font-size: 28rpx; color: #666; line-height: 40rpx;">想要看到相同规格的同种类型</text>
<text style="font-size: 28rpx; color: #f10b0bff; line-height: 40rpx;">相同规格的同种类型</text>
<text style="font-size: 28rpx; color: #666; line-height: 40rpx;">点击商品内的对比价格按钮即可展示</text>
<view style="margin-top: 40rpx;">
<button style="background-color: #ff6b81; color: #fff; border-radius: 8rpx; padding: 12rpx 40rpx; font-size: 28rpx;" bindtap="closeTips">我知道了</button>
</view>
</view>
</view>
</view>

21
pages/compare_price/index.wxss

@ -4,9 +4,9 @@
/* 瀑布流容器 */
.waterfall-container {
display: flex;
gap: 16rpx;
gap: 8rpx;
width: 100%;
padding: 0 10rpx;
padding: 0;
box-sizing: border-box;
}
@ -34,7 +34,7 @@
.product-card {
width: 100%;
height: auto;
min-height: 450rpx;
min-height: 550rpx;
background: #fff;
border-radius: 16rpx;
overflow: hidden;
@ -54,7 +54,7 @@
.product-image-wrapper {
position: relative;
width: 100%;
height: 320rpx;
height: 380rpx;
background: #f5f5f5;
border-radius: 16rpx 16rpx 0 0;
overflow: hidden;
@ -153,12 +153,14 @@
.status-tag {
display: inline;
margin-right: 8rpx;
font-size: 20rpx;
padding: 4rpx 8rpx;
border-radius: 4rpx;
font-size: 24rpx;
padding: 4rpx 12rpx;
border-radius: 16rpx;
font-weight: 600;
white-space: nowrap;
flex-shrink: 0;
background-color: #f0f0f0;
color: #666;
}
.status-tag.source-third {
@ -211,7 +213,8 @@
}
.product-price {
font-size: 26rpx;
font-size: 40rpx;
font-weight: bold;
color: #ff6b81;
color: #ff4d4f;
flex-shrink: 0;
}

127
pages/goods-detail/goods-detail.js

@ -3691,7 +3691,7 @@ Page({
// 对比价格功能:处理按钮点击事件
onCompareClick: function () {
console.log('用户点击了对比价格按钮,准备显示弹窗');
console.log('用户点击了对比价格按钮,准备跳转到对比价格页面');
// 检查用户登录状态
const openid = wx.getStorageSync('openid');
@ -3744,27 +3744,97 @@ Page({
console.log('用户身份证认证状态:', idcardstatus);
// 获取当前商品的信息
const currentGoods = this.data.goodsDetail;
const currentCategory = currentGoods.category || '';
const currentSpecifications = currentGoods.weightQuantityData || [];
// 定义种类选项
const categoryOptions = ['全部', '绿壳', '粉壳', '褐壳', '土鸡蛋'];
// 直接获取当前页面滚动位置
wx.createSelectorQuery().selectViewport().scrollOffset(function(res) {
console.log('记录当前滚动位置:', res.scrollTop);
// 保存滚动位置并显示弹窗
this.setData({
scrollTop: res.scrollTop,
showCompareModal: true,
activeTab: 'home' // 默认显示首页数据选项卡
});
// 找到当前商品种类在选项中的索引,默认为0(全部)
let defaultCategoryIndex = 0;
if (currentCategory) {
const index = categoryOptions.indexOf(currentCategory);
if (index !== -1) {
defaultCategoryIndex = index;
}
}
// 显示种类选择对话框
wx.showActionSheet({
itemList: categoryOptions,
success: (categoryRes) => {
const selectedCategoryIndex = categoryRes.tapIndex;
const selectedCategory = categoryOptions[selectedCategoryIndex];
// 打印弹窗状态,用于调试
console.log('弹窗状态设置为:', this.data.showCompareModal);
// 构建规格选择列表
const specList = currentSpecifications.map((spec, index) => {
return spec.display || spec.weightSpec || `规格${index + 1}`;
});
// 加载首页数据
this.loadHomeGoods();
// 显示规格选择对话框
wx.showActionSheet({
itemList: specList,
success: (specRes) => {
const selectedSpecIndex = specRes.tapIndex;
const selectedSpec = currentSpecifications[selectedSpecIndex];
// 显示提示信息
wx.showToast({
title: `已选择${selectedCategory} ${selectedSpec.display}`,
icon: 'info',
duration: 1500,
success: () => {
setTimeout(() => {
// 构建要传递的数据
const goodsData = {
id: currentGoods.id || currentGoods.productId,
name: currentGoods.name || '',
price: currentGoods.price || '',
imageUrls: currentGoods.imageUrls || [],
region: currentGoods.region || '',
weightQuantityData: currentGoods.weightQuantityData || [],
category: selectedCategory,
yolk: currentGoods.yolk || '',
sourceType: currentGoods.sourceType || '',
supplyStatus: currentGoods.supplyStatus || '',
mediaItems: currentGoods.mediaItems || [],
frequency: currentGoods.frequency || 0,
status: currentGoods.status || 'published',
totalStock: currentGoods.totalStock || '充足',
selectedSpec: selectedSpec
};
// 加载收藏数据
this.loadFavoriteGoods();
}.bind(this)).exec();
console.log('准备跳转到对比价格页面,传递的数据:', goodsData);
// 跳转到对比价格页面
wx.navigateTo({
url: `/pages/compare_price/index?goodsData=${encodeURIComponent(JSON.stringify(goodsData))}`,
success: function () {
console.log('成功跳转到对比价格页面');
},
fail: function (error) {
console.error('跳转到对比价格页面失败:', error);
wx.showToast({
title: '跳转失败,请稍后重试',
icon: 'none'
});
}
});
}, 1500);
}
});
},
fail: (res) => {
console.log('选择规格失败:', res);
}
});
},
fail: (res) => {
console.log('选择种类失败:', res);
}
});
},
// 关闭对比价格弹窗
@ -3802,18 +3872,21 @@ Page({
},
// 加载首页商品数据
loadHomeGoods: function () {
loadHomeGoods: function (selectedCategory, selectedSpec) {
this.setData({ loadingHome: true });
// 获取当前商品的规格信息
const currentGoods = this.data.goodsDetail;
const currentSpecifications = currentGoods.weightQuantityData || [];
// 提取当前商品的净重规格(如"净重41-42")
const currentWeightSpecs = currentSpecifications.map(item => item.weightSpec.trim())
.filter(spec => spec && (spec.includes('净重') || spec.includes('毛重')));
// 提取当前商品的种类(category)
const currentCategory = currentGoods.category || '';
console.log('当前商品的种类:', currentCategory);
// 使用传入的参数或默认值
const categoryToUse = selectedCategory || currentGoods.category || '';
const specToUse = selectedSpec || (currentSpecifications.length > 0 ? currentSpecifications[0] : null);
// 提取规格信息
const currentWeightSpecs = specToUse ? [specToUse.weightSpec.trim()] : [];
console.log('当前选择的种类:', categoryToUse);
console.log('当前选择的规格:', specToUse);
// 调用API获取首页商品列表
API.getProducts()
@ -3883,12 +3956,12 @@ Page({
isSoldOutLabel: isSoldOutLabel // 添加是否显示已售空标签的标记
};
}).filter(goods => {
// 1. 先过滤相同种类(category)的商品
if (currentCategory && goods.category !== currentCategory) {
// 1. 先过滤种类(category)的商品
if (categoryToUse && categoryToUse !== '全部' && goods.category !== categoryToUse) {
return false;
}
// 2. 只有当当前商品有明确的规格时才进行筛选
// 2. 只有当有明确的规格时才进行筛选
if (currentWeightSpecs.length === 0) {
return true;
}

Loading…
Cancel
Save