8 changed files with 544 additions and 5 deletions
|
After Width: | Height: | Size: 672 KiB |
@ -0,0 +1,126 @@ |
|||
// pages/compare_price/index.js
|
|||
const API = require('../../utils/api.js'); |
|||
|
|||
Page({ |
|||
data: { |
|||
// 页面数据
|
|||
showTips: true, |
|||
goods: [], |
|||
loading: false, |
|||
selectedOption: '' |
|||
}, |
|||
|
|||
onLoad: function (options) { |
|||
// 页面加载
|
|||
console.log('对比价格页面加载'); |
|||
}, |
|||
|
|||
onShow: function () { |
|||
// 页面显示
|
|||
}, |
|||
|
|||
onHide: function () { |
|||
// 页面隐藏
|
|||
}, |
|||
|
|||
onUnload: function () { |
|||
// 页面卸载
|
|||
}, |
|||
|
|||
onPullDownRefresh: function () { |
|||
// 下拉刷新
|
|||
}, |
|||
|
|||
onReachBottom: function () { |
|||
// 上拉触底
|
|||
}, |
|||
|
|||
// 图片加载完成事件
|
|||
onImageLoad: function (e) { |
|||
// 图片加载完成后的处理逻辑
|
|||
console.log('图片加载完成:', e); |
|||
}, |
|||
|
|||
// 关闭提示弹窗
|
|||
closeTips: function () { |
|||
this.setData({ |
|||
showTips: false |
|||
}); |
|||
}, |
|||
|
|||
// 选择选项
|
|||
selectOption: function (e) { |
|||
const option = e.currentTarget.dataset.option; |
|||
console.log('选择了:', option); |
|||
|
|||
// 显示加载状态
|
|||
this.setData({ |
|||
loading: true, |
|||
selectedOption: option |
|||
}); |
|||
|
|||
// 调用 API 获取符合条件的商品
|
|||
API.getProducts(1, 20, 'all', '') |
|||
.then(res => { |
|||
console.log('获取商品列表成功:', res); |
|||
// 过滤出 category 匹配且 price 不为 null 的商品
|
|||
const filteredGoods = res.products.filter(item => |
|||
item.category === option && |
|||
item.status === 'published' && |
|||
item.price !== null && |
|||
item.price !== undefined |
|||
); |
|||
|
|||
// 清理 mediaItems 中的 URL,去除反引号和空格
|
|||
// 同时处理 imageUrls 字段,将其转换为 mediaItems 格式
|
|||
const cleanedGoods = filteredGoods.map(item => { |
|||
// 首先清理 imageUrls 字段(如果存在)
|
|||
if (item.imageUrls && Array.isArray(item.imageUrls)) { |
|||
item.imageUrls = item.imageUrls.map(url => { |
|||
return url.trim().replace(/[`]/g, ''); |
|||
}); |
|||
|
|||
// 如果没有 mediaItems 字段,将 imageUrls 转换为 mediaItems 格式
|
|||
if (!item.mediaItems || !Array.isArray(item.mediaItems) || item.mediaItems.length === 0) { |
|||
item.mediaItems = item.imageUrls.map(url => ({ |
|||
type: 'image', |
|||
url: url |
|||
})); |
|||
} |
|||
} |
|||
|
|||
// 清理 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, ''); |
|||
} |
|||
return media; |
|||
}); |
|||
} |
|||
return item; |
|||
}); |
|||
|
|||
console.log('过滤后的商品列表:', cleanedGoods); |
|||
// 检查商品数据结构
|
|||
if (cleanedGoods.length > 0) { |
|||
console.log('第一个商品的媒体数据:', cleanedGoods[0].mediaItems); |
|||
} |
|||
this.setData({ |
|||
goods: cleanedGoods, |
|||
loading: false |
|||
}); |
|||
}) |
|||
.catch(err => { |
|||
console.error('获取商品列表失败:', err); |
|||
this.setData({ |
|||
loading: false |
|||
}); |
|||
wx.showToast({ |
|||
title: '获取商品失败,请稍后重试', |
|||
icon: 'none' |
|||
}); |
|||
}); |
|||
} |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"navigationBarTitleText": "对比价格", |
|||
"usingComponents": {} |
|||
} |
|||
@ -0,0 +1,170 @@ |
|||
<!-- pages/compare_price/index.wxml --> |
|||
<!--背景图片--> |
|||
<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="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> |
|||
</view> |
|||
<view style="display: flex; flex-direction: column; gap: 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="selectOption" data-option="绿壳">绿壳</button> |
|||
<button style="background-color: rgba(255, 255, 255, 0.8); color: #333; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx;" bindtap="selectOption" data-option="粉壳">粉壳</button> |
|||
<button style="background-color: rgba(255, 255, 255, 0.8); color: #333; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx;" bindtap="selectOption" data-option="褐壳">褐壳</button> |
|||
</view> |
|||
|
|||
<!-- 商品列表 --> |
|||
<view wx:if="{{loading}}" style="margin-top: 40rpx; color: #fff; text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);"> |
|||
<text>加载中...</text> |
|||
</view> |
|||
|
|||
<view wx:else> |
|||
<view wx:if="{{goods.length > 0}}" 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> |
|||
|
|||
<!-- 商品卡片列表 --> |
|||
<view class="waterfall-container"> |
|||
<view class="waterfall-column"> |
|||
<view |
|||
class="waterfall-item" |
|||
wx:for="{{goods}}" |
|||
wx:key="id" |
|||
wx:if="{{index % 2 === 0}}" |
|||
data-item="{{item}}" |
|||
> |
|||
<view class="product-card {{item.status === 'sold_out' ? 'sold-out-grayscale' : ''}}" style="position: relative; background-color: rgba(255, 255, 255, 0.8); border-radius: 16rpx; overflow: hidden;"> |
|||
<!-- 售空商品白色覆盖层 --> |
|||
<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> |
|||
<!-- 图片处理 --> |
|||
<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'}}" |
|||
mode="aspectFill" |
|||
lazy-load="true" |
|||
bindload="onImageLoad" |
|||
data-index="{{index}}" |
|||
></image> |
|||
<view wx:if="{{item.supplyStatus === '预售' && item.status !== 'sold_out'}}" class="promo-tag presale">预售</view> |
|||
<view wx:if="{{item.supplyStatus === '现货' && item.status !== 'sold_out'}}" class="promo-tag in-stock">现货</view> |
|||
<view wx:if="{{item.status === 'sold_out'}}" class="promo-tag sold-out">售空</view> |
|||
</view> |
|||
<view class="product-info"> |
|||
<view class="product-first-row"> |
|||
<view class="status-tag source-{{item.sourceType === '三方认证' ? 'third' : (item.sourceType === '平台货源' ? 'platform' : 'unverified')}}" style="margin-bottom: 8rpx;"> |
|||
{{item.sourceType || ''}} |
|||
</view> |
|||
<text class="product-title">{{item.name}}</text> |
|||
<text class="product-description">{{item.description || ''}}</text> |
|||
</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> |
|||
<view wx:if="{{item.status === 'sold_out'}}" class="status-tag item-count">已售:{{item.originalTotalStock || 0}}件</view> |
|||
</view> |
|||
<view class="product-meta"> |
|||
<text class="sales-count">已有{{item.frequency || 0}}人浏览</text> |
|||
<text class="product-price">¥{{item.price}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="waterfall-column"> |
|||
<view |
|||
class="waterfall-item" |
|||
wx:for="{{goods}}" |
|||
wx:key="id" |
|||
wx:if="{{index % 2 === 1}}" |
|||
data-item="{{item}}" |
|||
> |
|||
<view class="product-card {{item.status === 'sold_out' ? 'sold-out-grayscale' : ''}}" style="position: relative; background-color: rgba(255, 255, 255, 0.8); border-radius: 16rpx; overflow: hidden;"> |
|||
<!-- 售空商品白色覆盖层 --> |
|||
<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> |
|||
<!-- 图片处理 --> |
|||
<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'}}" |
|||
mode="aspectFill" |
|||
lazy-load="true" |
|||
bindload="onImageLoad" |
|||
data-index="{{index}}" |
|||
></image> |
|||
<view wx:if="{{item.supplyStatus === '预售' && item.status !== 'sold_out'}}" class="promo-tag presale">预售</view> |
|||
<view wx:if="{{item.supplyStatus === '现货' && item.status !== 'sold_out'}}" class="promo-tag in-stock">现货</view> |
|||
<view wx:if="{{item.status === 'sold_out'}}" class="promo-tag sold-out">售空</view> |
|||
</view> |
|||
<view class="product-info"> |
|||
<view class="product-first-row"> |
|||
<view class="status-tag source-{{item.sourceType === '三方认证' ? 'third' : (item.sourceType === '平台货源' ? 'platform' : 'unverified')}}" style="margin-bottom: 8rpx;"> |
|||
{{item.sourceType || ''}} |
|||
</view> |
|||
<text class="product-title">{{item.name}}</text> |
|||
<text class="product-description">{{item.description || ''}}</text> |
|||
</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> |
|||
<view wx:if="{{item.status === 'sold_out'}}" class="status-tag item-count">已售:{{item.originalTotalStock || 0}}件</view> |
|||
</view> |
|||
<view class="product-meta"> |
|||
<text class="sales-count">已有{{item.frequency || 0}}人浏览</text> |
|||
<text class="product-price">¥{{item.price}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view wx:else style="margin-top: 40rpx; color: #fff; text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);"> |
|||
<text>暂无商品数据</text> |
|||
</view> |
|||
</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> |
|||
<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> |
|||
@ -0,0 +1,217 @@ |
|||
/* pages/compare_price/index.wxss */ |
|||
/* 商品卡片样式 */ |
|||
|
|||
/* 瀑布流容器 */ |
|||
.waterfall-container { |
|||
display: flex; |
|||
gap: 16rpx; |
|||
width: 100%; |
|||
padding: 0 10rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
/* 瀑布流列 */ |
|||
.waterfall-column { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16rpx; |
|||
} |
|||
|
|||
/* 瀑布流商品项 */ |
|||
.waterfall-item { |
|||
border-radius: 16rpx; |
|||
overflow: hidden; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.waterfall-item:active { |
|||
transform: scale(0.98); |
|||
opacity: 0.9; |
|||
} |
|||
|
|||
/* 商品卡片 */ |
|||
.product-card { |
|||
width: 100%; |
|||
height: auto; |
|||
min-height: 450rpx; |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
overflow: hidden; |
|||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); |
|||
transition: all 0.3s ease; |
|||
display: flex; |
|||
flex-direction: column; |
|||
position: relative; |
|||
} |
|||
|
|||
.product-card:active { |
|||
transform: scale(0.98); |
|||
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
/* 商品图片区域 */ |
|||
.product-image-wrapper { |
|||
position: relative; |
|||
width: 100%; |
|||
height: 320rpx; |
|||
background: #f5f5f5; |
|||
border-radius: 16rpx 16rpx 0 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* 统一媒体元素样式 */ |
|||
.product-media { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: block; |
|||
object-fit: cover; |
|||
object-position: center; |
|||
background-color: #f5f5f5; |
|||
} |
|||
|
|||
/* 售空商品白色覆盖层 - 覆盖整个卡片 */ |
|||
.sold-out-overlay-full { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(255, 255, 255, 0.5); |
|||
z-index: 15; |
|||
border-radius: 16rpx; |
|||
backdrop-filter: none; |
|||
-webkit-backdrop-filter: none; |
|||
} |
|||
|
|||
/* 促销标签 */ |
|||
.promo-tag { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
padding: 6rpx 12rpx; |
|||
font-size: 20rpx; |
|||
color: #fff; |
|||
border-radius: 0 0 12rpx 0; |
|||
z-index: 20; |
|||
font-weight: 600; |
|||
} |
|||
|
|||
.promo-tag.presale { |
|||
background: linear-gradient(135deg, #ff6b00 0%, #ff8c00 100%); |
|||
box-shadow: 0 2rpx 8rpx rgba(255, 107, 0, 0.3); |
|||
} |
|||
|
|||
.promo-tag.in-stock { |
|||
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%); |
|||
box-shadow: 0 2rpx 8rpx rgba(82, 196, 26, 0.3); |
|||
} |
|||
|
|||
.promo-tag.sold-out { |
|||
background: linear-gradient(135deg, #a92a2aff 0%, #a6a6a6 100%); |
|||
box-shadow: 0 2rpx 8rpx rgba(140, 140, 140, 0.3); |
|||
} |
|||
|
|||
/* 商品信息区域 */ |
|||
.product-info { |
|||
padding: 16rpx; |
|||
height: auto; |
|||
min-height: 210rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
gap: 10rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
/* 第一行布局:货源类型 | 产品名称 | 货源描述 */ |
|||
.product-first-row { |
|||
display: block; |
|||
width: 100%; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
/* 商品标题 */ |
|||
.product-title { |
|||
font-size: 26rpx; |
|||
color: #000000; |
|||
font-weight: 700; |
|||
display: inline; |
|||
margin-right: 8rpx; |
|||
} |
|||
|
|||
/* 商品描述 */ |
|||
.product-description { |
|||
font-size: 26rpx; |
|||
color: #000000; |
|||
font-weight: 700; |
|||
display: inline; |
|||
word-break: break-word; |
|||
} |
|||
|
|||
/* 状态标签样式 */ |
|||
.status-tag { |
|||
display: inline; |
|||
margin-right: 8rpx; |
|||
font-size: 20rpx; |
|||
padding: 4rpx 8rpx; |
|||
border-radius: 4rpx; |
|||
font-weight: 600; |
|||
white-space: nowrap; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.status-tag.source-third { |
|||
background: rgba(24, 144, 255, 0.15); |
|||
color: #096dd9; |
|||
border: 1rpx solid rgba(24, 144, 255, 0.5); |
|||
} |
|||
|
|||
.status-tag.source-platform { |
|||
background: rgba(82, 196, 26, 0.15); |
|||
color: #389e0d; |
|||
border: 1rpx solid rgba(82, 196, 26, 0.5); |
|||
} |
|||
|
|||
.status-tag.source-unverified { |
|||
background: rgba(255, 122, 69, 0.15); |
|||
color: #ff7a45; |
|||
border: 1rpx solid rgba(255, 122, 69, 0.5); |
|||
} |
|||
|
|||
.status-tag.item-count { |
|||
background: rgba(82, 196, 26, 0.15); |
|||
color: #389e0d; |
|||
border: 1rpx solid rgba(82, 196, 26, 0.5); |
|||
} |
|||
|
|||
/* 商品库存行 */ |
|||
.product-stock-row { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
/* 销量和地区 - 淘宝风格 */ |
|||
.product-meta { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
font-size: 22rpx; |
|||
color: #999; |
|||
margin-top: 8rpx; |
|||
} |
|||
|
|||
.sales-count { |
|||
color: #999; |
|||
background: rgba(255, 77, 79, 0.08); |
|||
padding: 4rpx 10rpx; |
|||
border-radius: 6rpx; |
|||
font-size: 20rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.product-price { |
|||
font-size: 26rpx; |
|||
font-weight: bold; |
|||
color: #ff6b81; |
|||
} |
|||
Loading…
Reference in new issue