Trae AI 7 days ago
parent
commit
4970545a40
  1. 3
      app.json
  2. BIN
      images/background.png
  3. 126
      pages/compare_price/index.js
  4. 4
      pages/compare_price/index.json
  5. 170
      pages/compare_price/index.wxml
  6. 217
      pages/compare_price/index.wxss
  7. 17
      pages/index/index.js
  8. 12
      pages/index/index.wxml

3
app.json

@ -23,7 +23,8 @@
"pages/order/detail/index",
"pages/company/company",
"pages/qrcode/index",
"pages/collection/index"
"pages/collection/index",
"pages/compare_price/index"
],
"subpackages": [
{

BIN
images/background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 KiB

126
pages/compare_price/index.js

@ -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'
});
});
}
});

4
pages/compare_price/index.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "对比价格",
"usingComponents": {}
}

170
pages/compare_price/index.wxml

@ -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>

217
pages/compare_price/index.wxss

@ -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;
}

17
pages/index/index.js

@ -415,6 +415,23 @@ Page({
});
},
// 跳转到对比价格页面
navigateToComparePrice() {
wx.navigateTo({
url: '/pages/compare_price/index',
success: function () {
console.log('成功跳转到对比价格页面');
},
fail: function (error) {
console.error('跳转到对比价格页面失败:', error);
wx.showToast({
title: '跳转失败,请稍后重试',
icon: 'none'
});
}
});
},
// 切换侧边栏显示
toggleSidebar() {
if (this.data.isDragging) {

12
pages/index/index.wxml

@ -202,6 +202,14 @@
<text class="function-btn-icon">🛒</text>
<text class="function-btn-text">货源管理</text>
</view>
<view class="function-btn" bindtap="navigateToQRCode" wx:if="{{isInPersonnel}}">
<text class="function-btn-icon">📜</text>
<text class="function-btn-text">合格证</text>
</view>
<view class="function-btn" bindtap="navigateToComparePrice">
<text class="function-btn-icon">👓</text>
<text class="function-btn-text">对比价格</text>
</view>
<view class="function-btn" bindtap="navigateToSettlement">
<text class="function-btn-icon">🥚</text>
<text class="function-btn-text">我要卖蛋</text>
@ -214,10 +222,6 @@
<text class="function-btn-icon">📄</text>
<text class="function-btn-text">我们</text>
</view>
<view class="function-btn" bindtap="navigateToQRCode" wx:if="{{isInPersonnel}}">
<text class="function-btn-icon">📜</text>
<text class="function-btn-text">合格证</text>
</view>
</view>
<!-- 添加桌面引导框 -->

Loading…
Cancel
Save