Files
medical-mall/pages/mall/consumer/category - 副本 (2).uvue
2026-01-23 16:47:05 +08:00

834 lines
21 KiB
Plaintext

<!-- pages/mall/consumer/category.uvue -->
<template>
<view class="category-page">
<!-- 顶部搜索栏 -->
<view class="search-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="search-container">
<view class="search-box" @click="navigateToSearch">
<text class="search-icon">🔍</text>
<text class="search-placeholder">症状/药品/品牌智能搜索</text>
</view>
</view>
</view>
<!-- 分类内容区 -->
<view class="category-content">
<!-- 左侧一级分类 -->
<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'
// 响应式数据
const statusBarHeight = ref(0)
const primaryCategories = ref<any[]>([])
const productList = ref<any[]>([])
const activePrimary = ref<string>('cold')
const cartCount = ref(3)
const hasMore = ref(true)
// 获取当前分类信息
const currentCategoryName = ref('感冒发烧')
const currentCategoryDesc = ref('解热镇痛')
// 医药分类数据(与主页一致)
const medicineCategories = [
{ id: 'cold', name: '感冒发烧', icon: '🤧', desc: '解热镇痛', color: '#2196F3' },
{ id: 'stomach', name: '肠胃用药', icon: '🤢', desc: '消化系统', color: '#4CAF50' },
{ id: 'pain', name: '止痛消炎', icon: '💊', desc: '镇痛消炎', color: '#F44336' },
{ id: 'skin', name: '皮肤用药', icon: '🤕', desc: '皮肤护理', color: '#9C27B0' },
{ id: 'vitamin', name: '维生素', icon: '🍊', desc: '营养补充', color: '#FF9800' },
{ id: 'chronic', name: '慢性病', icon: '🫀', desc: '长期管理', color: '#795548' },
{ id: 'child', name: '儿童用药', icon: '👶', desc: '儿童专用', color: '#00BCD4' },
{ id: 'external', name: '外用药品', icon: '🧴', desc: '外用制剂', color: '#8BC34A' },
{ id: 'device', name: '医疗器械', icon: '🩺', desc: '医疗设备', color: '#607D8B' },
{ id: 'health', name: '健康食品', icon: '🥗', desc: '保健食品', color: '#FFC107' }
]
// Mock 商品数据
const mockProducts = {
cold: [
{
id: 'cold1',
name: '布洛芬缓释胶囊',
specification: '0.3g*24粒',
price: 18.5,
originalPrice: 25.8,
image: 'https://picsum.photos/300/300?random=cold1',
manufacturer: '修正药业',
sales: 2560,
badge: '热销'
},
{
id: 'cold2',
name: '板蓝根颗粒',
specification: '10g*20袋',
price: 22.8,
originalPrice: 29.9,
image: 'https://picsum.photos/300/300?random=cold2',
manufacturer: '白云山',
sales: 1890,
badge: '推荐'
},
{
id: 'cold3',
name: '连花清瘟胶囊',
specification: '0.35g*36粒',
price: 42.8,
originalPrice: 48.0,
image: 'https://picsum.photos/300/300?random=cold3',
manufacturer: '以岭药业',
sales: 3200,
badge: '爆款'
},
{
id: 'cold4',
name: '对乙酰氨基酚片',
specification: '0.5g*12片',
price: 8.9,
originalPrice: 12.0,
image: 'https://picsum.photos/300/300?random=cold4',
manufacturer: '强生制药',
sales: 1420,
badge: '特价'
},
{
id: 'cold5',
name: '感冒清热颗粒',
specification: '3g*10袋',
price: 16.5,
originalPrice: 19.9,
image: 'https://picsum.photos/300/300?random=cold5',
manufacturer: '同仁堂',
sales: 980,
badge: '新品'
},
{
id: 'cold6',
name: '复方氨酚烷胺片',
specification: '10片/盒',
price: 12.8,
originalPrice: 15.0,
image: 'https://picsum.photos/300/300?random=cold6',
manufacturer: '三九医药',
sales: 1650,
badge: '家庭装'
}
],
stomach: [
{
id: 'stomach1',
name: '胃康灵胶囊',
specification: '0.4g*24粒',
price: 32.8,
originalPrice: 38.5,
image: 'https://picsum.photos/300/300?random=stomach1',
manufacturer: '三九医药',
sales: 890,
badge: '热销'
},
{
id: 'stomach2',
name: '奥美拉唑肠溶胶囊',
specification: '20mg*14粒',
price: 28.5,
originalPrice: 35.0,
image: 'https://picsum.photos/300/300?random=stomach2',
manufacturer: '阿斯利康',
sales: 1250,
badge: '处方药'
},
{
id: 'stomach3',
name: '健胃消食片',
specification: '0.8g*32片',
price: 15.9,
originalPrice: 19.9,
image: 'https://picsum.photos/300/300?random=stomach3',
manufacturer: '江中制药',
sales: 2100,
badge: '推荐'
},
{
id: 'stomach4',
name: '蒙脱石散',
specification: '3g*10袋',
price: 18.6,
originalPrice: 22.0,
image: 'https://picsum.photos/300/300?random=stomach4',
manufacturer: '益普生',
sales: 1780,
badge: '止泻'
},
{
id: 'stomach5',
name: '多潘立酮片',
specification: '10mg*30片',
price: 22.8,
originalPrice: 26.5,
image: 'https://picsum.photos/300/300?random=stomach5',
manufacturer: '西安杨森',
sales: 950,
badge: '促消化'
},
{
id: 'stomach6',
name: '铝碳酸镁咀嚼片',
specification: '0.5g*20片',
price: 25.9,
originalPrice: 29.9,
image: 'https://picsum.photos/300/300?random=stomach6',
manufacturer: '拜耳',
sales: 1320,
badge: '护胃'
}
],
pain: [
{
id: 'pain1',
name: '阿莫西林胶囊',
specification: '0.25g*24粒',
price: 28.5,
originalPrice: 35.0,
image: 'https://picsum.photos/300/300?random=pain1',
manufacturer: '华北制药',
sales: 1560,
badge: '处方药'
},
{
id: 'pain2',
name: '双氯芬酸钠缓释片',
specification: '75mg*10片',
price: 19.8,
originalPrice: 24.0,
image: 'https://picsum.photos/300/300?random=pain2',
manufacturer: '诺华制药',
sales: 1280,
badge: '止痛'
},
{
id: 'pain3',
name: '云南白药胶囊',
specification: '0.25g*32粒',
price: 35.9,
originalPrice: 42.0,
image: 'https://picsum.photos/300/300?random=pain3',
manufacturer: '云南白药',
sales: 2350,
badge: '经典'
},
{
id: 'pain4',
name: '塞来昔布胶囊',
specification: '0.2g*10粒',
price: 48.6,
originalPrice: 55.0,
image: 'https://picsum.photos/300/300?random=pain4',
manufacturer: '辉瑞',
sales: 890,
badge: '抗炎'
},
{
id: 'pain5',
name: '布洛芬片',
specification: '0.1g*24片',
price: 12.5,
originalPrice: 15.0,
image: 'https://picsum.photos/300/300?random=pain5',
manufacturer: '中美史克',
sales: 1680,
badge: '经济装'
},
{
id: 'pain6',
name: '头孢克肟胶囊',
specification: '0.1g*6粒',
price: 32.8,
originalPrice: 38.0,
image: 'https://picsum.photos/300/300?random=pain6',
manufacturer: '广州白云山',
sales: 1120,
badge: '抗生素'
}
]
}
// 补充其他分类的默认数据(简化版)
const generateDefaultProducts = (categoryId: string) => {
const baseProducts = [
{ name: '通用药品1', price: 25.8, manufacturer: '知名药企', sales: 1200 },
{ name: '通用药品2', price: 18.5, manufacturer: '知名药企', sales: 950 },
{ name: '通用药品3', price: 32.0, manufacturer: '知名药企', sales: 1450 },
{ name: '通用药品4', price: 22.8, manufacturer: '知名药企', sales: 880 },
{ name: '通用药品5', price: 28.9, manufacturer: '知名药企', sales: 1100 },
{ name: '通用药品6', price: 19.9, manufacturer: '知名药企', sales: 920 }
]
return baseProducts.map((product, index) => ({
id: `${categoryId}${index + 1}`,
...product,
specification: '规格待定',
originalPrice: product.price * 1.2,
image: `https://picsum.photos/300/300?random=${categoryId}${index}`,
badge: index === 0 ? '热销' : index === 1 ? '推荐' : ''
}))
}
// 生命周期
onMounted(() => {
initPage()
})
// 初始化页面
const initPage = () => {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
// 加载分类数据
primaryCategories.value = medicineCategories
// 默认加载感冒发烧分类
selectPrimaryCategory('cold')
}
// 选择一级分类
const selectPrimaryCategory = (categoryId: string) => {
activePrimary.value = categoryId
// 更新当前分类信息
const category = medicineCategories.find(cat => cat.id === categoryId)
if (category) {
currentCategoryName.value = category.name
currentCategoryDesc.value = category.desc
}
// 加载对应商品
if (mockProducts[categoryId]) {
productList.value = mockProducts[categoryId]
} else {
productList.value = generateDefaultProducts(categoryId)
}
hasMore.value = true
}
// 添加到购物车
const addToCart = (product: any) => {
uni.showToast({
title: '已添加到购物车',
icon: 'success'
})
cartCount.value++
}
// 导航函数
const navigateToSearch = () => uni.navigateTo({ url: '/pages/medicine/search' })
const navigateToCart = () => uni.navigateTo({ url: '/pages/medicine/cart' })
const navigateToProduct = (product: any) => {
uni.navigateTo({
url: `/pages/medicine/detail?id=${product.id}`
})
}
</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: 60px;
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1400px;
margin: 0 auto;
width: 100%;
}
.search-box {
flex: 1;
max-width: 600px;
background: rgba(255, 255, 255, 0.95);
border-radius: 25px;
padding: 10px 20px;
display: flex;
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.search-box:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
border-color: rgba(255, 255, 255, 0.3);
}
.search-icon {
font-size: 18px;
color: #4CAF50;
margin-right: 12px;
}
.search-placeholder {
font-size: 15px;
color: #666;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.icon {
font-size: 22px;
color: white;
}
.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;
margin-top: 60px;
padding: 0 16px;
max-width: 1400px;
margin-left: auto;
margin-right: auto;
width: 100%;
gap: 20px;
}
/* 左侧一级分类 */
.primary-category {
width: 120px;
background: white;
border-radius: 12px;
padding: 12px 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
flex-shrink: 0;
}
.primary-item {
display: flex;
align-items: center;
padding: 12px 16px;
margin: 4px 8px;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
color: #666;
}
.primary-item:hover {
transform: translateX(2px);
}
.primary-item.active {
color: white !important;
font-weight: bold;
}
.primary-icon {
font-size: 18px;
margin-right: 8px;
min-width: 24px;
text-align: center;
}
.primary-name {
font-size: 14px;
line-height: 1.4;
}
/* 右侧内容区 */
.product-content {
flex: 1;
padding: 16px 0;
}
.category-header {
margin-bottom: 20px;
padding: 0 8px;
}
.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;
padding: 0 12px;
}
.primary-category {
width: 100%;
display: flex;
flex-wrap: wrap;
padding: 8px;
}
.primary-item {
width: calc(25% - 8px);
margin: 4px;
padding: 10px 8px;
text-align: center;
}
.primary-icon {
margin-right: 0;
margin-bottom: 4px;
font-size: 16px;
}
.primary-name {
font-size: 12px;
}
.product-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.search-container {
padding: 0 12px;
height: 55px;
}
.search-box {
padding: 8px 16px;
}
.category-header {
padding: 0;
}
}
/* 中屏手机/小平板 (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) {
.product-grid {
grid-template-columns: repeat(4, 1fr);
gap: 24px;
}
}
/* 大桌面端 (1400px以上) */
@media screen and (min-width: 1400px) {
.product-grid {
grid-template-columns: repeat(5, 1fr);
gap: 24px;
}
}
</style>