Files
medical-mall/pages/mall/consumer/category.uvue

1180 lines
31 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="category-page">
<!-- 顶部搜索栏 -->
<view class="search-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="search-container">
<view class="search-box" @click="navigateToSearch" :style="{ height: '30px' }">
<!-- 模拟输入框 -->
<text class="search-placeholder">请输入药品名称、症状或品牌</text>
<!-- 扫码图标 -->
<view class="nav-icon-btn" @click.stop="onScan">
<text class="nav-icon">🔳</text>
</view>
<!-- 相机图标 -->
<view class="nav-camera-btn" @click.stop="onCamera">
<text class="nav-camera-icon">📷</text>
</view>
<!-- 搜索按钮 -->
<view class="nav-inner-search-btn" :style="{ height: '22px' }">
<text class="nav-inner-search-text">搜索</text>
</view>
</view>
</view>
</view>
<!-- 分类内容区 -->
<view
class="category-content"
:style="{
marginTop: (statusBarHeight + headerHeight + 10) + 'px',
height: `calc(100vh - ${statusBarHeight + headerHeight + 10}px)`
}"
>
<!-- 左侧一级分类 -->
<scroll-view scroll-y class="primary-category">
<view
v-for="item in primaryCategories"
:key="item.id"
:class="['primary-item', { active: activePrimary === item.id }]"
@click="selectPrimaryCategory(item.id)"
:style="{ backgroundColor: activePrimary === item.id ? item.color : 'transparent' }"
>
<text class="primary-icon">{{ item.icon }}</text>
<text class="primary-name">{{ item.name }}</text>
</view>
</scroll-view>
<!-- 右侧商品列表 -->
<scroll-view
scroll-y
class="product-content"
@scrolltolower="loadMore"
:lower-threshold="50"
>
<!-- 分类标题 -->
<view class="category-header">
<text class="category-title">{{ currentCategoryName }}</text>
<text class="category-desc">{{ currentCategoryDesc }}</text>
</view>
<!-- 商品网格 -->
<view v-if="productList.length > 0" class="product-grid">
<view
v-for="product in productList"
:key="product.id"
class="product-card"
@click="navigateToProduct(product)"
>
<view class="product-badge" v-if="product.is_hot">热销</view>
<image
class="product-image"
:src="product.main_image_url"
mode="aspectFill"
/>
<view class="product-info">
<text class="product-name">{{ product.name }}</text>
<view class="price-section">
<view class="current-price">
<text class="price-symbol">¥</text>
<text class="price-value">{{ product.base_price }}</text>
</view>
<text class="original-price" v-if="product.market_price != null && product.market_price! > product.base_price">
¥{{ product.market_price }}
</text>
</view>
<view class="product-meta">
<text class="manufacturer">{{ product.brand_name || product.shop_name || '自营' }}</text>
<view class="sales-info">
<text class="sales-count">已售{{ product.sale_count }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-else class="empty-state">
<text class="empty-icon">💊</text>
<text class="empty-text">暂无相关药品</text>
<text class="empty-desc">该分类下暂无商品,敬请期待</text>
</view>
<!-- 加载更多提示 -->
<view v-if="hasMore" class="load-more">
<text class="load-text">上拉加载更多</text>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, onMounted } from 'vue'
import supabaseService from '@/utils/supabaseService.uts'
import type { Category, Product } from '@/utils/supabaseService.uts'
// 响应式数据
const statusBarHeight = ref(0)
const headerHeight = ref(44) // 默认头部高度
const primaryCategories = ref<Category[]>([])
const productList = ref<Product[]>([])
const activePrimary = ref<string>('')
const cartCount = ref(3)
const hasMore = ref(true)
const hasLoadedFromParams = ref(false) // 标记是否已通过参数加载
const currentPage = ref(1)
const loading = ref(false)
// 获取当前分类信息
const currentCategoryName = ref('')
const currentCategoryDesc = ref('')
// 页面参数
const pageParams = ref<any>({})
// 生命周期
onMounted(async() => {
await loadCategories()
// 等待分类加载完成后,再检查是否需要加载默认分类的商品
// 延迟一点时间,确保页面参数处理完成
setTimeout(async () => {
if (!hasLoadedFromParams.value && activePrimary.value) {
await loadProducts()
}
}, 300)
})
// 添加加载分类的方法
const loadCategories = async () => {
try {
const categories = await supabaseService.getCategories()
console.log('加载分类数据成功,数量:', categories.length)
if (categories.length > 0) {
primaryCategories.value = categories
// 如果没有通过参数设置分类,则设置默认选中第一个分类
if (!activePrimary.value && categories[0]) {
activePrimary.value = categories[0].id
console.log('设置默认分类为:', categories[0].name, 'ID:', categories[0].id)
}
} else {
console.warn('从Supabase获取的分类数据为空')
}
} catch (error) {
console.error('加载分类数据失败:', error)
}
}
// 加载商品数据
const loadProducts = async () => {
if (loading.value) return
if (!activePrimary.value) {
console.warn('activePrimary为空无法加载商品')
return
}
loading.value = true
try {
console.log('开始加载商品分类ID:', activePrimary.value, '页码:', currentPage.value)
const response = await supabaseService.getProductsByCategory(activePrimary.value, currentPage.value)
console.log('商品加载结果:', {
dataCount: response.data.length,
total: response.total,
hasmore: response.hasmore,
page: currentPage.value
})
if (currentPage.value === 1) {
productList.value = response.data
} else {
productList.value.push(...response.data)
}
hasMore.value = response.hasmore
// 更新当前分类信息
const category = primaryCategories.value.find(cat => cat.id === activePrimary.value)
if (category) {
currentCategoryName.value = category.name
currentCategoryDesc.value = category.description || ''
}
console.log('商品列表加载完成,当前总数量:', productList.value.length)
} catch (error) {
console.error('加载商品数据失败:', error)
if (currentPage.value === 1) {
productList.value = []
}
} finally {
loading.value = false
}
}
// 加载更多
const loadMore = () => {
if (hasMore.value && !loading.value) {
currentPage.value++
loadProducts()
}
}
// 页面加载时处理参数 - 这是处理分类切换的主要入口
onLoad((options: any) => {
console.log('=== category页面onLoad被调用 ===')
console.log('页面加载时间:', Date.now())
console.log('传入的options参数:', options)
console.log('当前活动分类:', activePrimary.value)
let categoryId = ''
let categoryName = ''
// 首先检查传入的options参数
if (options && options.categoryId) {
categoryId = options.categoryId
categoryName = options.name || ''
console.log('✅ onLoad中找到分类参数:', categoryId, categoryName)
}
// 如果options中没有尝试从getCurrentPages()获取
if (!categoryId) {
const pages = getCurrentPages()
if (pages.length > 0) {
const currentPage = pages[pages.length - 1]
const pageOptions = currentPage.options || {}
console.log('从getCurrentPages()获取参数:', pageOptions)
if (pageOptions.categoryId) {
categoryId = pageOptions.categoryId
categoryName = pageOptions.name || ''
console.log('✅ 从getCurrentPages()找到分类参数:', categoryId, categoryName)
}
}
}
// 如果有找到分类ID则选中对应的分类
if (categoryId) {
hasLoadedFromParams.value = true
console.log('✅ 准备选中分类:', categoryId)
console.log('分类名称:', categoryName || '未指定')
// 检查是否需要更新分类
if (activePrimary.value !== categoryId) {
console.log('当前分类:', activePrimary.value, '与目标分类:', categoryId, '不同,需要更新')
console.log('准备调用selectPrimaryCategory函数...')
selectPrimaryCategory(categoryId)
} else {
console.log('当前分类已经是目标分类,但可能用户想要刷新页面')
console.log('当前分类:', activePrimary.value, '目标分类:', categoryId)
// 即使分类相同,也重新加载数据,确保数据是最新的
// 添加一个小的延迟,确保页面完全显示后再更新数据
setTimeout(() => {
selectPrimaryCategory(categoryId)
}, 100)
}
} else {
console.log('⚠️ onLoad中未找到分类参数将使用从数据库加载的第一个分类')
// 不再使用硬编码的默认分类loadCategories 会设置第一个分类
}
console.log('=== category页面onLoad执行完成 ===')
})
// 页面显示时也检查参数,确保从其他页面返回时能正确显示
onShow(() => {
console.log('=== category页面onShow被调用 ===')
console.log('页面显示时间:', Date.now())
console.log('当前活动分类:', activePrimary.value)
// 在onShow中我们也需要检查是否有新的参数
// 因为当从主页再次点击分类跳转过来时可能不会触发onLoad
// 而是触发onShow
// 获取当前页面实例和参数
const pages = getCurrentPages()
if (pages.length > 0) {
const currentPage = pages[pages.length - 1]
const pageOptions = currentPage.options || {}
console.log('onShow中获取参数:', pageOptions)
// 检查是否有分类参数
if (pageOptions.categoryId) {
hasLoadedFromParams.value = true
const categoryId = pageOptions.categoryId
const categoryName = pageOptions.name || ''
console.log('✅ onShow中找到分类参数:', categoryId, categoryName)
console.log('URL中的时间戳参数:', pageOptions.timestamp)
console.log('URL中的随机参数:', pageOptions.random)
// 检查是否需要更新分类
if (activePrimary.value !== categoryId) {
console.log('当前分类:', activePrimary.value, '与目标分类:', categoryId, '不同,需要更新')
console.log('准备调用selectPrimaryCategory函数...')
selectPrimaryCategory(categoryId)
} else {
console.log('当前分类已经是目标分类,但可能用户想要刷新页面')
console.log('当前分类:', activePrimary.value, '目标分类:', categoryId)
// 即使分类相同,也重新加载数据,确保数据是最新的
// 添加一个小的延迟,确保页面完全显示后再更新数据
setTimeout(() => {
selectPrimaryCategory(categoryId)
}, 100)
}
} else {
console.log('⚠️ onShow中未找到分类参数')
console.log('尝试从URL中解析参数...')
// 尝试从当前页面的URL中解析参数
const currentUrl = currentPage.route || ''
console.log('当前页面路由:', currentUrl)
// 如果URL中有查询参数尝试解析
if (currentPage.$page && currentPage.$page.fullPath) {
const fullPath = currentPage.$page.fullPath
console.log('完整路径:', fullPath)
// 尝试解析查询参数
const queryIndex = fullPath.indexOf('?')
if (queryIndex > -1) {
const queryString = fullPath.substring(queryIndex + 1)
console.log('查询字符串:', queryString)
// 简单解析查询参数
const params = new URLSearchParams(queryString)
const urlCategoryId = params.get('categoryId')
if (urlCategoryId) {
hasLoadedFromParams.value = true
console.log('✅ 从URL解析到分类参数:', urlCategoryId)
selectPrimaryCategory(urlCategoryId)
}
}
}
}
}
console.log('=== category页面onShow执行完成 ===')
})
// 选择一级分类
const selectPrimaryCategory = async (categoryId: string) => {
console.log('=== selectPrimaryCategory函数开始执行 ===')
console.log('传入的categoryId:', categoryId)
console.log('当前时间:', Date.now())
// 验证categoryId是否有效
if (!categoryId) {
console.error('categoryId为空尝试使用第一个分类')
if (primaryCategories.value.length > 0) {
categoryId = primaryCategories.value[0].id
} else {
console.error('没有可用的分类')
return
}
}
console.log('验证后的categoryId:', categoryId)
console.log('当前activePrimary的值:', activePrimary.value)
// 更新活动分类
activePrimary.value = categoryId
console.log('更新后的activePrimary:', activePrimary.value)
// 更新当前分类信息
const category = primaryCategories.value.find(cat => cat.id === categoryId)
if (category) {
currentCategoryName.value = category.name
currentCategoryDesc.value = category.description
console.log('✅ 找到分类:', category.name, '描述:', category.description)
} else {
console.error('❌ 未找到分类ID:', categoryId, ',使用第一个分类')
// 如果找不到对应的分类,使用第一个分类
if (primaryCategories.value.length > 0) {
const firstCategory = primaryCategories.value[0]
currentCategoryName.value = firstCategory.name
currentCategoryDesc.value = firstCategory.description
activePrimary.value = firstCategory.id
categoryId = firstCategory.id
console.log('使用默认分类:', firstCategory.name)
}
}
console.log('准备加载商品数据...')
// 重置分页并加载
currentPage.value = 1
hasMore.value = true
await loadProducts()
console.log('✅ 加载商品数据成功')
console.log('分类:', categoryId)
console.log('商品数量:', productList.value.length)
console.log('商品列表:', productList.value)
// 验证数据是否已正确更新
console.log('数据更新验证:')
console.log('activePrimary:', activePrimary.value)
console.log('currentCategoryName:', currentCategoryName.value)
console.log('currentCategoryDesc:', currentCategoryDesc.value)
console.log('productList长度:', productList.value.length)
console.log('=== selectPrimaryCategory函数执行完成 ===')
}
// 添加到购物车
const addToCart = async (product: any) => {
uni.showLoading({ title: '添加中...' })
try {
const success = await supabaseService.addToCart(product.id, 1)
if (success) {
uni.showToast({
title: '已添加到购物车',
icon: 'success'
})
cartCount.value++
} else {
uni.showToast({
title: '添加失败,请先登录',
icon: 'none'
})
}
} catch (e) {
console.error('添加到购物车异常', e)
uni.showToast({ title: '操作失败', icon: 'none' })
} finally {
uni.hideLoading()
}
}
// 导航函数
const navigateToSearch = () => uni.navigateTo({ url: '/pages/mall/consumer/search' })
const navigateToCart = () => uni.navigateTo({ url: '/pages/mall/consumer/cart' })
const navigateToProduct = (product: any) => {
const id = product.id
const price = (product.base_price || 0).toString()
const originalPrice = (product.market_price || '').toString()
const name = encodeURIComponent(product.name || '')
const image = encodeURIComponent(product.main_image_url || '')
uni.navigateTo({
url: `/pages/mall/consumer/product-detail?id=${id}&productId=${id}&price=${price}&originalPrice=${originalPrice}&name=${name}&image=${image}`
})
}
// 相机功能
const onCamera = () => {
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
console.log('相机拍摄成功:', res.tempFilePaths[0])
uni.showToast({
title: '已拍摄,正在识别...',
icon: 'loading'
})
// 这里可以添加后续的识别逻辑
setTimeout(() => {
uni.showToast({
title: '识别成功',
icon: 'success'
})
}, 1000)
},
fail: (err) => {
console.error('相机调用失败:', err)
}
})
}
// 扫码功能
const onScan = () => {
uni.scanCode({
success: (res) => {
console.log('扫码成功:', res)
uni.showToast({
title: '扫码成功: ' + res.result,
icon: 'none'
})
},
fail: (err) => {
console.error('扫码失败:', err)
}
})
}
</script>
<style>
.category-page {
width: 100%;
min-height: 100vh;
background-color: #f8fafc;
display: flex;
flex-direction: column;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
}
/* 搜索栏 */
.search-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
z-index: 1000;
box-shadow: 0 2px 12px rgba(76, 175, 80, 0.15);
}
/* 搜索栏 */
/* 导航栏搜索框容器内边距调整 */
.search-container {
height: 44px; /* 调整为与消息页一致的高度 */
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1400px;
margin: 0 auto;
width: 100%;
}
/* 搜索框 hover 效果 */
.search-box:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 导航栏搜索框容器内边距调整 */
.search-box {
flex: 1;
max-width: 600px;
background: #f0f0f0;
border-radius: 20px;
padding: 0 4px 0 12px;
display: flex;
flex-direction: row; /* UVUE 显式设置 row */
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
width: 100%;
height: 32px; /* 减小高度与顶部高度44px适配略小于顶部高度 */
}
.search-placeholder {
font-size: 14px;
color: #999;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nav-inner-search-text {
font-size: 12px; /* 字体稍微变小 */
color: #ffffff;
font-weight: 500;
}
.icon {
font-size: 22px;
color: white;
}
.nav-icon-btn {
padding: 4px 8px 4px 4px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-right: 1px solid #ddd;
margin-right: 8px;
}
.nav-icon {
font-size: 18px;
}
.nav-camera-btn {
padding: 4px 8px 4px 4px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #ddd;
border-right: 1px solid #ddd; /* 修复UVUE样式 */
margin-right: 8px;
}
.nav-camera-icon {
font-size: 20px;
}
/* 搜索按钮高度微调 */
.nav-inner-search-btn {
padding: 0 12px; /* 减小内边距 */
background-color: #87CEEB; /* 天空蓝 */
border-radius: 16px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 24px; /* 随搜索框高度减小而减小 */
}
.cart-badge {
position: absolute;
top: -5px;
right: -5px;
background: #FF5722;
color: white;
font-size: 10px;
min-width: 18px;
height: 18px;
border-radius: 9px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 4px;
border: 2px solid #4CAF50;
}
/* 分类内容区 */
.category-content {
display: flex;
flex-direction: row; /* 强制水平排列 */
/* margin-top: 44px; 已通过 style 动态绑定 */
padding: 0 16px;
max-width: 1400px;
margin-left: auto;
margin-right: auto;
width: 100%;
gap: 20px;
/* height: calc(100vh - 44px); 已通过 style 动态绑定 */
overflow: hidden; /* 防止整体滚动 */
}
/* 左侧一级分类 */
.primary-category {
width: 120px;
height: 100%; /* 占满父容器高度 */
background: white;
border-radius: 12px;
padding: 12px 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
flex-shrink: 0;
overflow-y: auto; /* 允许内部滚动 */
}
.primary-item {
display: flex;
flex-direction: column; /* 图标和文字垂直排列 */
align-items: center;
justify-content: center;
padding: 12px 8px;
margin: 4px 8px;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
color: #666;
text-align: center;
}
.primary-item:hover {
transform: translateY(-2px); /* 悬停时向上浮动 */
}
.primary-item.active {
color: white !important;
font-weight: bold;
}
.primary-icon {
font-size: 24px;
margin-bottom: 6px;
margin-right: 0; /* 移除右边距 */
text-align: center;
display: block;
}
.primary-name {
font-size: 13px;
line-height: 1.4;
display: block;
}
/* 右侧内容区 */
.product-content {
flex: 1;
height: 100%; /* 占满父容器高度 */
padding: 0; /* 移除内边距,交给内部元素 */
overflow-y: auto; /* 允许内部滚动 */
}
.category-header {
margin-bottom: 16px;
padding: 16px 8px 0 8px;
position: sticky;
top: 0;
background-color: #f8fafc;
z-index: 10;
}
.category-title {
font-size: 20px;
font-weight: bold;
color: #333;
margin-bottom: 4px;
}
.category-desc {
font-size: 14px;
color: #666;
}
/* 商品网格 */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
.product-card {
background: white;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid #e0e0e0;
position: relative;
}
.product-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.product-badge {
position: absolute;
top: 12px;
left: 12px;
background: #FF5722;
color: white;
font-size: 11px;
padding: 4px 12px;
border-radius: 12px;
font-weight: 600;
z-index: 2;
}
.product-image {
width: 100%;
height: 160px;
object-fit: cover;
background: white;
}
.product-info {
padding: 16px;
}
.product-name {
font-size: 15px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
display: block;
line-height: 1.4;
}
.product-spec {
font-size: 13px;
color: #666;
margin-bottom: 12px;
display: block;
}
.price-section {
display: flex;
align-items: baseline;
gap: 8px;
margin-bottom: 12px;
}
.current-price {
display: flex;
align-items: baseline;
}
.price-symbol {
font-size: 14px;
color: #FF5722;
}
.price-value {
font-size: 20px;
font-weight: bold;
color: #FF5722;
margin-left: 2px;
}
.original-price {
font-size: 13px;
color: #999;
text-decoration: line-through;
}
.product-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
margin-bottom: 12px;
}
.manufacturer {
color: #666;
}
.sales-count {
color: #999;
}
.product-action {
margin-top: 12px;
}
.cart-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
background: #4CAF50;
color: white;
padding: 8px 12px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.cart-btn:hover {
background: #388E3C;
}
.cart-icon {
font-size: 14px;
}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
text-align: center;
}
.empty-icon {
font-size: 60px;
color: #4CAF50;
margin-bottom: 15px;
}
.empty-text {
font-size: 18px;
color: #333;
font-weight: bold;
margin-bottom: 8px;
}
.empty-desc {
font-size: 14px;
color: #666;
}
/* 加载更多 */
.load-more {
text-align: center;
padding: 20px 0;
color: #999;
font-size: 14px;
}
.load-text {
display: inline-block;
padding: 8px 16px;
background: #f5f5f5;
border-radius: 20px;
}
/* ===== 响应式设计 ===== */
/* 小屏手机 (小于414px) */
@media screen and (max-width: 414px) {
.category-content {
/* flex-direction: column; 移除这一行,保持 row 布局 */
padding: 0 8px;
gap: 10px;
}
.primary-category {
width: 80px; /* 减小宽度 */
/* display: flex; 移除flex布局保持默认 */
/* flex-wrap: wrap; 移除换行 */
padding: 8px 0;
}
.primary-item {
/* width: calc(25% - 8px); 移除百分比宽度 */
width: auto; /* 恢复自动宽度 */
margin: 4px;
padding: 8px 4px;
/* text-align: center; 已经在通用样式中设置 */
}
.primary-icon {
margin-right: 0;
margin-bottom: 4px;
font-size: 20px;
}
.primary-name {
font-size: 11px;
}
.product-grid {
grid-template-columns: repeat(2, 1fr); /* 改为双列显示 */
gap: 8px;
padding: 0 4px 20px 4px; /* 增加底部内边距 */
}
/* 手机端商品卡片极简模式 - 仿照主页样式 */
.product-spec,
.manufacturer,
.original-price,
.sales-info,
.product-badge { /* 分类页也隐藏角标,保持整洁 */
display: none;
}
.product-info {
padding: 6px;
}
.product-image {
height: 100px; /* 由于分类页右侧空间更窄,图片高度设得更小一点 */
}
.product-name {
font-size: 12px;
height: 32px;
line-height: 1.3;
margin-bottom: 2px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.price-section {
margin-bottom: 0;
margin-top: 4px;
justify-content: space-between;
width: 100%;
}
.price-symbol {
font-size: 10px;
}
.price-value {
font-size: 14px;
}
.product-meta {
display: none; /* 隐藏整个元数据行 */
}
.search-container {
padding: 0 12px;
height: 55px;
}
.search-box {
padding: 8px 16px;
}
.category-header {
padding: 12px 4px 0 4px;
}
}
/* 中屏手机/小平板 (415px-768px) */
@media screen and (min-width: 415px) and (max-width: 768px) {
.product-grid {
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
}
/* 平板设备 (769px-1024px) */
@media screen and (min-width: 769px) and (max-width: 1024px) {
.product-grid {
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
}
/* 桌面端 (1025px以上) */
@media screen and (min-width: 1025px) {
.category-content {
gap: 30px;
padding: 0 24px;
}
.primary-category {
width: 160px;
padding: 16px 0;
}
.primary-item {
padding: 16px 20px;
margin: 6px 12px;
border-radius: 10px;
}
.primary-icon {
font-size: 20px;
min-width: 28px;
}
.primary-name {
font-size: 15px;
}
.product-content {
padding: 20px 0;
}
.category-header {
margin-bottom: 24px;
padding: 0 12px;
}
.category-title {
font-size: 24px;
}
.category-desc {
font-size: 15px;
}
.product-grid {
grid-template-columns: repeat(4, 1fr);
gap: 24px;
}
.product-card {
border-radius: 14px;
}
.product-info {
padding: 20px;
}
.product-name {
font-size: 16px;
}
.product-spec {
font-size: 14px;
}
.price-value {
font-size: 22px;
}
}
/* 大桌面端 (1400px以上) */
@media screen and (min-width: 1400px) {
.category-content {
max-width: 1600px;
gap: 40px;
padding: 0 32px;
}
.primary-category {
width: 200px;
padding: 20px 0;
}
.primary-item {
padding: 18px 24px;
margin: 8px 16px;
border-radius: 12px;
}
.primary-icon {
font-size: 22px;
min-width: 32px;
}
.primary-name {
font-size: 16px;
}
.product-content {
padding: 24px 0;
}
.category-header {
margin-bottom: 28px;
padding: 0 16px;
}
.category-title {
font-size: 26px;
}
.category-desc {
font-size: 16px;
}
.product-grid {
grid-template-columns: repeat(5, 1fr);
gap: 28px;
}
.product-card {
border-radius: 16px;
}
.product-image {
height: 180px;
}
.product-info {
padding: 24px;
}
.product-name {
font-size: 17px;
}
.product-spec {
font-size: 15px;
}
.price-value {
font-size: 24px;
}
}
</style>