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
+43 -34
View File
@@ -39,43 +39,43 @@ export const BRANDS = {
], ],
beer: [ beer: [
// 国产主流 // 国产主流
{ name: '青岛啤酒', product: '经典', degree: 4.3 }, { name: '青岛啤酒', product: '经典', degree: 4.3, group: 'domestic' },
{ name: '青岛啤酒', product: '全麦白啤', degree: 4.7 }, { name: '青岛啤酒', product: '全麦白啤', degree: 4.7, group: 'domestic' },
{ name: '青岛啤酒', product: '黑啤', degree: 5.5 }, { name: '青岛啤酒', product: '黑啤', degree: 5.5, group: 'domestic' },
{ name: '雪花', product: '勇闯天涯', degree: 3.3 }, { name: '雪花', product: '勇闯天涯', degree: 3.3, group: 'domestic' },
{ name: '雪花', product: '纯生', degree: 3.6 }, { name: '雪花', product: '纯生', degree: 3.6, group: 'domestic' },
{ name: '雪花', product: 'superX', degree: 4.0 }, { name: '雪花', product: 'superX', degree: 4.0, group: 'domestic' },
{ name: '百威', product: '经典', degree: 5.0 }, { name: '百威', product: '经典', degree: 5.0, group: 'domestic' },
{ name: '百威', product: '锦兔', degree: 5.0 }, { name: '百威', product: '锦兔', degree: 5.0, group: 'domestic' },
{ name: '哈尔滨', product: '冰纯', degree: 4.5 }, { name: '哈尔滨', product: '冰纯', degree: 4.5, group: 'domestic' },
{ name: '哈尔滨', product: '小麦王', degree: 3.6 }, { name: '哈尔滨', product: '小麦王', degree: 3.6, group: 'domestic' },
{ name: '燕京', product: 'U8', degree: 2.5 }, { name: '燕京', product: 'U8', degree: 2.5, group: 'domestic' },
{ name: '燕京', product: '原浆白啤', degree: 4.8 }, { name: '燕京', product: '原浆白啤', degree: 4.8, group: 'domestic' },
{ name: '乌苏', product: '大乌苏', degree: 4.0 }, { name: '乌苏', product: '大乌苏', degree: 4.0, group: 'domestic' },
{ name: '珠江', product: '纯生', degree: 3.6 }, { name: '珠江', product: '纯生', degree: 3.6, group: 'domestic' },
{ name: '泰山', product: '7天原浆', degree: 4.7 }, { name: '泰山', product: '7天原浆', degree: 4.7, group: 'domestic' },
// 国际品牌 // 国际品牌
{ name: '喜力', product: '星银', degree: 5.0 }, { name: '喜力', product: '星银', degree: 5.0, group: 'international' },
{ name: '科罗娜', product: 'Extra', degree: 4.5 }, { name: '科罗娜', product: 'Extra', degree: 4.5, group: 'international' },
{ name: '嘉士伯', product: '特醇', degree: 5.0 }, { name: '嘉士伯', product: '特醇', degree: 5.0, group: 'international' },
{ name: '朝日', product: '超爽', degree: 5.0 }, { name: '朝日', product: '超爽', degree: 5.0, group: 'international' },
{ name: '麒麟', product: '一番榨', degree: 5.0 }, { name: '麒麟', product: '一番榨', degree: 5.0, group: 'international' },
{ name: '三得利', product: '高端麦芽', degree: 5.5 }, { name: '三得利', product: '高端麦芽', degree: 5.5, group: 'international' },
{ name: '札幌', product: '黑标', degree: 5.0 }, { name: '札幌', product: '黑标', degree: 5.0, group: 'international' },
{ name: '虎牌', product: '经典', degree: 5.0 }, { name: '虎牌', product: '经典', degree: 5.0, group: 'international' },
{ name: '生力', product: '清爽', degree: 5.0 }, { name: '生力', product: '清爽', degree: 5.0, group: 'international' },
// 德式/白啤 // 德式/白啤
{ name: '福佳', product: '白啤', degree: 4.9 }, { name: '福佳', product: '白啤', degree: 4.9, group: 'wheat' },
{ name: '1664', product: '白啤', degree: 5.0 }, { name: '1664', product: '白啤', degree: 5.0, group: 'wheat' },
{ name: '柏龙', product: '小麦啤', degree: 5.5 }, { name: '柏龙', product: '小麦啤', degree: 5.5, group: 'wheat' },
{ name: '艾丁格', product: '小麦啤', degree: 5.3 }, { name: '艾丁格', product: '小麦啤', degree: 5.3, group: 'wheat' },
// 精酿 // 精酿
{ name: '鹅岛', product: 'IPA', degree: 5.9 }, { name: '鹅岛', product: 'IPA', degree: 5.9, group: 'craft' },
{ name: '熊猫精酿', product: '蜂蜜生姜艾尔', degree: 5.0 }, { name: '熊猫精酿', product: '蜂蜜生姜艾尔', degree: 5.0, group: 'craft' },
{ name: '京A', product: '工人淡色艾尔', degree: 5.0 }, { name: '京A', product: '工人淡色艾尔', degree: 5.0, group: 'craft' },
{ name: '拳击猫', product: 'TKO IPA', degree: 6.5 }, { name: '拳击猫', product: 'TKO IPA', degree: 6.5, group: 'craft' },
{ name: '高大师', product: '婴儿肥IPA', degree: 5.6 }, { name: '高大师', product: '婴儿肥IPA', degree: 5.6, group: 'craft' },
{ name: '精酿', product: '自选', degree: 6.0 } { name: '精酿', product: '自选', degree: 6.0, group: 'craft' }
], ],
wine: [ wine: [
{ name: '拉菲', product: '传奇', degree: 13 }, { name: '拉菲', product: '传奇', degree: 13 },
@@ -122,6 +122,15 @@ export const BRANDS = {
other: [] other: []
} }
// 啤酒品牌分组tab(record页两级结构:分组tab + 组内品牌标签)
export const BEER_BRAND_GROUPS = [
{ id: 'all', name: '全部' },
{ id: 'domestic', name: '国产' },
{ id: 'international', name: '国际' },
{ id: 'wheat', name: '麦啤' },
{ id: 'craft', name: '精酿' }
]
// 配餐分类 // 配餐分类
export const FOOD_CATEGORIES = [ export const FOOD_CATEGORIES = [
{ id: 'hotpot', name: '火锅', emoji: '🍲' }, { id: 'hotpot', name: '火锅', emoji: '🍲' },
+101 -5
View File
@@ -46,6 +46,24 @@
<view v-if="currentDrink.category" class="drink-form card"> <view v-if="currentDrink.category" class="drink-form card">
<!-- 品牌选择 --> <!-- 品牌选择 -->
<text class="section-label">品牌</text> <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 class="brand-tags">
<view <view
v-for="brand in visibleBrands" v-for="brand in visibleBrands"
@@ -55,10 +73,14 @@
@click="selectBrand(brand)" @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>
<!-- 更多:默认只展示前几个品牌,点击展开全部 --> <!-- 搜索无结果提示 -->
<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> <text>{{ showAllBrands ? '收起 ▴' : '更多 ▾' }}</text>
</view> </view>
</view> </view>
@@ -66,7 +88,7 @@
<input <input
class="input-field" class="input-field"
v-model="currentDrink.brand" v-model="currentDrink.brand"
placeholder="或输入其他品牌" :placeholder="currentDrink.category === 'beer' ? '搜索或输入其他品牌' : '或输入其他品牌'"
placeholder-class="input-placeholder" placeholder-class="input-placeholder"
/> />
</view> </view>
@@ -320,7 +342,7 @@
<script> <script>
import { import {
DRINK_CATEGORIES, DRINK_UNITS, BRANDS, FOOD_CATEGORIES, DRINK_CATEGORIES, DRINK_UNITS, BRANDS, BEER_BRAND_GROUPS, FOOD_CATEGORIES,
FEELINGS, VISIBILITY_OPTIONS FEELINGS, VISIBILITY_OPTIONS
} from '../../common/constants' } from '../../common/constants'
import { calcStandardCups, unitToMl, formatDate, getCatIcon, isIconPath } from '../../common/utils' import { calcStandardCups, unitToMl, formatDate, getCatIcon, isIconPath } from '../../common/utils'
@@ -350,6 +372,11 @@ export default {
brandList: [], brandList: [],
showAllBrands: false, showAllBrands: false,
maxVisibleBrands: 8, maxVisibleBrands: 8,
// 啤酒两级结构:分组tab列表 + 当前激活分组
beerGroups: BEER_BRAND_GROUPS,
activeBeerGroup: 'all',
// 点选标签填入的品牌名(不触发搜索过滤,区别于手动输入)
lastBeerSelection: '',
amountStr: '', amountStr: '',
amountFocused: false, amountFocused: false,
degreeStr: '', degreeStr: '',
@@ -375,8 +402,23 @@ export default {
} }
}, },
computed: { computed: {
// 啤酒搜索关键词:品牌输入框内容兼作实时搜索(点选标签填入的值不算搜索)
beerKeyword() {
const v = (this.currentDrink.brand || '').trim()
if (v && v === this.lastBeerSelection) return ''
return v
},
// 品牌列表默认只展示前 maxVisibleBrands 个,点“更多”后展开全部 // 品牌列表默认只展示前 maxVisibleBrands 个,点“更多”后展开全部
// 啤酒走两级结构:搜索优先,其次按分组tab过滤
visibleBrands() { 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) return this.showAllBrands ? this.brandList : this.brandList.slice(0, this.maxVisibleBrands)
}, },
currentCups() { currentCups() {
@@ -440,12 +482,26 @@ export default {
this.degreeStr = String(cat.defaultDegree) this.degreeStr = String(cat.defaultDegree)
this.brandList = BRANDS[cat.id] || [] this.brandList = BRANDS[cat.id] || []
this.showAllBrands = false 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) { selectBrand(brand) {
this.currentDrink.brand = brand.name this.currentDrink.brand = brand.name
this.currentDrink.product = brand.product this.currentDrink.product = brand.product
this.currentDrink.degree = brand.degree this.currentDrink.degree = brand.degree
this.degreeStr = String(brand.degree) this.degreeStr = String(brand.degree)
// 啤酒:记录点选值,避免输入框填入后误触发搜索过滤
if (this.currentDrink.category === 'beer') {
this.lastBeerSelection = brand.name
}
}, },
onAmountChange() { onAmountChange() {
// 响应式计算 // 响应式计算
@@ -540,6 +596,8 @@ export default {
this.degreeStr = '' this.degreeStr = ''
this.brandList = [] this.brandList = []
this.showAllBrands = false this.showAllBrands = false
this.activeBeerGroup = 'all'
this.lastBeerSelection = ''
}, },
async publishRecord() { async publishRecord() {
const recordData = { const recordData = {
@@ -743,6 +801,44 @@ export default {
margin-bottom: $sp-md; 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 { .tag-more {
border: 2rpx dashed var(--border-faint, rgba(255, 255, 255, 0.2)); border: 2rpx dashed var(--border-faint, rgba(255, 255, 255, 0.2));