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