Files
medical-mall/doc_mall/consumer/backup_pages/category药品.uvue

1133 lines
31 KiB
Plaintext
Raw Permalink 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">
<!-- 鍒嗙被鏍囬 -->
<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.badge">{{ product.badge }}</view>
<image
class="product-image"
:src="product.image"
mode="aspectFill"
/>
<view class="product-info">
<text class="product-name">{{ product.name }}</text>
<text class="product-spec">{{ product.specification }}</text>
<view class="price-section">
<view class="current-price">
<text class="price-symbol">楼</text>
<text class="price-value">{{ product.price }}</text>
</view>
<text class="original-price" v-if="product.originalPrice > product.price">
楼{{ product.originalPrice }}
</text>
</view>
<view class="product-meta">
<text class="manufacturer">{{ product.manufacturer }}</text>
<view class="sales-info">
<text class="sales-count">宸插敭{{ product.sales }}</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 currentCategoryName = ref('')
const currentCategoryDesc = ref('')
// 椤甸潰鍙傛暟
const pageParams = ref<any>({})
// 鐢熷懡鍛ㄦ湡
onMounted(async() => {
await loadCategories()
await loadProducts()
})
// 娣诲姞鍔犺浇鍒嗙被鐨勬柟娉?
const loadCategories = async () => {
const categories = await supabaseService.getCategories()
if (categories.length > 0) {
primaryCategories.value = categories
// 璁剧疆榛樿閫変腑绗竴涓垎绫?
if (!activePrimary.value && categories[0]) {
activePrimary.value = categories[0].id
}
}
}
// 鍔犺浇鍟嗗搧鏁版嵁
const loadProducts = async () => {
if (activePrimary.value) {
const response = await supabaseService.getProductsByCategory(activePrimary.value)
productList.value = 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
}
}
}
// 椤甸潰鍔犺浇鏃跺鐞嗗弬鏁?- 杩欐槸澶勭悊鍒嗙被鍒囨崲鐨勪富瑕佸叆鍙?
onLoad((options: any) => {
console.log('=== category椤甸潰onLoad琚皟鐢?===')
console.log('椤甸潰鍔犺浇鏃堕棿:', Date.now())
console.log('浼犲叆鐨刼ptions鍙傛暟:', 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涓病鏈夛紝灏濊瘯浠巊etCurrentPages()鑾峰彇
if (!categoryId) {
const pages = getCurrentPages()
if (pages.length > 0) {
const currentPage = pages[pages.length - 1]
const pageOptions = currentPage.options || {}
console.log('浠巊etCurrentPages()鑾峰彇鍙傛暟:', pageOptions)
if (pageOptions.categoryId) {
categoryId = pageOptions.categoryId
categoryName = pageOptions.name || ''
console.log('鉁?浠巊etCurrentPages()鎵惧埌鍒嗙被鍙傛暟:', categoryId, categoryName)
}
}
}
// 濡傛灉鏈夋壘鍒板垎绫籌D锛屽垯閫変腑瀵瑰簲鐨勫垎绫?
if (categoryId) {
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涓湭鎵惧埌鍒嗙被鍙傛暟锛屽皢浣跨敤浠庢暟鎹簱鍔犺浇鐨勭涓€涓垎绫?)
// 涓嶅啀浣跨敤纭紪鐮佺殑榛樿鍒嗙被锛宭oadCategories 浼氳缃涓€涓垎绫?
}
console.log('=== category椤甸潰onLoad鎵ц瀹屾垚 ===')
})
// 椤甸潰鏄剧ず鏃朵篃妫€鏌ュ弬鏁帮紝纭繚浠庡叾浠栭〉闈㈣繑鍥炴椂鑳芥纭樉绀?
onShow(() => {
console.log('=== category椤甸潰onShow琚皟鐢?===')
console.log('椤甸潰鏄剧ず鏃堕棿:', Date.now())
console.log('褰撳墠娲诲姩鍒嗙被:', activePrimary.value)
// 鍦╫nShow涓紝鎴戜滑涔熼渶瑕佹鏌ユ槸鍚︽湁鏂扮殑鍙傛暟
// 鍥犱负褰撲粠涓婚〉鍐嶆鐐瑰嚮鍒嗙被璺宠浆杩囨潵鏃讹紝鍙兘涓嶄細瑙﹀彂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) {
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('灏濊瘯浠嶶RL涓В鏋愬弬鏁?..')
// 灏濊瘯浠庡綋鍓嶉〉闈㈢殑URL涓В鏋愬弬鏁?
const currentUrl = currentPage.route || ''
console.log('褰撳墠椤甸潰璺敱:', currentUrl)
// 濡傛灉URL涓湁鏌ヨ鍙傛暟锛屽皾璇曡В鏋?
if (currentPage.$page && currentPage.$page.fullPath) {
const fullPath = currentPage.$page.fullPath
console.log('瀹屾暣璺緞:', fullPath)
// 灏濊瘯瑙f瀽鏌ヨ鍙傛暟
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) {
console.log('鉁?浠嶶RL瑙瀽鍒板垎绫诲弬鏁?', urlCategoryId)
selectPrimaryCategory(urlCategoryId)
}
}
}
}
}
console.log('=== category椤甸潰onShow鎵ц瀹屾垚 ===')
})
// 閫夋嫨涓€绾у垎绫?
const selectPrimaryCategory = async (categoryId: string) => {
console.log('=== selectPrimaryCategory鍑芥暟寮€濮嬫墽琛?===')
console.log('浼犲叆鐨刢ategoryId:', 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('鉂?鏈壘鍒板垎绫籌D:', 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('鍑嗗鍔犺浇鍟嗗搧鏁版嵁...')
// 鍔犺浇瀵瑰簲鍟嗗搧 - 浣跨敤 Supabase 鏈嶅姟
const response = await supabaseService.getProductsByCategory(categoryId)
productList.value = response.data
hasMore.value = response.hasmore
console.log('鉁?鍔犺浇鍟嗗搧鏁版嵁鎴愬姛')
console.log('鍒嗙被:', categoryId)
console.log('鍟嗗搧鏁伴噺:', response.data.length)
console.log('鍟嗗搧鍒楄〃:', response.data)
// 楠岃瘉鏁版嵁鏄惁宸叉纭洿鏂?
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 = (product: any) => {
// 鑾峰彇鐜版湁璐墿杞︽暟鎹?
const cartData = uni.getStorageSync('cart')
let cartItems: any[] = []
if (cartData) {
try {
cartItems = JSON.parse(cartData as string) as any[]
} catch (e) {
console.error('瑙f瀽璐墿杞︽暟鎹け璐?, e)
}
}
// 妫€鏌ュ晢鍝佹槸鍚﹀凡瀛樺湪
const existingItem = cartItems.find((item: any) => item.id === product.id)
if (existingItem) {
existingItem.quantity++
} else {
// 娣诲姞鏂板晢鍝?
cartItems.push({
id: product.id,
shopId: product.shopId || 'shop_default',
shopName: product.shopName || product.manufacturer || '鑷惀搴楅摵',
name: product.name,
price: product.price,
image: product.image,
spec: product.specification || '榛樿瑙勬牸',
quantity: 1,
selected: true
})
}
// 淇濆瓨鍥炲瓨鍌?
uni.setStorageSync('cart', JSON.stringify(cartItems))
uni.showToast({
title: '宸叉坊鍔犲埌璐墿杞?,
icon: 'success'
})
cartCount.value++
}
// 瀵艰埅鍑芥暟
const navigateToSearch = () => uni.navigateTo({ url: '/pages/mall/consumer/search' })
const navigateToCart = () => uni.navigateTo({ url: '/pages/medicine/cart' })
const navigateToProduct = (product: any) => {
uni.navigateTo({
url: `/pages/mall/consumer/product-detail?productId=${product.id}&price=${product.price}&originalPrice=${product.originalPrice || ''}&name=${encodeURIComponent(product.name)}&image=${encodeURIComponent(product.image || '')}`
})
}
// 鐩告満鍔熻兘
const onCamera = () => {
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
console.log('鐩告満鎷嶆憚鎴愬姛:', res.tempFilePaths[0])
uni.showToast({
title: '宸叉媿鎽勶紝姝e湪璇嗗埆...',
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: #ff5000;
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: #ff5000;
color: white;
font-size: 11px;
padding: 4px 12px;
border-radius: 12px;
font-weight: 700;
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: 700;
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: #ff5000;
}
.price-value {
font-size: 20px;
font-weight: bold;
color: #ff5000;
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>