From 6f882874b292ebf25df6becf4e39a754131f9043 Mon Sep 17 00:00:00 2001 From: User Date: Sat, 28 Feb 2026 17:12:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=B9=E6=AF=94=E4=BB=B7?= =?UTF-8?q?=E6=A0=BCui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../@socket.io/component-emitter/index.js | 189 ++++++++++++++++++ .../@socket.io/component-emitter/index.js.map | 1 + .../accepts/miniprogram_npm/mime-db/index.js | 8 +- pages/compare_price/index.js | 107 +++++++++- pages/compare_price/index.wxml | 98 ++++++--- pages/compare_price/index.wxss | 21 +- 6 files changed, 378 insertions(+), 46 deletions(-) create mode 100644 miniprogram_npm/@socket.io/component-emitter/index.js create mode 100644 miniprogram_npm/@socket.io/component-emitter/index.js.map diff --git a/miniprogram_npm/@socket.io/component-emitter/index.js b/miniprogram_npm/@socket.io/component-emitter/index.js new file mode 100644 index 0000000..19242b8 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/miniprogram_npm/@socket.io/component-emitter/index.js.map b/miniprogram_npm/@socket.io/component-emitter/index.js.map new file mode 100644 index 0000000..b3e5acb --- /dev/null +++ b/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"]} \ No newline at end of file diff --git a/miniprogram_npm/accepts/miniprogram_npm/mime-db/index.js b/miniprogram_npm/accepts/miniprogram_npm/mime-db/index.js index bcd7c6a..e11ead6 100644 --- a/miniprogram_npm/accepts/miniprogram_npm/mime-db/index.js +++ b/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 \ No newline at end of file diff --git a/pages/compare_price/index.js b/pages/compare_price/index.js index 73b061b..a384548 100644 --- a/pages/compare_price/index.js +++ b/pages/compare_price/index.js @@ -40,7 +40,9 @@ Page({ loading: false, selectedOption: '', selectedCategory: '', - selectedSpec: '' + selectedSpec: '', + currentGoods: null, + currentSwiperIndex: 0 }, onLoad: function (options) { @@ -67,10 +69,44 @@ Page({ 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 + selectedSpec: specWeight, + currentGoods: goodsData }); // 调用 API 获取符合条件的商品 @@ -83,19 +119,30 @@ Page({ 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. 检查商品状态和价格 + // 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; } - // 2. 过滤种类 + // 3. 过滤种类 if (selectedCategory && selectedCategory !== '全部' && item.category !== selectedCategory) { return false; } - // 3. 过滤规格 + // 4. 过滤规格 if (specWeight) { // 检查多个可能存储重量信息的字段 const fieldsToCheck = [ @@ -220,6 +267,35 @@ 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 (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; @@ -458,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 + }); + } } }); \ No newline at end of file diff --git a/pages/compare_price/index.wxml b/pages/compare_price/index.wxml index 9657f76..33e5f51 100644 --- a/pages/compare_price/index.wxml +++ b/pages/compare_price/index.wxml @@ -3,7 +3,7 @@ - + @@ -23,14 +23,53 @@ - - - 选择的种类: {{selectedCategory}} - 选择的规格: {{selectedSpec}} + + + + 当前商品 + + + + + + + + + + + + + + + + {{currentGoods.name}} + + {{selectedSpec}} + {{currentGoods.yolk || '无'}} + 库存:{{currentGoods.totalStock || '充足'}} + + + + ¥{{currentGoods.price}} + ¥{{currentGoods.originalPrice}} + + + + + + + + + + + + 选择的种类: {{selectedCategory}} + 规格: {{selectedSpec}} + - + {{item.name}} - {{item.description || ''}} + + {{item.category || selectedCategory || '无'}} + {{item.specification || item.weightSpec || item.grossWeight || selectedSpec || '无'}} + {{item.yolk}} + 库存:{{item.totalStock && item.totalStock !== '充足' ? item.totalStock + '件' : (item.totalStock || '充足')}} @@ -100,7 +143,10 @@ 已有{{item.frequency || 0}}人浏览 - ¥{{item.price}} + + ¥{{item.price}} + ¥{{item.originalPrice}} + @@ -141,7 +187,7 @@ show-center-play-btn="{{true}}" show-play-btn="{{false}}" controls="{{true}}" - autoplay="{{false}}" + autoplay="{{true}}" loop="{{true}}" muted="{{true}}" poster="" @@ -167,7 +213,11 @@ {{item.sourceType || ''}} {{item.name}} - {{item.description || ''}} + + {{item.category || selectedCategory || '无'}} + {{item.specification || item.weightSpec || item.grossWeight || selectedSpec || '无'}} + {{item.yolk}} + 库存:{{item.totalStock && item.totalStock !== '充足' ? item.totalStock + '件' : (item.totalStock || '充足')}} @@ -175,13 +225,21 @@ 已有{{item.frequency || 0}}人浏览 - ¥{{item.price}} + + ¥{{item.price}} + ¥{{item.originalPrice}} + + + + + 已经加载全部符合的商品 + @@ -190,19 +248,5 @@ - - - - 欢迎使用对比价格功能 - 此页面用于对比不同商品的价格信息。 - 对比同种商品,不同规格 - 的商品价格信息。 - 想要看到相同规格的同种类型 - 相同规格的同种类型 - 点击商品内的对比价格按钮即可展示 - - - - - + \ No newline at end of file diff --git a/pages/compare_price/index.wxss b/pages/compare_price/index.wxss index 9085200..8f0327c 100644 --- a/pages/compare_price/index.wxss +++ b/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; }