You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

511 lines
11 KiB

<template>
<view class="container">
<!-- 导航栏 -->
<view class="nav-bar">
<text class="nav-back" @click="goBack"></text>
<text class="nav-title">商品列表</text>
<text class="nav-right"></text>
</view>
<!-- 搜索栏 -->
<view class="search-section">
<view class="search-box">
<text class="search-icon">🔍</text>
<input
class="search-input"
v-model="searchKeyword"
placeholder="搜索商品名称或型号"
@input="onSearch"
/>
<text class="clear-btn" v-if="searchKeyword" @click="clearSearch">×</text>
</view>
</view>
<!-- 筛选栏 -->
<view class="filter-section">
<view class="filter-item" @click="showCategoryFilter">
<text class="filter-text">{{ selectedCategory || '全部分类' }}</text>
<text class="filter-arrow">▼</text>
</view>
<view class="filter-item" @click="showSortFilter">
<text class="filter-text">{{ getSortText() }}</text>
<text class="filter-arrow">▼</text>
</view>
</view>
<!-- 商品列表 -->
<view class="product-section">
<view class="product-list">
<view
class="product-item"
v-for="(item, index) in filteredProducts"
:key="index"
@click="viewProduct(item)"
>
<image :src="item.image" class="product-image" mode="aspectFill" />
<view class="product-info">
<text class="product-name">{{ item.name }}</text>
<text class="product-model">型号:{{ item.model }}</text>
<text class="product-category">分类:{{ item.category }}</text>
<view class="product-footer">
<text class="product-price">¥{{ item.price }}</text>
<text class="product-stock">库存:{{ item.stock }}</text>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="filteredProducts.length === 0">
<image src="/static/logo.png" class="empty-icon" />
<text class="empty-text">暂无商品数据</text>
<text class="empty-desc">请尝试调整搜索条件</text>
</view>
</view>
<!-- 分类筛选弹窗 -->
<view class="filter-modal" v-if="showCategoryModal" @click="hideCategoryFilter">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">选择分类</text>
<text class="modal-close" @click="hideCategoryFilter">×</text>
</view>
<view class="modal-body">
<view
class="category-item"
v-for="(category, index) in categories"
:key="index"
@click="selectCategory(category)"
:class="{ 'selected': selectedCategory === category }"
>
<text class="category-text">{{ category }}</text>
<text class="category-check" v-if="selectedCategory === category">✓</text>
</view>
</view>
</view>
</view>
<!-- 排序筛选弹窗 -->
<view class="filter-modal" v-if="showSortModal" @click="hideSortFilter">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">排序方式</text>
<text class="modal-close" @click="hideSortFilter">×</text>
</view>
<view class="modal-body">
<view
class="sort-item"
v-for="(sort, index) in sortOptions"
:key="index"
@click="selectSort(sort.value)"
:class="{ 'selected': selectedSort === sort.value }"
>
<text class="sort-text">{{ sort.label }}</text>
<text class="sort-check" v-if="selectedSort === sort.value"></text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
searchKeyword: '',
selectedCategory: '',
selectedSort: 'default',
showCategoryModal: false,
showSortModal: false,
categories: ['全部分类', '电表设备', '配电箱', '电线电缆', '开关插座', '照明设备'],
sortOptions: [
{ label: '默认排序', value: 'default' },
{ label: '价格从低到高', value: 'price_asc' },
{ label: '价格从高到低', value: 'price_desc' },
{ label: '库存从多到少', value: 'stock_desc' }
],
productList: [
{
id: 1,
name: '智能电表DT862',
model: 'DT862-4',
category: '电表设备',
price: 156.00,
stock: 50,
image: '/static/logo.png'
},
{
id: 2,
name: '三相配电箱',
model: 'PZ30-12',
category: '配电箱',
price: 280.00,
stock: 25,
image: '/static/logo.png'
},
{
id: 3,
name: 'BV电线2.5平方',
model: 'BV-2.5',
category: '电线电缆',
price: 3.50,
stock: 1000,
image: '/static/logo.png'
},
{
id: 4,
name: '墙壁开关插座',
model: 'WS-86',
category: '开关插座',
price: 25.00,
stock: 200,
image: '/static/logo.png'
},
{
id: 5,
name: 'LED吸顶灯',
model: 'LED-24W',
category: '照明设备',
price: 89.00,
stock: 80,
image: '/static/logo.png'
}
]
}
},
computed: {
filteredProducts() {
let products = [...this.productList]
// 分类筛选
if (this.selectedCategory && this.selectedCategory !== '全部分类') {
products = products.filter(item => item.category === this.selectedCategory)
}
// 搜索筛选
if (this.searchKeyword) {
const keyword = this.searchKeyword.toLowerCase()
products = products.filter(item =>
item.name.toLowerCase().includes(keyword) ||
item.model.toLowerCase().includes(keyword)
)
}
// 排序
switch (this.selectedSort) {
case 'price_asc':
products.sort((a, b) => a.price - b.price)
break
case 'price_desc':
products.sort((a, b) => b.price - a.price)
break
case 'stock_desc':
products.sort((a, b) => b.stock - a.stock)
break
}
return products
}
},
methods: {
onSearch() {
// 搜索逻辑已在computed中处理
},
clearSearch() {
this.searchKeyword = ''
},
showCategoryFilter() {
this.showCategoryModal = true
},
hideCategoryFilter() {
this.showCategoryModal = false
},
selectCategory(category) {
this.selectedCategory = category === '全部分类' ? '' : category
this.hideCategoryFilter()
},
showSortFilter() {
this.showSortModal = true
},
hideSortFilter() {
this.showSortModal = false
},
selectSort(sortValue) {
this.selectedSort = sortValue
this.hideSortFilter()
},
getSortText() {
const option = this.sortOptions.find(item => item.value === this.selectedSort)
return option ? option.label : '默认排序'
},
viewProduct(item) {
uni.showToast({
title: `查看商品:${item.name}`,
icon: 'none'
})
},
goBack() {
uni.navigateBack()
}
}
}
</script>
<style scoped>
.container {
background-color: #f5f5f5;
min-height: 100vh;
}
.nav-bar {
background-color: #007aff;
color: white;
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15px;
}
.nav-back {
font-size: 24px;
font-weight: bold;
width: 60px;
}
.nav-title {
font-size: 18px;
font-weight: bold;
flex: 1;
text-align: center;
}
.nav-right {
width: 60px;
}
.search-section {
padding: 15px;
background-color: white;
}
.search-box {
display: flex;
align-items: center;
background-color: #f5f5f5;
border-radius: 20px;
padding: 8px 15px;
}
.search-icon {
margin-right: 10px;
color: #999;
}
.search-input {
flex: 1;
font-size: 14px;
color: #333;
}
.clear-btn {
color: #999;
font-size: 18px;
margin-left: 10px;
}
.filter-section {
display: flex;
background-color: white;
border-top: 1px solid #f0f0f0;
padding: 0 15px;
}
.filter-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 12px 0;
border-right: 1px solid #f0f0f0;
}
.filter-item:last-child {
border-right: none;
}
.filter-text {
font-size: 14px;
color: #333;
margin-right: 5px;
}
.filter-arrow {
font-size: 10px;
color: #999;
}
.product-section {
padding: 15px;
}
.product-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.product-item {
background-color: white;
border-radius: 10px;
padding: 15px;
display: flex;
align-items: center;
}
.product-image {
width: 80px;
height: 80px;
border-radius: 8px;
margin-right: 15px;
background-color: #f0f0f0;
}
.product-info {
flex: 1;
}
.product-name {
font-size: 16px;
font-weight: bold;
color: #333;
display: block;
margin-bottom: 5px;
}
.product-model {
font-size: 12px;
color: #666;
display: block;
margin-bottom: 3px;
}
.product-category {
font-size: 12px;
color: #666;
display: block;
margin-bottom: 8px;
}
.product-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.product-price {
font-size: 16px;
font-weight: bold;
color: #ff4757;
}
.product-stock {
font-size: 12px;
color: #999;
}
.empty-state {
text-align: center;
padding: 60px 20px;
}
.empty-icon {
width: 80px;
height: 80px;
opacity: 0.3;
margin-bottom: 20px;
}
.empty-text {
font-size: 16px;
color: #999;
display: block;
margin-bottom: 10px;
}
.empty-desc {
font-size: 14px;
color: #ccc;
}
.filter-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
z-index: 1000;
}
.modal-content {
background-color: white;
width: 100%;
border-radius: 15px 15px 0 0;
max-height: 60vh;
overflow: hidden;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 20px;
border-bottom: 1px solid #f0f0f0;
}
.modal-title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.modal-close {
font-size: 20px;
color: #999;
}
.modal-body {
max-height: 40vh;
overflow-y: auto;
}
.category-item, .sort-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 20px;
border-bottom: 1px solid #f8f8f8;
}
.category-item:last-child, .sort-item:last-child {
border-bottom: none;
}
.category-item.selected, .sort-item.selected {
background-color: #f0f8ff;
}
.category-text, .sort-text {
font-size: 14px;
color: #333;
}
.category-check, .sort-check {
color: #007aff;
font-size: 16px;
}
</style>