feat: 点单搜索

This commit is contained in:
Kroytz committed 2026-07-18 23:36:09 +08:00
1 parent 81397fc50a
commit 3f14ef5007
1 file changed
+23 -9
+23 -9
View File
@@ -62,7 +62,7 @@
<scroll-view class="menus" :scroll-into-view="menuScrollIntoView" scroll-with-animation scroll-y>
<view class="wrapper">
<view class="menu" :id="`menu-${item.id}`" :class="{'current': item.id === currentCateId}"
v-for="(item, index) in goods" :key="index" @tap="handleMenuTap(item.id)">
v-for="(item, index) in filteredGoods" :key="index" @tap="handleMenuTap(item.id)">
<text>{{ item.name }}</text>
<view class="dot" v-show="menuCartNum(item.id)">{{ menuCartNum(item.id) }}</view>
</view>
@@ -74,7 +74,7 @@
<view class="wrapper">
<view class="list">
<!-- category begin -->
<view class="category" v-for="(item, index) in goods" :key="index"
<view class="category" v-for="(item, index) in filteredGoods" :key="index"
:id="`cate-${item.id}`">
<view class="title">
<text>{{ item.name }}</text>
@@ -82,7 +82,7 @@
</view>
<view class="items">
<!-- 商品 begin -->
<view class="good" v-for="(good, key) in item.goodsList" :key="key" v-show="isGoodVisible(good)"
<view class="good" v-for="(good, key) in item.goodsList" :key="key"
:class="{'background-grey': good.stock <= 0}">
<image mode="aspectFill" :src="good.image" class="image"
@tap="showGoodDetailModal(item, good)"></image>
@@ -118,6 +118,7 @@
</view>
</view>
<!-- category end -->
<uv-empty v-if="keyword.trim() && !filteredGoods.length" mode="search"></uv-empty>
<view class="bottom-spacer"></view>
</view>
</view>
@@ -248,7 +249,8 @@
import {
ref,
computed,
nextTick
nextTick,
watch
} from 'vue'
import { useMainStore } from '@/store/store'
import { storeToRefs } from 'pinia'
@@ -318,8 +320,20 @@ const spread = computed(() => { //差多少元起送
if (orderType.value != 'takeout') return
return parseFloat((store.value.minPrice - getCartGoodsPrice).toFixed(2))
})
const isGoodVisible = (good) => !keyword.value || [good.storeName, good.storeInfo]
.filter(Boolean).join(' ').toLowerCase().includes(keyword.value.trim().toLowerCase())
const filteredGoods = computed(() => {
const query = keyword.value.trim().toLowerCase()
if (!query) return goods.value
return goods.value.map(item => ({
...item,
goodsList: (item.goodsList || []).filter(good => [good.storeName, good.storeInfo, good.keyword]
.filter(Boolean).join(' ').toLowerCase().includes(query))
})).filter(item => item.goodsList.length)
})
watch(keyword, () => {
currentCateId.value = filteredGoods.value[0]?.id || 0
cateScrollTop.value = 0
sizeCalcState.value = false
})
const hasSpecialSpecs = (good) => (good.productAttr || []).some(attr => (attr.attrValueArr || []).length > 1)
const defaultSpec = (good) => (good.productAttr || []).map(attr => attr.attrValueArr?.[0]).filter(Boolean).join(',')
@@ -515,7 +529,7 @@ const handleMenuTap = (id) => { //点击菜单项事件
}
currentCateId.value = id
nextTick(() => cateScrollTop.value = goods.value.find(item => item.id == id).top)
nextTick(() => cateScrollTop.value = filteredGoods.value.find(item => item.id == id)?.top || 0)
}
const handleGoodsScroll = ({ detail }) => { //商品列表滚动事件
if (!sizeCalcState.value) {
@@ -525,7 +539,7 @@ const handleGoodsScroll = ({ detail }) => { //商品列表滚动事件
const {
scrollTop
} = detail
let tabs = goods.value.filter(item => item.top <= scrollTop).reverse()
let tabs = filteredGoods.value.filter(item => item.top <= scrollTop).reverse()
if (tabs.length > 0) {
currentCateId.value = tabs[0].id
}
@@ -542,7 +556,7 @@ const calcSize = () => {
}
}).exec()
}
goods.value.forEach(item => {
filteredGoods.value.forEach(item => {
let view = uni.createSelectorQuery().select(`#cate-${item.id}`)
view.fields({
size: true