feat(record): 实现啤酒品牌分组标签和搜索功能

- 为啤酒类别添加分组tab(全部/国产/国际/麦啤/精酿)
- 实现啤酒品牌的两级筛选结构:分组tab + 组内品牌标签
- 添加啤酒品牌实时搜索功能,支持按名称和产品搜索
- 优化品牌标签显示逻辑,同品牌多产品时显示品牌·产品格式
- 添加搜索无结果提示信息
- 更新输入框占位符文字为"搜索或输入其他品牌"
- 修复啤酒类别下不应显示"更多"按钮的问题
- 添加啤酒分组标签的样式和交互效果
This commit is contained in:
cg
2026-08-20 22:21:16 +08:00
parent 18e7b4fd50
commit f98d25d752
2 changed files with 144 additions and 39 deletions
+101 -5
View File
@@ -46,6 +46,24 @@
<view v-if="currentDrink.category" class="drink-form card">
<!-- 品牌选择 -->
<text class="section-label">品牌</text>
<!-- 啤酒:分组tab(全部/国产/国际/麦啤/精酿)+ 组内品牌标签,输入框可实时搜索 -->
<scroll-view
v-if="currentDrink.category === 'beer' && !beerKeyword"
class="beer-brand-tabs"
scroll-x
enhanced
:show-scrollbar="false"
>
<view
v-for="tab in beerGroups"
:key="tab.id"
class="beer-tab"
:class="{ 'beer-tab-active': activeBeerGroup === tab.id }"
@click="selectBeerGroup(tab.id)"
>
<text>{{ tab.name }}</text>
</view>
</scroll-view>
<view class="brand-tags">
<view
v-for="brand in visibleBrands"
@@ -55,10 +73,14 @@
@click="selectBrand(brand)"
>
<!-- 同品牌多产品时展示产品名以便区分 -->
<text>{{ brandList.filter(b => b.name === brand.name).length > 1 ? brand.name + '·' + brand.product : brand.name }}</text>
<text>{{ getBrandTagLabel(brand) }}</text>
</view>
<!-- 更多:默认只展示前几个品牌,点击展开全部 -->
<view v-if="brandList.length > maxVisibleBrands" class="tag tag-more" @click="showAllBrands = !showAllBrands">
<!-- 搜索无结果提示 -->
<view v-if="currentDrink.category === 'beer' && beerKeyword && visibleBrands.length === 0" class="brand-empty">
<text>没找到相关啤酒,可直接在下方输入品牌</text>
</view>
<!-- 更多:默认只展示前几个品牌,点击展开全部(啤酒为分组tab无需更多) -->
<view v-if="currentDrink.category !== 'beer' && brandList.length > maxVisibleBrands" class="tag tag-more" @click="showAllBrands = !showAllBrands">
<text>{{ showAllBrands ? '收起 ▴' : '更多 ▾' }}</text>
</view>
</view>
@@ -66,7 +88,7 @@
<input
class="input-field"
v-model="currentDrink.brand"
placeholder="或输入其他品牌"
:placeholder="currentDrink.category === 'beer' ? '搜索或输入其他品牌' : '或输入其他品牌'"
placeholder-class="input-placeholder"
/>
</view>
@@ -320,7 +342,7 @@
<script>
import {
DRINK_CATEGORIES, DRINK_UNITS, BRANDS, FOOD_CATEGORIES,
DRINK_CATEGORIES, DRINK_UNITS, BRANDS, BEER_BRAND_GROUPS, FOOD_CATEGORIES,
FEELINGS, VISIBILITY_OPTIONS
} from '../../common/constants'
import { calcStandardCups, unitToMl, formatDate, getCatIcon, isIconPath } from '../../common/utils'
@@ -350,6 +372,11 @@ export default {
brandList: [],
showAllBrands: false,
maxVisibleBrands: 8,
// 啤酒两级结构:分组tab列表 + 当前激活分组
beerGroups: BEER_BRAND_GROUPS,
activeBeerGroup: 'all',
// 点选标签填入的品牌名(不触发搜索过滤,区别于手动输入)
lastBeerSelection: '',
amountStr: '',
amountFocused: false,
degreeStr: '',
@@ -375,8 +402,23 @@ export default {
}
},
computed: {
// 啤酒搜索关键词:品牌输入框内容兼作实时搜索(点选标签填入的值不算搜索)
beerKeyword() {
const v = (this.currentDrink.brand || '').trim()
if (v && v === this.lastBeerSelection) return ''
return v
},
// 品牌列表默认只展示前 maxVisibleBrands 个,点“更多”后展开全部
// 啤酒走两级结构:搜索优先,其次按分组tab过滤
visibleBrands() {
if (this.currentDrink.category === 'beer') {
const kw = this.beerKeyword.toLowerCase()
if (kw) {
return this.brandList.filter(b => (b.name + b.product).toLowerCase().includes(kw))
}
if (this.activeBeerGroup === 'all') return this.brandList
return this.brandList.filter(b => b.group === this.activeBeerGroup)
}
return this.showAllBrands ? this.brandList : this.brandList.slice(0, this.maxVisibleBrands)
},
currentCups() {
@@ -440,12 +482,26 @@ export default {
this.degreeStr = String(cat.defaultDegree)
this.brandList = BRANDS[cat.id] || []
this.showAllBrands = false
// 啤酒默认展示全部分组
this.activeBeerGroup = 'all'
this.lastBeerSelection = ''
},
selectBeerGroup(id) {
this.activeBeerGroup = id
},
getBrandTagLabel(brand) {
// 同品牌多产品时展示 品牌·产品,否则只展品牌名
return this.brandList.filter(b => b.name === brand.name).length > 1 ? brand.name + '·' + brand.product : brand.name
},
selectBrand(brand) {
this.currentDrink.brand = brand.name
this.currentDrink.product = brand.product
this.currentDrink.degree = brand.degree
this.degreeStr = String(brand.degree)
// 啤酒:记录点选值,避免输入框填入后误触发搜索过滤
if (this.currentDrink.category === 'beer') {
this.lastBeerSelection = brand.name
}
},
onAmountChange() {
// 响应式计算
@@ -540,6 +596,8 @@ export default {
this.degreeStr = ''
this.brandList = []
this.showAllBrands = false
this.activeBeerGroup = 'all'
this.lastBeerSelection = ''
},
async publishRecord() {
const recordData = {
@@ -743,6 +801,44 @@ export default {
margin-bottom: $sp-md;
}
/* 啤酒品牌分组tab:横向滚动,点击切换组内品牌标签 */
.beer-brand-tabs {
white-space: nowrap;
width: 100%;
margin-bottom: $sp-md;
}
.beer-tab {
display: inline-flex;
align-items: center;
padding: $sp-xs $sp-lg;
margin-right: $sp-sm;
border-radius: $radius-full;
font-size: $fs-sm;
font-weight: $fw-medium;
color: $text-secondary;
background: $bg-elevated;
border: 2rpx solid var(--border-faint, rgba(255, 255, 255, 0.08));
transition: all 0.2s ease;
&.beer-tab-active {
color: $amber;
background: $amber-glow;
border-color: $amber;
}
&:active {
transform: scale(0.95);
}
}
/* 啤酒搜索无结果提示 */
.brand-empty {
font-size: $fs-sm;
color: $text-tertiary;
padding: $sp-xs 0;
}
/* 更多/收起按钮:虚线边框与普通品牌标签区分 */
.tag-more {
border: 2rpx dashed var(--border-faint, rgba(255, 255, 255, 0.2));