Browse Source

优化对比价格ui

Xfy
User 6 days ago
parent
commit
6f882874b2
  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. 107
      pages/compare_price/index.js
  5. 98
      pages/compare_price/index.wxml
  6. 21
      pages/compare_price/index.wxss

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

107
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
});
}
}
});

98
pages/compare_price/index.wxml

@ -3,7 +3,7 @@
<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;">
@ -23,14 +23,53 @@
</view>
<view wx:else>
<view wx:if="{{goods.length > 0 && (selectedOption || selectedCategory)}}" 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;">选择的种类: {{selectedCategory}}</text>
<text style="font-size: 28rpx; font-weight: bold; color: #333; text-align: center; display: block; margin-top: 10rpx;">选择的规格: {{selectedSpec}}</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"
@ -66,7 +105,7 @@
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{false}}"
autoplay="{{true}}"
loop="{{true}}"
muted="{{true}}"
poster=""
@ -92,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>
@ -100,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>
@ -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 || ''}}
</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>
@ -175,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);">
@ -190,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;
}

Loading…
Cancel
Save