|
After Width: | Height: | Size: 273 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 463 KiB After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 366 KiB |
|
After Width: | Height: | Size: 294 KiB |
@ -1,3 +1,5 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "选择兴趣",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "我的商品",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "white",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundTextStyle": "dark"
|
||||
}
|
||||
@ -0,0 +1,371 @@
|
||||
// pages/myProducts/myProducts.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
// 商品分类
|
||||
categories: ['全部', '电子产品', '图书文具', '服装鞋帽', '运动户外', '美妆个护', '家居生活', '其他'],
|
||||
selectedCategory: 0,
|
||||
|
||||
// 商品状态筛选
|
||||
statusFilter: ['全部', '在售', '已售出', '已下架'],
|
||||
selectedStatus: 0,
|
||||
|
||||
// 排序选项
|
||||
sortOptions: ['默认排序', '发布时间', '价格从低到高', '价格从高到低'],
|
||||
selectedSort: 0,
|
||||
|
||||
// 商品列表数据
|
||||
products: [],
|
||||
filteredProducts: [],
|
||||
|
||||
// 加载状态
|
||||
isLoading: true,
|
||||
error: '',
|
||||
|
||||
// 分页相关
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.loadMyProducts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 每次显示页面时重新加载数据,确保数据最新
|
||||
this.loadMyProducts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载我的商品列表
|
||||
*/
|
||||
loadMyProducts() {
|
||||
this.setData({
|
||||
isLoading: true,
|
||||
error: ''
|
||||
});
|
||||
|
||||
// 模拟从后端获取数据
|
||||
setTimeout(() => {
|
||||
// 模拟商品数据
|
||||
const mockProducts = [
|
||||
{
|
||||
id: 'p1',
|
||||
name: '二手iPhone 13 128GB 白色',
|
||||
price: '2999',
|
||||
originalPrice: '5999',
|
||||
image: 'https://via.placeholder.com/200x200/4285F4/ffffff?text=iPhone13',
|
||||
category: '电子产品',
|
||||
status: 'selling', // selling: 在售, sold: 已售出, off: 已下架
|
||||
publishTime: '2024-04-15 10:30',
|
||||
views: 156,
|
||||
likes: 23,
|
||||
comments: 8
|
||||
},
|
||||
{
|
||||
id: 'p2',
|
||||
name: 'Java编程思想 第4版 九成新',
|
||||
price: '35',
|
||||
originalPrice: '108',
|
||||
image: 'https://via.placeholder.com/200x200/34A853/ffffff?text=Java',
|
||||
category: '图书文具',
|
||||
status: 'selling',
|
||||
publishTime: '2024-04-14 16:45',
|
||||
views: 89,
|
||||
likes: 12,
|
||||
comments: 5
|
||||
},
|
||||
{
|
||||
id: 'p3',
|
||||
name: '耐克运动鞋 Air Max 270',
|
||||
price: '180',
|
||||
originalPrice: '899',
|
||||
image: 'https://via.placeholder.com/200x200/EA4335/ffffff?text=运动鞋',
|
||||
category: '服装鞋帽',
|
||||
status: 'sold',
|
||||
publishTime: '2024-04-12 09:15',
|
||||
views: 210,
|
||||
likes: 35,
|
||||
comments: 12
|
||||
},
|
||||
{
|
||||
id: 'p4',
|
||||
name: '戴尔笔记本电脑 XPS 13',
|
||||
price: '3200',
|
||||
originalPrice: '9999',
|
||||
image: 'https://via.placeholder.com/200x200/FBBC05/ffffff?text=笔记本',
|
||||
category: '电子产品',
|
||||
status: 'selling',
|
||||
publishTime: '2024-04-10 14:20',
|
||||
views: 178,
|
||||
likes: 28,
|
||||
comments: 9
|
||||
},
|
||||
{
|
||||
id: 'p5',
|
||||
name: '瑜伽垫 加厚加宽 蓝色',
|
||||
price: '68',
|
||||
originalPrice: '158',
|
||||
image: 'https://via.placeholder.com/200x200/4285F4/ffffff?text=瑜伽垫',
|
||||
category: '运动户外',
|
||||
status: 'off',
|
||||
publishTime: '2024-04-08 11:30',
|
||||
views: 67,
|
||||
likes: 9,
|
||||
comments: 3
|
||||
},
|
||||
{
|
||||
id: 'p6',
|
||||
name: 'SK-II神仙水 75ml',
|
||||
price: '380',
|
||||
originalPrice: '590',
|
||||
image: 'https://via.placeholder.com/200x200/FF6B9D/ffffff?text=神仙水',
|
||||
category: '美妆个护',
|
||||
status: 'selling',
|
||||
publishTime: '2024-04-05 15:45',
|
||||
views: 234,
|
||||
likes: 42,
|
||||
comments: 18
|
||||
}
|
||||
];
|
||||
|
||||
this.setData({
|
||||
products: mockProducts,
|
||||
filteredProducts: mockProducts,
|
||||
isLoading: false,
|
||||
hasMore: false // 模拟没有更多数据
|
||||
});
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换商品分类
|
||||
*/
|
||||
onCategoryChange(e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
this.setData({
|
||||
selectedCategory: index,
|
||||
currentPage: 1
|
||||
});
|
||||
this.filterProducts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换商品状态筛选
|
||||
*/
|
||||
onStatusChange(e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
this.setData({
|
||||
selectedStatus: index,
|
||||
currentPage: 1
|
||||
});
|
||||
this.filterProducts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换排序方式
|
||||
*/
|
||||
onSortChange(e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
this.setData({
|
||||
selectedSort: index
|
||||
});
|
||||
this.filterProducts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据筛选条件过滤商品
|
||||
*/
|
||||
filterProducts() {
|
||||
let filtered = [...this.data.products];
|
||||
|
||||
// 按分类筛选
|
||||
if (this.data.selectedCategory !== 0) {
|
||||
const category = this.data.categories[this.data.selectedCategory];
|
||||
filtered = filtered.filter(item => item.category === category);
|
||||
}
|
||||
|
||||
// 按状态筛选
|
||||
if (this.data.selectedStatus !== 0) {
|
||||
const statusMap = {
|
||||
1: 'selling',
|
||||
2: 'sold',
|
||||
3: 'off'
|
||||
};
|
||||
const status = statusMap[this.data.selectedStatus];
|
||||
filtered = filtered.filter(item => item.status === status);
|
||||
}
|
||||
|
||||
// 排序
|
||||
switch (this.data.selectedSort) {
|
||||
case 1: // 发布时间
|
||||
filtered.sort((a, b) => new Date(b.publishTime) - new Date(a.publishTime));
|
||||
break;
|
||||
case 2: // 价格从低到高
|
||||
filtered.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
|
||||
break;
|
||||
case 3: // 价格从高到低
|
||||
filtered.sort((a, b) => parseFloat(b.price) - parseFloat(a.price));
|
||||
break;
|
||||
default: // 默认排序
|
||||
// 保持原顺序
|
||||
break;
|
||||
}
|
||||
|
||||
this.setData({
|
||||
filteredProducts: filtered
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看商品详情
|
||||
*/
|
||||
onProductDetail(e) {
|
||||
const productId = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/product-detail/product-detail?id=${productId}`
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 下架商品
|
||||
*/
|
||||
onOffShelf(e) {
|
||||
const productId = e.currentTarget.dataset.id;
|
||||
|
||||
wx.showModal({
|
||||
title: '确认下架',
|
||||
content: '确定要下架该商品吗?下架后可重新上架。',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 更新商品状态
|
||||
const updatedProducts = this.data.products.map(item => {
|
||||
if (item.id === productId && item.status === 'selling') {
|
||||
return { ...item, status: 'off' };
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
this.setData({
|
||||
products: updatedProducts
|
||||
});
|
||||
this.filterProducts();
|
||||
|
||||
wx.showToast({
|
||||
title: '商品已下架',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重新上架商品
|
||||
*/
|
||||
onReShelf(e) {
|
||||
const productId = e.currentTarget.dataset.id;
|
||||
|
||||
wx.showModal({
|
||||
title: '重新上架',
|
||||
content: '确定要重新上架该商品吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 更新商品状态
|
||||
const updatedProducts = this.data.products.map(item => {
|
||||
if (item.id === productId && item.status === 'off') {
|
||||
return { ...item, status: 'selling', publishTime: new Date().toLocaleString('zh-CN') };
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
this.setData({
|
||||
products: updatedProducts
|
||||
});
|
||||
this.filterProducts();
|
||||
|
||||
wx.showToast({
|
||||
title: '商品已重新上架',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑商品
|
||||
*/
|
||||
onEditProduct(e) {
|
||||
const productId = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/publish/publish?mode=edit&id=${productId}`
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
*/
|
||||
onDeleteProduct(e) {
|
||||
const productId = e.currentTarget.dataset.id;
|
||||
|
||||
wx.showModal({
|
||||
title: '确认删除',
|
||||
content: '确定要删除该商品吗?删除后无法恢复。',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 删除商品
|
||||
const updatedProducts = this.data.products.filter(item => item.id !== productId);
|
||||
|
||||
this.setData({
|
||||
products: updatedProducts
|
||||
});
|
||||
this.filterProducts();
|
||||
|
||||
wx.showToast({
|
||||
title: '商品已删除',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载更多
|
||||
*/
|
||||
onReachBottom() {
|
||||
if (this.data.hasMore && !this.data.isLoading) {
|
||||
// 实际项目中这里应该请求下一页数据
|
||||
wx.showToast({
|
||||
title: '没有更多数据了',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 下拉刷新
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
this.loadMyProducts();
|
||||
wx.stopPullDownRefresh();
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回上一页
|
||||
*/
|
||||
onBack() {
|
||||
wx.navigateBack();
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,130 @@
|
||||
<!--pages/myProducts/myProducts.wxml-->
|
||||
<view class="page-container">
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view wx:if="{{isLoading}}" class="loading-container">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 错误状态 -->
|
||||
<view wx:elif="{{error}}" class="error-container">
|
||||
<text class="error-icon">⚠</text>
|
||||
<text class="error-text">{{error}}</text>
|
||||
<button class="retry-btn" bindtap="loadMyProducts">重新加载</button>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表内容 -->
|
||||
<view wx:else class="content">
|
||||
<!-- 分类筛选 -->
|
||||
<scroll-view class="category-scroll" scroll-x enable-flex>
|
||||
<view class="category-item {{selectedCategory === index ? 'selected' : ''}}" wx:for="{{categories}}" wx:key="index" data-index="{{index}}" bindtap="onCategoryChange">
|
||||
<text>{{item}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 状态筛选和排序 -->
|
||||
<view class="filter-section">
|
||||
<view class="filter-group">
|
||||
<text class="filter-label">状态:</text>
|
||||
<view class="filter-options">
|
||||
<view class="filter-item {{selectedStatus === index ? 'selected' : ''}}" wx:for="{{statusFilter}}" wx:key="index" data-index="{{index}}" bindtap="onStatusChange">
|
||||
<text>{{item}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="sort-group">
|
||||
<text class="filter-label">排序:</text>
|
||||
<view class="filter-options">
|
||||
<view class="filter-item {{selectedSort === index ? 'selected' : ''}}" wx:for="{{sortOptions}}" wx:key="index" data-index="{{index}}" bindtap="onSortChange">
|
||||
<text>{{item}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<view class="product-list">
|
||||
<view wx:if="{{filteredProducts.length === 0}}" class="empty-state">
|
||||
<image class="empty-image" src="/images/empty.png" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无商品</text>
|
||||
<button class="publish-btn" bindtap="onPublish">去发布商品</button>
|
||||
</view>
|
||||
|
||||
<view wx:else class="product-items">
|
||||
<view class="product-item" wx:for="{{filteredProducts}}" wx:key="id">
|
||||
<!-- 商品基本信息 -->
|
||||
<view class="product-info" bindtap="onProductDetail" data-id="{{item.id}}">
|
||||
<!-- 商品图片 -->
|
||||
<view class="product-image-container">
|
||||
<image class="product-image" src="{{item.image}}" mode="aspectFill"></image>
|
||||
<view class="product-status" wx:if="{{item.status === 'sold'}}">
|
||||
<text>已售出</text>
|
||||
</view>
|
||||
<view class="product-status off" wx:if="{{item.status === 'off'}}">
|
||||
<text>已下架</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品详情 -->
|
||||
<view class="product-details">
|
||||
<view class="product-title">
|
||||
<text>{{item.name}}</text>
|
||||
</view>
|
||||
|
||||
<view class="product-meta">
|
||||
<text class="product-category">{{item.category}}</text>
|
||||
<text class="publish-time">{{item.publishTime}}</text>
|
||||
</view>
|
||||
|
||||
<view class="product-stats">
|
||||
<view class="stat-item">
|
||||
<text class="stat-icon">👁</text>
|
||||
<text class="stat-text">{{item.views}}</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-icon">❤️</text>
|
||||
<text class="stat-text">{{item.likes}}</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-icon">💬</text>
|
||||
<text class="stat-text">{{item.comments}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 价格信息 -->
|
||||
<view class="price-info">
|
||||
<text class="current-price">¥{{item.price}}</text>
|
||||
<text class="original-price" wx:if="{{item.originalPrice}}">¥{{item.originalPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<!-- 在售商品的操作 -->
|
||||
<view wx:if="{{item.status === 'selling'}}">
|
||||
<button class="action-btn edit-btn" bindtap="onEditProduct" data-id="{{item.id}}">编辑</button>
|
||||
<button class="action-btn off-btn" bindtap="onOffShelf" data-id="{{item.id}}">下架</button>
|
||||
<button class="action-btn delete-btn" bindtap="onDeleteProduct" data-id="{{item.id}}">删除</button>
|
||||
</view>
|
||||
|
||||
<!-- 已售出商品的操作 -->
|
||||
<view wx:elif="{{item.status === 'sold'}}">
|
||||
<button class="action-btn view-btn" bindtap="onProductDetail" data-id="{{item.id}}">查看详情</button>
|
||||
<button class="action-btn delete-btn" bindtap="onDeleteProduct" data-id="{{item.id}}">删除</button>
|
||||
</view>
|
||||
|
||||
<!-- 已下架商品的操作 -->
|
||||
<view wx:else>
|
||||
<button class="action-btn edit-btn" bindtap="onEditProduct" data-id="{{item.id}}">编辑</button>
|
||||
<button class="action-btn on-btn" bindtap="onReShelf" data-id="{{item.id}}">重新上架</button>
|
||||
<button class="action-btn delete-btn" bindtap="onDeleteProduct" data-id="{{item.id}}">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,466 @@
|
||||
/* pages/myProducts/myProducts.wxss */
|
||||
/* 全局样式 - 与小程序保持一致 */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 头部样式 - 使用小程序主色调 */
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 88rpx;
|
||||
padding: 0 30rpx;
|
||||
background-color: #4285F4;
|
||||
color: white;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
width: 88rpx;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.content {
|
||||
padding-top: 88rpx;
|
||||
}
|
||||
|
||||
/* 分类滚动 - 与main页面风格一致 */
|
||||
.category-scroll {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
background-color: white;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
display: inline-flex;
|
||||
padding: 0 30rpx;
|
||||
height: 60rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.category-item.selected {
|
||||
color: #4285F4;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.category-item.selected::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 30%;
|
||||
width: 40%;
|
||||
height: 6rpx;
|
||||
background-color: #4285F4;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
/* 筛选区域 - 卡片式设计 */
|
||||
.filter-section {
|
||||
background-color: white;
|
||||
padding: 20rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
border-radius: 0 0 10rpx 10rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.filter-group,
|
||||
.sort-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.sort-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
width: 80rpx;
|
||||
}
|
||||
|
||||
.filter-options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
padding: 8rpx 20rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
transition: all 0.3s ease;
|
||||
border: 1rpx solid #e9ecef;
|
||||
}
|
||||
|
||||
.filter-item.selected {
|
||||
background-color: #4285F4;
|
||||
color: white;
|
||||
border-color: #4285F4;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60vh;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 8rpx solid #f3f3f3;
|
||||
border-top: 8rpx solid #4285F4;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 错误状态 */
|
||||
.error-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60vh;
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 20rpx;
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
background-color: #4285F4;
|
||||
color: white;
|
||||
font-size: 28rpx;
|
||||
padding: 0 40rpx;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(66, 133, 244, 0.3);
|
||||
}
|
||||
|
||||
.retry-btn:active {
|
||||
transform: scale(0.95);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60vh;
|
||||
background-color: white;
|
||||
margin: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
padding: 40rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.empty-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 30rpx;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
background-color: #4285F4;
|
||||
color: white;
|
||||
font-size: 28rpx;
|
||||
padding: 0 60rpx;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(66, 133, 244, 0.3);
|
||||
}
|
||||
|
||||
.publish-btn:active {
|
||||
transform: scale(0.95);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 商品列表 */
|
||||
.product-list {
|
||||
padding: 0 20rpx 20rpx;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
background-color: white;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.product-info {
|
||||
display: flex;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.product-image-container {
|
||||
position: relative;
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.product-status {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: white;
|
||||
padding: 8rpx 16rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 8rpx 0 8rpx 0;
|
||||
}
|
||||
|
||||
.product-status.off {
|
||||
background-color: rgba(150, 150, 150, 0.6);
|
||||
}
|
||||
|
||||
.product-details {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 44rpx;
|
||||
margin-bottom: 10rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.product-stats {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.price-info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.current-price {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #ff6b81;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
/* 操作按钮 - 优化样式,确保更小并在同一行排列 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
padding: 12rpx 15rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 0 0 auto; /* 不自动拉伸,保持按钮固定大小 */
|
||||
margin: 0 6rpx;
|
||||
font-size: 22rpx; /* 进一步减小字体大小 */
|
||||
line-height: 50rpx; /* 进一步减小按钮高度 */
|
||||
padding: 0 25rpx; /* 添加水平内边距,确保文字不会太拥挤 */
|
||||
border-radius: 8rpx;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
||||
border: none;
|
||||
white-space: nowrap; /* 确保按钮文字不会换行 */
|
||||
}
|
||||
|
||||
/* 增加按钮点击效果 */
|
||||
.action-btn:active {
|
||||
transform: scale(0.95);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 保持与小程序整体色彩一致 */
|
||||
.edit-btn {
|
||||
background-color: #4285F4; /* 主色调 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.off-btn {
|
||||
background-color: #ff9800; /* 下架按钮使用橙色 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.on-btn {
|
||||
background-color: #34C759; /* 上架按钮使用绿色 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #ff6b81; /* 删除按钮使用红色,与订单页面一致 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.view-btn {
|
||||
background-color: #2196f3; /* 查看按钮使用蓝色变体 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 响应式调整 - 确保小屏幕上按钮仍能在一行显示 */
|
||||
@media screen and (max-width: 320px) {
|
||||
.filter-options {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
margin-right: 0;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.product-image-container {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
margin-right: 0;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.price-info {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
padding: 8rpx 10rpx;
|
||||
overflow-x: auto; /* 允许在极端情况下水平滚动 */
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
font-size: 20rpx;
|
||||
line-height: 45rpx;
|
||||
margin: 0 4rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 文本样式 - 与app.wxss保持一致 */
|
||||
text {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', SimSun, sans-serif;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "我的订单",
|
||||
"navigationBarBackgroundColor": "#f5f5f5",
|
||||
"navigationBarTextStyle": "black",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundTextStyle": "dark"
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
<!--pages/orders/orders.wxml-->
|
||||
<view class="orders-container">
|
||||
<!-- 订单状态筛选标签 -->
|
||||
<view class="order-tabs">
|
||||
<view class="tab-item {{activeTab === 'all' ? 'active' : ''}}" bindtap="switchTab" data-tab="all">全部</view>
|
||||
<view class="tab-item {{activeTab === 'pending' ? 'active' : ''}}" bindtap="switchTab" data-tab="pending">待付款</view>
|
||||
<view class="tab-item {{activeTab === 'paid' ? 'active' : ''}}" bindtap="switchTab" data-tab="paid">待发货</view>
|
||||
<view class="tab-item {{activeTab === 'shipped' ? 'active' : ''}}" bindtap="switchTab" data-tab="shipped">待收货</view>
|
||||
<view class="tab-item {{activeTab === 'completed' ? 'active' : ''}}" bindtap="switchTab" data-tab="completed">已完成</view>
|
||||
<view class="tab-item {{activeTab === 'cancelled' ? 'active' : ''}}" bindtap="switchTab" data-tab="cancelled">已取消</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<view class="order-list">
|
||||
<!-- 加载状态 -->
|
||||
<view wx:if="{{isLoading}}" class="loading-container">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view wx:elif="{{orders.length === 0 && !isLoading}}" class="empty-container">
|
||||
<image class="empty-icon" src="/images/empty-orders.png" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无订单</text>
|
||||
<text class="empty-subtext">去逛逛,发现心仪商品</text>
|
||||
<button class="go-shopping-btn" bindtap="goShopping">去购物</button>
|
||||
</view>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<block wx:else>
|
||||
<view wx:for="{{orders}}" wx:key="id" class="order-item">
|
||||
<!-- 订单头部 -->
|
||||
<view class="order-header">
|
||||
<view class="order-info">
|
||||
<text class="order-number">订单号:{{item.orderNumber}}</text>
|
||||
<text class="order-time">{{item.orderTime}}</text>
|
||||
</view>
|
||||
<text class="order-status {{item.status}}">{{item.statusText}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 订单商品 -->
|
||||
<view class="order-products">
|
||||
<view wx:for="{{item.products}}" wx:for-item="product" wx:key="productId" class="product-item">
|
||||
<image class="product-image" src="{{product.image || '/images/default-product.png'}}" mode="aspectFit"></image>
|
||||
<view class="product-info">
|
||||
<text class="product-name">{{product.name}}</text>
|
||||
<text class="product-specs">{{product.specs || '规格:标准'}}</text>
|
||||
<view class="product-price-count">
|
||||
<text class="product-price">¥{{product.price}}</text>
|
||||
<text class="product-count">x{{product.count}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单尾部 -->
|
||||
<view class="order-footer">
|
||||
<view class="order-total">
|
||||
<view class="total-info">
|
||||
<text class="total-label">共{{item.totalCount}}件商品</text>
|
||||
</view>
|
||||
<view class="price-container">
|
||||
<text class="total-price-label">合计:</text>
|
||||
<text class="currency-symbol">¥</text>
|
||||
<text class="total-price-value">{{item.totalPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="order-actions">
|
||||
<button wx:if="{{item.status === 'pending'}}" class="action-btn secondary" bindtap="cancelOrder" data-id="{{item.id}}">
|
||||
取消订单
|
||||
</button>
|
||||
<button wx:if="{{item.status === 'pending'}}" class="action-btn primary" bindtap="payOrder" data-id="{{item.id}}">
|
||||
去付款
|
||||
</button>
|
||||
<button wx:if="{{item.status === 'shipped'}}" class="action-btn primary" bindtap="confirmReceipt" data-id="{{item.id}}">
|
||||
确认收货
|
||||
</button>
|
||||
<button wx:if="{{item.status === 'completed' || item.status === 'cancelled'}}" class="action-btn secondary" bindtap="viewOrderDetail" data-id="{{item.id}}">
|
||||
查看详情
|
||||
</button>
|
||||
<button wx:if="{{item.status === 'completed'}}" class="action-btn secondary" bindtap="buyAgain" data-id="{{item.id}}">
|
||||
再次购买
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,351 @@
|
||||
/* pages/orders/orders.wxss *//* 订单页面样式 */
|
||||
.orders-container {
|
||||
padding-bottom: 100rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 订单状态筛选标签 */
|
||||
.order-tabs {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
padding: 0 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.tab-item.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 30%;
|
||||
width: 40%;
|
||||
height: 6rpx;
|
||||
background-color: #667eea;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
/* 订单列表 */
|
||||
.order-list {
|
||||
margin-top: 90rpx;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 100rpx 0;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 6rpx solid #f3f3f3;
|
||||
border-top: 6rpx solid #667eea;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 150rpx 0;
|
||||
background-color: #fff;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin-top: 40rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.empty-subtext {
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.go-shopping-btn {
|
||||
margin-top: 40rpx;
|
||||
background-color: #667eea;
|
||||
color: #fff;
|
||||
border-radius: 40rpx;
|
||||
font-size: 28rpx;
|
||||
padding: 20rpx 60rpx;
|
||||
}
|
||||
|
||||
/* 订单项 */
|
||||
.order-item {
|
||||
background-color: #fff;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 订单头部 */
|
||||
.order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 28rpx 32rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.order-number {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.order-time {
|
||||
font-size: 24rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-status.pending {
|
||||
color: #ff9500;
|
||||
}
|
||||
|
||||
.order-status.paid {
|
||||
color: #5ac8fa;
|
||||
}
|
||||
|
||||
.order-status.shipped {
|
||||
color: #34c759;
|
||||
}
|
||||
|
||||
.order-status.completed {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.order-status.cancelled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 订单商品 */
|
||||
.order-products {
|
||||
padding: 28rpx 32rpx;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
padding: 16rpx 0;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 40rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.product-specs {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.product-price-count {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 28rpx;
|
||||
color: #ff6b81;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.product-count {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 订单尾部 */
|
||||
.order-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx 32rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.order-total {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.total-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.total-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.price-container {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.total-price-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.currency-symbol {
|
||||
font-size: 24rpx;
|
||||
color: #ff6b81;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.total-price-value {
|
||||
font-size: 32rpx;
|
||||
color: #ff6b81;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.order-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 0 32rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 68rpx;
|
||||
border-radius: 34rpx;
|
||||
margin: 0;
|
||||
min-width: 160rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.action-btn.primary {
|
||||
background-color: #667eea;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2rpx 10rpx rgba(102, 126, 234, 0.2);
|
||||
}
|
||||
|
||||
.action-btn.secondary {
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
border: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
/* 按钮点击效果 */
|
||||
.action-btn:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 响应式调整优化 */
|
||||
@media (max-width: 375px) {
|
||||
.product-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.order-footer {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.order-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
min-width: auto;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.action-btn:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "商品详情",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "white",
|
||||
"enablePullDownRefresh": false,
|
||||
"disableScroll": false
|
||||
}
|
||||
|
||||
@ -0,0 +1,142 @@
|
||||
<!--pages/product-detail/product-detail.wxml-->
|
||||
<scroll-view class="scroll-container" scroll-y="true" wx:if="{{!loading}}">
|
||||
<view class="container">
|
||||
<!-- 商品图片轮播 -->
|
||||
<view class="image-section">
|
||||
<swiper
|
||||
class="detail_swiper"
|
||||
autoplay="{{imageUrls.length > 1}}"
|
||||
interval="3000"
|
||||
duration="500"
|
||||
indicator-dots="{{imageUrls.length > 1}}"
|
||||
bindchange="onImageChange"
|
||||
>
|
||||
<block wx:for="{{imageUrls}}" wx:key="{{index}}">
|
||||
<swiper-item>
|
||||
<view class="image-wrapper" bindtap="onPreviewImage" data-index="{{currentImageIndex}}">
|
||||
<image
|
||||
src="{{item}}"
|
||||
mode="widthFix"
|
||||
class="slide-image"
|
||||
binderror="onImageError"
|
||||
data-index="{{index}}"
|
||||
lazy-load="{{false}}"
|
||||
/>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
|
||||
<!-- 如果没有图片,显示占位图 -->
|
||||
<view class="no-image-placeholder" wx:if="{{imageUrls.length === 0 || !imageUrls[0]}}">
|
||||
<text class="placeholder-text">暂无图片</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品状态标签 -->
|
||||
<view class="status-badge" wx:if="{{product.status !== '在售'}}">
|
||||
<text>{{product.status === '已售' ? '已售出' : '已下架'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品基本信息 -->
|
||||
<view class="info-section">
|
||||
<view class="price-row">
|
||||
<view class="price-group">
|
||||
<text class="current-price">¥{{product.salePrice || product.suggestedPrice || 0}}</text>
|
||||
<text class="original-price" wx:if="{{product.originalPrice}}">¥{{product.originalPrice}}</text>
|
||||
</view>
|
||||
<view class="favorite-btn" bindtap="onToggleFavorite">
|
||||
<text class="iconfont" wx:if="{{isFavorite}}">❤️</text>
|
||||
<text class="iconfont" wx:else>🤍</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="product-title">
|
||||
<text>{{product.productName}}</text>
|
||||
</view>
|
||||
|
||||
<view class="product-tags">
|
||||
<text class="tag category-tag">{{product.productCategory}}</text>
|
||||
<text class="tag condition-tag">{{product.conditionText}}</text>
|
||||
<text class="tag score-tag" wx:if="{{product.aiScore && product.aiScore !== '--'}}">⭐ {{product.aiScore}}分</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品详细信息 -->
|
||||
<view class="detail-section">
|
||||
<view class="section-title">商品信息</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">商品描述</text>
|
||||
<text class="detail-value">{{product.productDescription || '暂无描述'}}</text>
|
||||
</view>
|
||||
|
||||
<view class="detail-item" wx:if="{{product.priceRangeText && product.priceRangeText !== '--'}}">
|
||||
<text class="detail-label">价格范围</text>
|
||||
<text class="detail-value">{{product.priceRangeText}}</text>
|
||||
</view>
|
||||
|
||||
<view class="detail-item" wx:if="{{product.analysisReport}}">
|
||||
<text class="detail-label">AI分析报告</text>
|
||||
<text class="detail-value">{{product.analysisReport}}</text>
|
||||
</view>
|
||||
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">交易方式</text>
|
||||
<text class="detail-value">{{product.transactionMethod || '面交'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 卖家信息 -->
|
||||
<view class="seller-section">
|
||||
<view class="section-title">卖家信息</view>
|
||||
<view class="seller-card" bindtap="onContactSeller">
|
||||
<image class="seller-avatar" src="{{product.sellerInfo.avatar}}" mode="aspectFill" />
|
||||
<view class="seller-info">
|
||||
<text class="seller-name">{{product.sellerInfo.name}}</text>
|
||||
<text class="seller-sno" wx:if="{{product.sellerInfo.sno}}">学号:{{product.sellerInfo.sno}}</text>
|
||||
<text class="seller-time">发布于 {{product.publishTime}}</text>
|
||||
</view>
|
||||
<view class="contact-btn">
|
||||
<text>联系</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar" wx:if="{{!loading}}">
|
||||
<view class="bar-left">
|
||||
<view class="icon-btn" bindtap="onViewCart">
|
||||
<text class="icon">🛒</text>
|
||||
<text class="badge" wx:if="{{cartCount > 0}}">{{cartCount}}</text>
|
||||
</view>
|
||||
<view class="icon-btn" bindtap="onToggleFavorite">
|
||||
<text class="icon">{{isFavorite ? '❤️' : '🤍'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bar-right">
|
||||
<button
|
||||
class="cart-btn {{inCart ? 'added' : ''}}"
|
||||
bindtap="onAddToCart"
|
||||
disabled="{{product.status !== '在售' || inCart}}"
|
||||
>
|
||||
{{inCart ? '已在购物车' : '加入购物车'}}
|
||||
</button>
|
||||
<button
|
||||
class="buy-btn"
|
||||
bindtap="onBuyNow"
|
||||
disabled="{{product.status !== '在售'}}"
|
||||
>
|
||||
立即购买
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-container" wx:if="{{loading}}">
|
||||
<view class="loading-content">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -0,0 +1,511 @@
|
||||
/* pages/product-detail/product-detail.wxss */
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
height: calc(100vh - env(safe-area-inset-top));
|
||||
padding-top: 0;
|
||||
padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
padding-bottom: 40rpx;
|
||||
background: linear-gradient(to bottom, #f8f9fa 0%, #f5f5f5 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 图片轮播区域 */
|
||||
.image-section {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: 500rpx;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail_swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.swiper-item {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: 500rpx;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
min-height: 500rpx;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
background-color: #f8f9fa;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slide-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
min-height: 500rpx;
|
||||
}
|
||||
|
||||
.no-image-placeholder {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
position: absolute;
|
||||
top: 30rpx;
|
||||
right: 30rpx;
|
||||
background: linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.5) 100%);
|
||||
backdrop-filter: blur(10rpx);
|
||||
color: #fff;
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 商品基本信息 */
|
||||
.info-section {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: linear-gradient(to bottom, #fff 0%, #fafafa 100%);
|
||||
padding: 40rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.price-group {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.current-price {
|
||||
font-size: 56rpx;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, #FF6B6B 0%, #FF4444 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
letter-spacing: -1rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 28rpx;
|
||||
color: #bbb;
|
||||
text-decoration: line-through;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.favorite-btn {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #ffeef0 0%, #ffe0e6 100%);
|
||||
border-radius: 50%;
|
||||
font-size: 40rpx;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.favorite-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 24rpx;
|
||||
letter-spacing: 0.5rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.product-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.tag:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.category-tag {
|
||||
background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
|
||||
color: #1565C0;
|
||||
border: 1rpx solid rgba(21, 101, 192, 0.2);
|
||||
}
|
||||
|
||||
.condition-tag {
|
||||
background: linear-gradient(135deg, #FFF3E0 0%, #FFE0B2 100%);
|
||||
color: #E65100;
|
||||
border: 1rpx solid rgba(230, 81, 0, 0.2);
|
||||
}
|
||||
|
||||
.score-tag {
|
||||
background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
|
||||
color: #6A1B9A;
|
||||
border: 1rpx solid rgba(106, 27, 154, 0.2);
|
||||
}
|
||||
|
||||
/* 详细信息区域 */
|
||||
.detail-section {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
padding: 40rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 30rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2rpx;
|
||||
left: 0;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(90deg, #4285F4 0%, #764ba2 100%);
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 30rpx;
|
||||
padding: 20rpx;
|
||||
background: #fafafa;
|
||||
border-radius: 16rpx;
|
||||
transition: background-color 0.2s ease;
|
||||
min-height: 80rpx;
|
||||
}
|
||||
|
||||
.detail-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 26rpx;
|
||||
color: #888;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5rpx;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* 卖家信息区域 */
|
||||
.seller-section {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
padding: 40rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.seller-card {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f4ff 100%);
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(66, 133, 244, 0.1);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
min-height: 140rpx;
|
||||
}
|
||||
|
||||
.seller-card:active {
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 6rpx 20rpx rgba(66, 133, 244, 0.15);
|
||||
}
|
||||
|
||||
.seller-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 24rpx;
|
||||
border: 3rpx solid #fff;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.seller-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.seller-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.seller-sno {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.seller-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.contact-btn {
|
||||
flex-shrink: 0;
|
||||
padding: 14rpx 28rpx;
|
||||
background: linear-gradient(135deg, #4285F4 0%, #667eea 100%);
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4rpx 12rpx rgba(66, 133, 244, 0.3);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.contact-btn:active {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 2rpx 8rpx rgba(66, 133, 244, 0.25);
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(to top, #fff 0%, #fafafa 100%);
|
||||
padding: 24rpx 30rpx;
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
z-index: 100;
|
||||
backdrop-filter: blur(20rpx);
|
||||
height: calc(136rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bar-left {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
font-size: 44rpx;
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.icon-btn:active {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -4rpx;
|
||||
right: -4rpx;
|
||||
background: linear-gradient(135deg, #FF6B6B 0%, #FF4444 100%);
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
padding: 4rpx 10rpx;
|
||||
border-radius: 20rpx;
|
||||
min-width: 32rpx;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
box-shadow: 0 2rpx 8rpx rgba(255, 68, 68, 0.4);
|
||||
border: 2rpx solid #fff;
|
||||
}
|
||||
|
||||
.bar-right {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cart-btn,
|
||||
.buy-btn {
|
||||
padding: 20rpx 32rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
flex: 1;
|
||||
max-width: 240rpx;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.cart-btn {
|
||||
background: linear-gradient(135deg, #fff 0%, #f8f9fa 100%);
|
||||
color: #4285F4;
|
||||
border: 2rpx solid #4285F4;
|
||||
box-shadow: 0 4rpx 12rpx rgba(66, 133, 244, 0.2);
|
||||
}
|
||||
|
||||
.cart-btn:active {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 2rpx 8rpx rgba(66, 133, 244, 0.15);
|
||||
}
|
||||
|
||||
.cart-btn.added {
|
||||
background: linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%);
|
||||
color: #999;
|
||||
border-color: #d0d0d0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.buy-btn {
|
||||
background: linear-gradient(135deg, #4285F4 0%, #667eea 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 4rpx 16rpx rgba(66, 133, 244, 0.4);
|
||||
}
|
||||
|
||||
.buy-btn:active {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 2rpx 10rpx rgba(66, 133, 244, 0.3);
|
||||
}
|
||||
|
||||
.buy-btn[disabled],
|
||||
.cart-btn[disabled] {
|
||||
background: linear-gradient(135deg, #e0e0e0 0%, #d0d0d0 100%);
|
||||
color: #bbb;
|
||||
border-color: #d0d0d0;
|
||||
box-shadow: none;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background: linear-gradient(to bottom, #f8f9fa 0%, #f5f5f5 100%);
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-top: 20rpx;
|
||||
animation: pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "求购列表",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
<!--pages/wanted-list/wanted-list.wxml-->
|
||||
<view class="page-container">
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-section">
|
||||
<view class="search-bar">
|
||||
<image class="search-icon" src="/images/search.png" mode="aspectFit"></image>
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="搜索求购信息"
|
||||
value="{{searchText}}"
|
||||
bindinput="onSearchInput"
|
||||
bindconfirm="onSearch"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 求购列表 -->
|
||||
<scroll-view
|
||||
class="wanted-list-container"
|
||||
scroll-y="true"
|
||||
refresher-enabled="{{true}}"
|
||||
refresher-triggered="{{refreshing}}"
|
||||
bindrefresherrefresh="onRefresh"
|
||||
bindscrolltolower="onLoadMore"
|
||||
>
|
||||
<view class="wanted-list">
|
||||
<view
|
||||
class="wanted-card"
|
||||
wx:for="{{wantedList}}"
|
||||
wx:key="_id"
|
||||
bindtap="onWantedTap"
|
||||
data-id="{{item._id}}"
|
||||
>
|
||||
<view class="card-header">
|
||||
<text class="wanted-title">{{item.productName}}</text>
|
||||
<text class="wanted-category">{{item.productCategory}}</text>
|
||||
</view>
|
||||
|
||||
<text class="wanted-description" wx:if="{{item.description}}">{{item.description}}</text>
|
||||
|
||||
<view class="wanted-details">
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">预算价格:</text>
|
||||
<text class="detail-value price">¥{{item.expectedPrice || 0}}</text>
|
||||
</view>
|
||||
<view class="detail-row" wx:if="{{item.conditionLevel}}">
|
||||
<text class="detail-label">成色要求:</text>
|
||||
<text class="detail-value">{{item.conditionLevel}}</text>
|
||||
</view>
|
||||
<view class="detail-row" wx:if="{{item.expectedBrand}}">
|
||||
<text class="detail-label">期望品牌:</text>
|
||||
<text class="detail-value">{{item.expectedBrand}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-footer">
|
||||
<view class="footer-left">
|
||||
<text class="wanted-time">{{item.formattedTime}}</text>
|
||||
<text class="wanted-views">👁 {{item.viewCount || 0}}</text>
|
||||
</view>
|
||||
<view class="contact-info">
|
||||
<text class="contact-name">{{item.contactName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" wx:if="{{wantedList.length === 0 && !loading}}">
|
||||
<text class="empty-text">暂无求购信息</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view class="load-more" wx:if="{{hasMore && !loading}}">
|
||||
<text>加载更多...</text>
|
||||
</view>
|
||||
|
||||
<!-- 没有更多 -->
|
||||
<view class="no-more" wx:if="{{!hasMore && wantedList.length > 0}}">
|
||||
<text>没有更多了</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<view class="loading-container" wx:if="{{loading && wantedList.length === 0}}">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -0,0 +1,192 @@
|
||||
/* pages/wanted-list/wanted-list.wxss */
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(to bottom, #f8f9fa 0%, #f5f5f5 100%);
|
||||
}
|
||||
|
||||
.search-section {
|
||||
background: white;
|
||||
padding: 20rpx 30rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #f5f5f5;
|
||||
border-radius: 50rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.wanted-list-container {
|
||||
height: calc(100vh - 120rpx);
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.wanted-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.wanted-card {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.wanted-card:active {
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.wanted-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.wanted-category {
|
||||
font-size: 24rpx;
|
||||
color: #4285F4;
|
||||
background: rgba(66, 133, 244, 0.1);
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.wanted-description {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wanted-details {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.detail-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.detail-value.price {
|
||||
color: #FF6B35;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: 20rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.footer-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.wanted-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.wanted-views {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
font-size: 24rpx;
|
||||
color: #4285F4;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 100rpx 20rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
text-align: center;
|
||||
padding: 30rpx;
|
||||
color: #999;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 30rpx;
|
||||
color: #ccc;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 100rpx 20rpx;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||