feat(record): 实现啤酒品牌分组标签和搜索功能
- 为啤酒类别添加分组tab(全部/国产/国际/麦啤/精酿) - 实现啤酒品牌的两级筛选结构:分组tab + 组内品牌标签 - 添加啤酒品牌实时搜索功能,支持按名称和产品搜索 - 优化品牌标签显示逻辑,同品牌多产品时显示品牌·产品格式 - 添加搜索无结果提示信息 - 更新输入框占位符文字为"搜索或输入其他品牌" - 修复啤酒类别下不应显示"更多"按钮的问题 - 添加啤酒分组标签的样式和交互效果
This commit is contained in:
+43
-34
@@ -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
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user