feat(商品): 添加商品使用说明字段并支持商品名称搜索
在商品类型、存储和页面中添加`usageInstruction`字段,用于展示商品使用说明。同时,在商品列表页面新增搜索功能,支持根据商品名称进行筛选。
This commit is contained in:
parent
7318c773c1
commit
999625ccd0
|
@ -7,6 +7,7 @@ export type Goods = {
|
|||
status: number,
|
||||
coverImg: string,
|
||||
goodsDetail: string,
|
||||
usageInstruction: string,
|
||||
cellId: number
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ const currentProduct = computed(() =>
|
|||
// 购物车弹窗控制
|
||||
const showCartPopup = ref(false)
|
||||
|
||||
const searchQuery = ref('')
|
||||
|
||||
// 点击分类导航
|
||||
function handleCategoryClick(index: number) {
|
||||
activeCategory.value = index
|
||||
|
@ -99,8 +101,16 @@ function getCartItemCount(cellId: number) {
|
|||
return item ? item.quantity : 0
|
||||
}
|
||||
|
||||
function filterProductsByName(products: Product[], query: string) {
|
||||
if (!query) return products
|
||||
return products.filter(p =>
|
||||
p.name.toLowerCase().includes(query.toLowerCase())
|
||||
)
|
||||
}
|
||||
|
||||
const currentProducts = computed(() => {
|
||||
return categories.value.filter(c => c.label === labels.value[activeCategory.value].id)
|
||||
const filteredByCategory = categories.value.filter(c => c.label === labels.value[activeCategory.value].id)
|
||||
return filterProductsByName(filteredByCategory, searchQuery.value)
|
||||
})
|
||||
|
||||
// 组件挂载时添加滚动监听
|
||||
|
@ -143,6 +153,12 @@ watch(() => route.path, (newPath) => {
|
|||
|
||||
<!-- 右侧商品列表 -->
|
||||
<div ref="scrollContainer" class="product-list">
|
||||
<van-search
|
||||
v-model="searchQuery"
|
||||
placeholder="搜索商品名称"
|
||||
shape="round"
|
||||
class="search-box"
|
||||
/>
|
||||
<div :ref="el => categoryRefs[0] = el as HTMLElement" class="category-section">
|
||||
<van-cell v-for="product in currentProducts" :key="product.id" class="product-item">
|
||||
<template #icon>
|
||||
|
|
|
@ -154,41 +154,40 @@ async function handleSubmit() {
|
|||
<div class="content-wrapper">
|
||||
<!-- 原有商品列表等代码保持不动 -->
|
||||
<van-cell-group class="product-list">
|
||||
<van-cell v-for="item in cartItems" :key="item.product.id" class="product-item">
|
||||
<template #icon>
|
||||
<van-image :src="item.product.image" width="60" height="60" class="product-image" />
|
||||
</template>
|
||||
<template v-for="item in cartItems" :key="item.product.id">
|
||||
<van-cell class="product-item">
|
||||
<template #icon>
|
||||
<van-image :src="item.product.image" width="60" height="60" class="product-image" />
|
||||
</template>
|
||||
|
||||
<div class="product-info">
|
||||
<div class="product-name van-ellipsis">
|
||||
{{ item.product.name }}
|
||||
<div class="product-info">
|
||||
<div class="product-name van-ellipsis">
|
||||
{{ item.product.name }}
|
||||
</div>
|
||||
<div class="price-row">
|
||||
<span class="product-price">
|
||||
¥{{ item.product.price.toFixed(2) }}
|
||||
</span>
|
||||
<span class="quantity">
|
||||
×{{ item.quantity }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price-row">
|
||||
<span class="product-price">
|
||||
¥{{ item.product.price.toFixed(2) }}
|
||||
</span>
|
||||
<span class="quantity">
|
||||
×{{ item.quantity }}
|
||||
</span>
|
||||
</van-cell>
|
||||
<van-cell v-if="item.product.usageInstruction" class="usage-instruction">
|
||||
<div class="instruction-content">
|
||||
使用说明:{{ item.product.usageInstruction }}
|
||||
</div>
|
||||
</div>
|
||||
</van-cell>
|
||||
</van-cell>
|
||||
</template>
|
||||
<van-cell>
|
||||
<van-field
|
||||
v-model="tel"
|
||||
label="手机号"
|
||||
placeholder="请输入联系电话"
|
||||
required
|
||||
class="tel-input"
|
||||
/>
|
||||
<van-field v-model="tel" label="手机号" placeholder="请输入联系电话" required class="tel-input" />
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group class="contact-form">
|
||||
<van-cell v-if="!corpidLogin"
|
||||
:class="['payment-option', { selected: selectedPayment === 'wechat' }]"
|
||||
@click="selectedPayment = 'wechat'"
|
||||
>
|
||||
<van-cell v-if="!corpidLogin" :class="['payment-option', { selected: selectedPayment === 'wechat' }]"
|
||||
@click="selectedPayment = 'wechat'">
|
||||
<van-icon name="wechat" class="method-icon" />
|
||||
<span class="method-label">微信支付</span>
|
||||
<div class="empty"></div>
|
||||
|
@ -197,8 +196,7 @@ async function handleSubmit() {
|
|||
|
||||
<van-cell
|
||||
:class="['payment-option', { selected: selectedPayment === 'balance', disabled: balance < totalPrice }]"
|
||||
@click="selectedPayment = 'balance'"
|
||||
>
|
||||
@click="selectedPayment = 'balance'">
|
||||
<van-icon name="balance-o" class="method-icon" />
|
||||
<span class="method-label">
|
||||
余额支付
|
||||
|
|
|
@ -10,6 +10,7 @@ export interface Product {
|
|||
image: string // 商品图片URL
|
||||
label: number // 商品标签
|
||||
cellId: number // 商品所在的格子ID
|
||||
usageInstruction: string // 商品使用说明
|
||||
}
|
||||
|
||||
export const useProductStore = defineStore("product", () => {
|
||||
|
@ -48,7 +49,8 @@ export const useProductStore = defineStore("product", () => {
|
|||
description: g.goodsDetail || "暂无描述",
|
||||
image: g.coverImg,
|
||||
label: g.categoryId,
|
||||
cellId: g.cellId
|
||||
cellId: g.cellId,
|
||||
usageInstruction: g.usageInstruction || ""
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error("获取商品数据失败:", error)
|
||||
|
|
|
@ -27,6 +27,7 @@ declare module 'vue' {
|
|||
VanNavBar: typeof import('vant/es')['NavBar']
|
||||
VanPicker: typeof import('vant/es')['Picker']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanSidebar: typeof import('vant/es')['Sidebar']
|
||||
VanSidebarItem: typeof import('vant/es')['SidebarItem']
|
||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||
|
|
Loading…
Reference in New Issue