Browse Source

价格对比结果页面ui设计

Xfy
Trae AI 4 days ago
parent
commit
e4d66543f3
  1. 256
      pages/compare_price/index.js
  2. 2
      pages/compare_price/index.json
  3. 352
      pages/compare_price/index.wxml
  4. 629
      pages/compare_price/index.wxss
  5. 40
      static/font/icons/remixicon.css

256
pages/compare_price/index.js

@ -113,6 +113,16 @@ Page({
}
}
// 处理当前商品的地区信息,只显示省份
if (goodsData.region) {
// 提取省份信息
const provinceRegex = /^([^省]+省|[^自治区]+自治区|[^直辖市]+直辖市|[^特别行政区]+特别行政区)/;
const match = goodsData.region.match(provinceRegex);
if (match) {
goodsData.region = match[1];
}
}
// 保存选择的种类、规格和当前商品数据到页面数据
this.setData({
selectedCategory: selectedCategory,
@ -245,102 +255,124 @@ Page({
}
// 处理商品数据
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];
}
}
// 处理规格信息,将多个净重信息分割成数组
item.processedSpecs = [];
if (item.specification) {
item.processedSpecs = processSpecifications(item.specification);
} else if (item.weightSpec) {
item.processedSpecs = processSpecifications(item.weightSpec);
} else if (item.grossWeight) {
item.processedSpecs = processSpecifications(item.grossWeight);
} else if (selectedSpec) {
item.processedSpecs = processSpecifications(selectedSpec);
}
// 处理库存显示逻辑
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;
});
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];
}
}
// 处理规格信息,将多个净重信息分割成数组
item.processedSpecs = [];
if (item.specification) {
item.processedSpecs = processSpecifications(item.specification);
} else if (item.weightSpec) {
item.processedSpecs = processSpecifications(item.weightSpec);
} else if (item.grossWeight) {
item.processedSpecs = processSpecifications(item.grossWeight);
} else if (selectedSpec) {
item.processedSpecs = processSpecifications(selectedSpec);
}
// 处理库存显示逻辑
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;
// 处理地区信息,只显示省份
if (item.region) {
// 提取省份信息
const provinceRegex = /^([^省]+省|[^自治区]+自治区|[^直辖市]+直辖市|[^特别行政区]+特别行政区)/;
const match = item.region.match(provinceRegex);
if (match) {
item.region = match[1];
}
}
// 计算价格涨幅
if (goodsData.price) {
const currentPrice = parseFloat(goodsData.price);
const itemPrice = parseFloat(item.price);
if (!isNaN(currentPrice) && !isNaN(itemPrice)) {
const priceDiff = itemPrice - currentPrice;
const pricePercent = ((priceDiff / currentPrice) * 100).toFixed(1);
item.priceDiff = priceDiff;
item.pricePercent = pricePercent;
}
}
return item;
});
// 显示提示信息
wx.showToast({
@ -438,14 +470,27 @@ Page({
});
},
// 重置选择,返回类别选择页面
// 重置选择,返回首页
resetSelection: function () {
this.setData({
selectedOption: '',
goods: [],
loading: false
wx.switchTab({
url: '/pages/index/index',
success: function() {
console.log('成功返回首页');
},
fail: function(error) {
console.error('返回首页失败:', error);
// 如果switchTab失败,尝试使用navigateTo
wx.navigateTo({
url: '/pages/index/index',
success: function() {
console.log('使用navigateTo成功返回首页');
},
fail: function(error) {
console.error('使用navigateTo返回首页也失败:', error);
}
});
}
});
console.log('已重置选择,返回类别选择页面');
},
// 关闭提示弹窗
@ -586,5 +631,12 @@ Page({
currentSwiperIndex: nextIndex
});
}
},
// 返回上一页
navigateBack: function () {
wx.navigateBack({
delta: 1
});
}
});

2
pages/compare_price/index.json

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

352
pages/compare_price/index.wxml

@ -1,252 +1,148 @@
<!-- 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: 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>
</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 class="page-container">
<scroll-view class="scroll-view" scroll-y="true" enable-back-to-top="true">
<!-- 步骤完成提示区 -->
<view class="tips-section">
<view class="tips-container">
<view class="tips-icon">
<text class="check-icon">✓</text>
</view>
<text class="tips-text">您已完成选择,以下是{{currentGoods ? currentGoods.productName : '商品'}}({{selectedSpec || '43-44g'}})的价格对比结果</text>
</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="{{(selectedOption || selectedCategory)}}" style="margin-top: 10rpx; width: 100%; box-sizing: border-box; padding: 0 20rpx;">
<!-- 当前商品信息 -->
<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 wx:if="{{loading}}" class="loading">
<text>加载中...</text>
</view>
<view wx:else>
<view wx:if="{{(selectedOption || selectedCategory)}}" class="content-container">
<!-- 当前商品卡片 -->
<view wx:if="{{currentGoods}}" class="current-goods-section">
<view class="section-title">
<text class="title-icon">🏷</text>
<text class="title-text">当前商品</text>
</view>
<view class="current-goods-card">
<view class="goods-header">
<view class="brand-tag">品牌</view>
<text class="goods-name">{{currentGoods.productName}}</text>
<view class="price-container">
<text class="currency-symbol" style="color: {{currentGoods.priceDiff > 0 ? '#FF4D4F' : currentGoods.priceDiff < 0 ? '#10B981' : '#666666'}}">¥</text>
<text class="price-amount" style="color: {{currentGoods.priceDiff > 0 ? '#FF4D4F' : currentGoods.priceDiff < 0 ? '#10B981' : '#666666'}}">{{currentGoods.price}}</text>
</view>
<!-- 商品信息 -->
<view style="display: flex; flex-direction: column; gap: 12rpx;">
<view style="display: flex; justify-content: space-between; align-items: center; flex-wrap: nowrap;">
<view style="display: flex; align-items: center; gap: 15rpx; flex: 1; overflow: hidden;">
<text style="font-size: 36rpx; font-weight: bold; color: #333; word-break: break-word; flex-shrink: 0;">{{currentGoods.name}}</text>
<view style="display: flex; gap: 15rpx; overflow-x: auto; padding-bottom: 4rpx;">
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666; flex-shrink: 0;">{{selectedSpec}}</view>
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666; flex-shrink: 0;">{{currentGoods.yolk || '无'}}</view>
<view style="background-color: #f0f0f0; padding: 8rpx 20rpx; border-radius: 24rpx; font-size: 36rpx; color: #666; flex-shrink: 0;">库存:{{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>
<text class="spec-info">{{currentGoods.specification || selectedSpec || '净重43-44g'}} | {{currentGoods.yolk || '绿壳'}} | 库存:{{currentGoods.totalStock || '450'}}</text>
<view class="merchant-info">
<view class="merchant-left">
<text class="merchant-icon">🏪</text>
<text class="merchant-text">{{currentGoods.sourceType || '鸡场直销'}}</text>
</view>
<view class="merchant-right">
<text class="merchant-icon">📍</text>
<text class="merchant-text">{{currentGoods.region || '重庆'}}</text>
</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 class="compare-section">
<view class="section-title">
<text class="title-icon">⚖</text>
<text class="title-text">同类商品价格对比</text>
<view class="filter-btn">
<text class="filter-text">筛选</text>
<text class="filter-icon">☰</text>
</view>
</view>
<!-- 商品卡片列表 -->
<view class="waterfall-container" style="width: 100%; box-sizing: border-box;">
<view class="waterfall-column">
<view
class="waterfall-item"
wx:for="{{goods}}"
wx:key="id"
wx:if="{{index % 2 === 0}}"
data-item="{{item}}"
bindtap="navigateToGoodsDetail"
>
<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">
<!-- 媒体处理:优先展示图片 -->
<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="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>
<view style="display: flex; flex-wrap: wrap; gap: 8rpx; margin-top: 8rpx; 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:for="{{item.processedSpecs}}" wx:key="index" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item}}</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>
<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>
<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 class="compare-list">
<view
class="compare-item"
wx:for="{{goods}}"
wx:key="id"
data-item="{{item}}"
bindtap="navigateToGoodsDetail"
>
<view class="compare-item-header">
<text class="compare-item-name">{{item.productName || item.name}}</text>
<view class="compare-item-price">
<text class="currency-symbol" style="color: {{item.priceDiff > 0 ? '#FF4D4F' : item.priceDiff < 0 ? '#10B981' : '#666666'}}">¥</text>
<text class="compare-price-amount" style="color: {{item.priceDiff > 0 ? '#FF4D4F' : item.priceDiff < 0 ? '#10B981' : '#666666'}}">{{item.price}}</text>
</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}}"
bindtap="navigateToGoodsDetail"
>
<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">
<!-- 媒体处理:优先展示图片 -->
<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="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>
<text class="compare-item-spec">{{item.specification || (item.processedSpecs && item.processedSpecs.length > 0 ? item.processedSpecs.join(' | ') : '净重:45-50g')}} | 蛋壳:{{item.category || '绿壳'}} | 蛋黄:{{item.yolk || '无'}}</text>
<view class="compare-item-footer">
<view class="merchant-region">
<text class="compare-item-merchant">🏪 {{item.sourceType || '生态农场'}}</text>
<text class="compare-item-region"> | 📍 {{item.region || '地区'}}</text>
</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>
<view style="display: flex; flex-wrap: wrap; gap: 8rpx; margin-top: 8rpx; 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:for="{{item.processedSpecs}}" wx:key="index" style="background-color: #f0f0f0; padding: 4rpx 12rpx; border-radius: 16rpx; font-size: 24rpx; color: #666;">{{item}}</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>
<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>
<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 class="price-comparison" wx:if="{{item.pricePercent}}">
<text class="price-trend-icon" style="color: {{item.priceDiff > 0 ? '#EF4444' : item.priceDiff < 0 ? '#10B981' : '#666666'}}">{{item.priceDiff > 0 ? '↑' : item.priceDiff < 0 ? '↓' : '→'}}</text>
<text class="price-trend-text" style="color: {{item.priceDiff > 0 ? '#FF4D4F' : item.priceDiff < 0 ? '#10B981' : '#666666'}}">{{item.priceDiff > 0 ? '+' : ''}}{{item.pricePercent}}%</text>
</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 class="trend-section">
<view class="section-title">
<text class="title-icon">📈</text>
<text class="title-text">价格趋势对比</text>
</view>
<view class="trend-chart">
<view class="chart-container">
<!-- 图表内容 -->
<view class="chart-placeholder">
<text>价格趋势图</text>
</view>
</view>
<view class="chart-legend">
<view class="legend-item">
<view class="legend-dot blue"></view>
<text class="legend-text">当前商品</text>
</view>
<view class="legend-item">
<view class="legend-dot orange"></view>
<text class="legend-text">同类平均</text>
</view>
</view>
</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);">
<text>暂无在售数据</text>
<!-- 加载完成提示 -->
<view wx:if="{{!loading && goods.length > 0}}" class="load-complete">
<text>已经加载全部符合的商品</text>
</view>
</view>
<view wx:if="{{goods.length === 0 && selectedOption}}" class="no-data">
<text>暂无在售数据</text>
</view>
<!-- 类别选择区域 -->
<view wx:if="{{!selectedOption}}" class="select-section">
<view class="select-card">
<text class="select-title">请从商品详情页点击对比价格</text>
</view>
<view class="select-tips">
<text class="tips-line">此页面仅用于展示对比价格数据</text>
<text class="tips-line">请返回商品详情页</text>
<text class="tips-line">点击对比价格按钮</text>
</view>
</view>
</view>
</scroll-view>
<!-- 底部操作栏 -->
<view class="bottom-bar">
<view class="bottom-btn reset-btn full-width" bindtap="resetSelection">
<text class="btn-icon">🔄</text>
<text class="btn-text">重新选择</text>
</view>
</view>
</view>

629
pages/compare_price/index.wxss

@ -1,227 +1,542 @@
/* pages/compare_price/index.wxss */
/* 商品卡片样式 */
/* 全局样式 */
.page-container {
width: 100%;
min-height: 100vh;
background-color: #F9FAFB;
font-family: 'Noto Sans SC';
position: relative;
}
/* 瀑布流容器 */
.waterfall-container {
/* 导航栏 */
.navbar {
height: 64px;
background-color: #FFFFFF;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05);
display: flex;
gap: 16rpx;
align-items: center;
justify-content: space-between;
padding: 0 16px;
position: sticky;
top: 0;
z-index: 100;
}
.nav-left, .nav-right {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.nav-icon {
font-size: 20px;
color: #374151;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
}
.nav-center {
flex: 1;
text-align: center;
}
.nav-title {
font-size: 18px;
font-weight: 500;
color: #1A1A1A;
font-family: 'SourceHanSans-Medium';
}
/* 滚动视图 */
.scroll-view {
flex: 1;
width: 100%;
padding: 0 10rpx;
box-sizing: border-box;
height: calc(100vh - 64px - 75px);
}
/* 步骤完成提示区 */
.tips-section {
padding: 12px 16px;
}
/* 瀑布流列 */
.waterfall-column {
.tips-container {
background-color: #EFF6FF;
border: 1px solid #DBEAFE;
border-radius: 8px;
padding: 12px;
display: flex;
align-items: center;
gap: 12px;
}
.tips-icon {
width: 32px;
height: 32px;
background-color: #DBEAFE;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.check-icon {
font-size: 16px;
color: #3B82F6;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
}
.tips-text {
flex: 1;
font-size: 14px;
color: #165DFF;
font-family: 'SourceHanSans-Medium';
line-height: 1.4;
}
/* 内容容器 */
.content-container {
padding: 0 16px;
}
/* 加载状态 */
.loading {
padding: 40px 0;
text-align: center;
color: #666666;
}
/* 无数据状态 */
.no-data {
padding: 40px 0;
text-align: center;
color: #666666;
}
/* 类别选择区域 */
.select-section {
padding: 40px 16px;
display: flex;
flex-direction: column;
gap: 16rpx;
min-width: 0;
align-items: center;
gap: 24px;
}
/* 瀑布流商品项 */
.waterfall-item {
border-radius: 16rpx;
overflow: hidden;
transition: all 0.3s ease;
.select-card {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 10px;
padding: 20px;
width: 100%;
max-width: 400px;
text-align: center;
}
.waterfall-item:active {
transform: scale(0.98);
opacity: 0.9;
.select-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
/* 商品卡片 */
.product-card {
.select-tips {
display: flex;
flex-direction: column;
gap: 24rpx;
width: 100%;
height: auto;
min-height: 550rpx;
background: #fff;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
max-width: 400px;
align-items: center;
}
.tips-line {
font-size: 28rpx;
color: #666666;
text-align: center;
line-height: 40rpx;
}
/* 区域标题 */
.section-title {
display: flex;
align-items: center;
justify-content: space-between;
margin: 20px 0 12px;
}
.title-icon {
font-size: 16px;
color: #FACC15;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
margin-right: 8px;
}
.compare-section .title-icon {
color: #3B82F6;
}
.trend-section .title-icon {
color: #3B82F6;
}
.title-text {
font-size: 16px;
color: #1A1A1A;
font-weight: 500;
flex: 1;
}
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
}
.filter-text {
font-size: 14px;
color: #3B82F6;
}
.filter-icon {
font-size: 14px;
color: #3B82F6;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
}
/* 当前商品卡片 */
.current-goods-section {
margin-bottom: 20px;
}
.current-goods-card {
background-color: #EFF6FF;
border: 1px solid #DBEAFE;
border-radius: 12px;
padding: 16px;
display: flex;
flex-direction: column;
position: relative;
box-sizing: border-box;
gap: 8px;
}
.product-card:active {
transform: scale(0.98);
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
.goods-header {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
/* 商品图片区域 */
.product-image-wrapper {
position: relative;
width: 100%;
height: 380rpx;
background: #f5f5f5;
border-radius: 16rpx 16rpx 0 0;
overflow: hidden;
.brand-tag {
background-color: #DBEAFE;
border-radius: 9999px;
padding: 2px 8px;
font-size: 12px;
color: #165DFF;
flex-shrink: 0;
}
/* 统一媒体元素样式 */
.product-media {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
object-position: center;
background-color: #f5f5f5;
.goods-name {
font-size: 16px;
color: #1A1A1A;
font-weight: 500;
flex: 1;
min-width: 0;
}
/* 售空商品白色覆盖层 - 覆盖整个卡片 */
.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;
.price-container {
display: flex;
align-items: baseline;
gap: 4px;
flex-shrink: 0;
}
/* 促销标签 */
.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;
.currency-symbol {
font-size: 14px;
}
.promo-tag.presale {
background: linear-gradient(135deg, #ff6b00 0%, #ff8c00 100%);
box-shadow: 0 2rpx 8rpx rgba(255, 107, 0, 0.3);
.price-amount {
font-size: 24px;
font-weight: bold;
}
.promo-tag.in-stock {
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
box-shadow: 0 2rpx 8rpx rgba(82, 196, 26, 0.3);
.spec-info {
font-size: 14px;
color: #666666;
margin-top: 4px;
}
.promo-tag.sold-out {
background: linear-gradient(135deg, #a92a2aff 0%, #a6a6a6 100%);
box-shadow: 0 2rpx 8rpx rgba(140, 140, 140, 0.3);
.merchant-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 4px;
}
.merchant-left {
display: flex;
align-items: center;
gap: 6px;
}
.merchant-right {
display: flex;
align-items: center;
gap: 6px;
}
.merchant-icon {
font-size: 14px;
color: #9CA3AF;
}
.merchant-text {
font-size: 14px;
color: #666666;
}
/* 商品信息区域 */
.product-info {
padding: 16rpx;
height: auto;
min-height: 210rpx;
/* 对比商品列表 */
.compare-section {
margin-bottom: 20px;
}
.compare-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.compare-item {
border: 1px solid #E5E7EB;
border-radius: 12px;
padding: 16px;
display: flex;
flex-direction: column;
gap: 8px;
background-color: #FFFFFF;
transition: all 0.3s ease;
}
.compare-item:active {
transform: scale(0.98);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
}
.compare-item-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10rpx;
box-sizing: border-box;
width: 100%;
gap: 12px;
}
/* 第一行布局:货源类型 | 产品名称 | 货源描述 */
.product-first-row {
display: block;
width: 100%;
.compare-item-name {
font-size: 15px;
color: #1A1A1A;
font-weight: 500;
flex: 1;
white-space: normal;
word-break: break-word;
line-height: 1.4;
}
/* 商品标题 */
.product-title {
font-size: 26rpx;
color: #000000;
font-weight: 700;
display: inline-block;
margin-right: 8rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
/* 商品描述 */
.product-description {
font-size: 26rpx;
color: #000000;
font-weight: 700;
display: inline;
.compare-item-price {
display: flex;
align-items: baseline;
gap: 4px;
flex-shrink: 0;
}
.compare-price-amount {
font-size: 18px;
font-weight: bold;
}
.compare-item-spec {
font-size: 12px;
color: #999999;
white-space: normal;
word-break: break-word;
margin-top: 4px;
}
.compare-item-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 8px;
}
.merchant-region {
display: flex;
align-items: center;
gap: 4px;
}
.compare-item-merchant {
font-size: 12px;
color: #999999;
}
/* 状态标签样式 */
.status-tag {
display: inline;
margin-right: 8rpx;
font-size: 24rpx;
padding: 4rpx 12rpx;
border-radius: 16rpx;
font-weight: 600;
white-space: nowrap;
.compare-item-region {
font-size: 12px;
color: #999999;
}
.price-comparison {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
background-color: #f0f0f0;
color: #666;
}
.status-tag.source-third {
background: rgba(24, 144, 255, 0.15);
color: #096dd9;
border: 1rpx solid rgba(24, 144, 255, 0.5);
.price-trend-icon {
font-size: 12px;
color: #EF4444;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
}
.status-tag.source-platform {
background: rgba(82, 196, 26, 0.15);
color: #389e0d;
border: 1rpx solid rgba(82, 196, 26, 0.5);
.price-trend-text {
font-size: 12px;
color: #FF4D4F;
}
.status-tag.source-unverified {
background: rgba(255, 122, 69, 0.15);
color: #ff7a45;
border: 1rpx solid rgba(255, 122, 69, 0.5);
/* 价格趋势图 */
.trend-section {
margin-bottom: 20px;
}
.status-tag.item-count {
background: rgba(82, 196, 26, 0.15);
color: #389e0d;
border: 1rpx solid rgba(82, 196, 26, 0.5);
.trend-chart {
display: flex;
flex-direction: column;
gap: 12px;
}
/* 商品库存行 */
.product-stock-row {
.chart-container {
width: 100%;
height: 180px;
background-color: #FFFFFF;
border: 1px solid #E5E7EB;
border-radius: 12px;
padding: 20px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
.chart-placeholder {
text-align: center;
color: #999999;
}
/* 销量和地区 - 淘宝风格 */
.product-meta {
.chart-legend {
display: flex;
justify-content: center;
gap: 24px;
}
.legend-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 22rpx;
color: #999;
margin-top: 8rpx;
gap: 8px;
}
.legend-dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.legend-dot.blue {
background-color: #165DFF;
}
.legend-dot.orange {
background-color: #F97316;
}
.legend-text {
font-size: 12px;
color: #666666;
}
/* 加载完成提示 */
.load-complete {
margin-top: 15px;
text-align: center;
color: #333333;
font-size: 14px;
}
/* 底部操作栏 */
.bottom-bar {
height: 75px;
background-color: #FFFFFF;
padding: 12px 16px;
box-sizing: border-box;
display: flex;
gap: 12px;
position: sticky;
bottom: 0;
z-index: 100;
box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.05);
}
.sales-count {
color: #999;
background: rgba(255, 77, 79, 0.08);
padding: 4rpx 10rpx;
border-radius: 6rpx;
font-size: 20rpx;
.bottom-btn {
flex: 1;
height: 50px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 16px;
font-weight: 500;
transition: all 0.3s ease;
}
.product-price {
font-size: 40rpx;
font-weight: bold;
color: #ff4d4f;
flex-shrink: 0;
.bottom-btn:active {
transform: scale(0.98);
}
.reset-btn {
border: 1px solid #D1D5DB;
background-color: #FFFFFF;
}
.full-width {
width: 100%;
}
.btn-icon {
font-size: 16px;
color: #374151;
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal;
line-height: 1;
}
.btn-icon.white {
color: #FFFFFF;
}
.btn-text {
color: #374151;
}
.btn-text.white {
color: #FFFFFF;
}

40
static/font/icons/remixicon.css

@ -0,0 +1,40 @@
/* RemixIcon Font Family */
@font-face {
font-family: 'remixicon';
src: url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.eot');
src: url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.eot?#iefix') format('embedded-opentype'),
url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.woff2') format('woff2'),
url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.woff') format('woff'),
url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.ttf') format('truetype'),
url('https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.svg#remixicon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
/* Icon Base Class */
[class^="ri-"]:before,
[class*=" ri-"]:before {
font-family: 'remixicon' !important;
font-style: normal;
font-weight: normal !important;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Common Icons */
.ri-arrow-left-line:before { content: "\e9a0"; }
.ri-share-line:before { content: "\ebfe"; }
.ri-check-double-line:before { content: "\eb7b"; }
.ri-price-tag-3-line:before { content: "\ecc6"; }
.ri-store-2-line:before { content: "\ecc5"; }
.ri-map-pin-line:before { content: "\ef14"; }
.ri-compasses-line:before { content: "\ec6d"; }
.ri-filter-3-line:before { content: "\ed25"; }
.ri-arrow-up-s-line:before { content: "\ea76"; }
.ri-line-chart-line:before { content: "\eebb"; }
.ri-refresh-line:before { content: "\eb44"; }
.ri-shopping-cart-line:before { content: "\ec20"; }
Loading…
Cancel
Save