Files
medical-mall/pages/mall/consumer/indexgood.uvue
2026-01-23 17:31:07 +08:00

2114 lines
41 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.
<!-- pages/mall/consumer/index.uvue -->
<template>
<view class="medic-home">
<!-- 智能顶部导航栏 - 添加滚动隐藏效果 -->
<view
class="smart-navbar"
:style="{
paddingTop: statusBarHeight + 'px',
transform: showNavbar ? 'translateY(0)' : 'translateY(-100%)',
opacity: showNavbar ? 1 : 0
}"
>
<view class="nav-container">
<!-- 品牌标识区域 - 响应式显示 -->
<view class="brand-section">
<!-- 品牌标识 - 在电脑端和平板端显示,小屏幕隐藏 -->
<view class="brand-logo-area" :class="{ 'hidden-on-mobile': isMobile }">
<view class="brand-info">
<text class="brand-name">康乐医药商城</text>
<text class="brand-tag">官方认证·正品保障</text>
</view>
</view>
<!-- 导航栏内搜索框 - 自适应平铺 -->
<view class="nav-search-container">
<view class="nav-search" @click="navigateToSearch">
<view class="nav-search-box">
<text class="nav-search-icon">🔍</text>
<!-- 小屏幕只显示搜索图标,隐藏搜索工具 -->
<view class="nav-search-tools" :class="{ 'hidden-on-mobile': isMobile }">
<text class="nav-tool-item">语音</text>
<text class="nav-tool-item">拍照</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 导航栏占位符 - 确保内容正确布局 -->
<view class="navbar-placeholder" :style="{ height: (statusBarHeight + 100) + 'px' }"></view>
<!-- 主内容区 -->
<scroll-view
scroll-y
class="main-scroll"
:style="{ height: scrollHeight + 'px' }"
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="loadMore"
@scroll="handleScroll"
>
<!-- 智能健康卡片 -->
<view class="smart-health-card">
<view class="health-content">
<view class="health-header">
<text class="health-title">智能健康助手</text>
<text class="health-subtitle">根据您的健康数据推荐</text>
</view>
<view class="health-tips">
<text class="tip-item">💡 按时用药提醒</text>
<text class="tip-item">📋 健康记录跟踪</text>
<text class="tip-item">🩺 在线问诊咨询</text>
</view>
</view>
</view>
<!-- 智能分类网格 - 完全响应式 -->
<view class="smart-categories">
<view class="section-header">
<text class="section-title">智能分类</text>
<text class="section-desc">快速定位所需药品</text>
</view>
<view class="category-grid">
<view
v-for="category in categories"
:key="category.id"
class="category-card"
@click="switchCategory(category)"
:style="{ '--card-color': category.color }"
>
<view class="card-icon">
<text>{{ category.icon }}</text>
</view>
<text class="card-name">{{ category.name }}</text>
<text class="card-desc">{{ category.desc }}</text>
</view>
</view>
</view>
<!-- 健康资讯轮播 -->
<view class="health-news">
<view class="news-header">
<text class="news-title">健康资讯</text>
<text class="news-more" @click="navigateToNews">更多 ></text>
</view>
<swiper
class="news-swiper"
:autoplay="true"
:interval="4000"
:duration="500"
:circular="true"
:indicator-dots="true"
indicator-color="rgba(255,255,255,0.3)"
indicator-active-color="#4CAF50"
>
<swiper-item
v-for="news in healthNews"
:key="news.id"
class="news-item"
>
<view class="news-content" @click="viewNewsDetail(news)">
<image
class="news-image"
:src="news.image"
mode="aspectFill"
/>
<view class="news-overlay">
<text class="news-tag">{{ news.tag }}</text>
<text class="news-caption">{{ news.title }}</text>
</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- 智能服务入口 -->
<view class="smart-services">
<view class="services-grid">
<view class="service-card" @click="navigateToConsultation">
<view class="service-icon" style="background: #2196F3;">
<text>👨‍⚕️</text>
</view>
<text class="service-name">在线问诊</text>
<text class="service-desc">三甲医生在线</text>
</view>
<view class="service-card" @click="navigateToPrescription">
<view class="service-icon" style="background: #4CAF50;">
<text>📋</text>
</view>
<text class="service-name">电子处方</text>
<text class="service-desc">医生开方购药</text>
</view>
<view class="service-card" @click="navigateToOTC">
<view class="service-icon" style="background: #FF9800;">
<text>💊</text>
</view>
<text class="service-name">非处方药</text>
<text class="service-desc">安全自主选购</text>
</view>
<view class="service-card" @click="navigateToHealthTools">
<view class="service-icon" style="background: #9C27B0;">
<text>🩺</text>
</view>
<text class="service-name">健康工具</text>
<text class="service-desc">健康管理助手</text>
</view>
</view>
</view>
<!-- 热销药品专区 -->
<view class="hot-products">
<view class="section-header">
<view class="title-section">
<text class="section-icon">🔥</text>
<text class="section-title">热销药品</text>
</view>
<view class="sort-tabs">
<text
v-for="tab in sortTabs"
:key="tab.id"
:class="['sort-tab', { active: activeSort === tab.id }]"
@click="switchSort(tab.id)"
>
{{ tab.name }}
</text>
</view>
</view>
<view class="products-grid">
<view
v-for="product in hotProducts"
: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 class="product-action">
<view class="cart-btn" @click.stop="addToCart(product)">
<text class="cart-icon">+</text>
<text class="cart-text">加入购物车</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 家庭常备药 -->
<view class="family-medicine">
<view class="section-header">
<view class="title-section">
<text class="section-icon">🏠</text>
<text class="section-title">家庭常备药</text>
</view>
<text class="section-subtitle">守护全家健康</text>
</view>
<view class="family-grid">
<view
v-for="item in familyItems"
:key="item.id"
class="family-item"
@click="navigateToCategory(item.categoryId)"
>
<view class="family-icon" :style="{ backgroundColor: item.color }">
<text>{{ item.icon }}</text>
</view>
<text class="family-name">{{ item.name }}</text>
<text class="family-desc">{{ item.desc }}</text>
</view>
</view>
</view>
<!-- 智能推荐 -->
<view class="smart-recommend">
<view class="section-header">
<view class="title-section">
<text class="section-icon">✨</text>
<text class="section-title">智能推荐</text>
</view>
<view class="recommend-filters">
<text
v-for="filter in recommendFilters"
:key="filter.id"
:class="['filter-item', { active: activeFilter === filter.id }]"
@click="switchFilter(filter.id)"
>
{{ filter.name }}
</text>
</view>
</view>
<view class="recommend-grid">
<view
v-for="product in recommendedProducts"
:key="product.id"
class="recommend-product"
@click="navigateToProduct(product)"
>
<view class="product-image-container">
<image
class="product-image"
:src="product.image"
mode="aspectFill"
/>
<view class="product-tags">
<text v-if="product.tag" class="product-tag">{{ product.tag }}</text>
<text v-if="product.featured" class="featured-tag">{{ product.featured }}</text>
</view>
</view>
<view class="product-details">
<text class="product-title">{{ product.name }}</text>
<text class="product-specification">{{ product.specification }}</text>
<view class="product-rating">
<view class="rating-stars">
<text class="star-icon">⭐</text>
<text class="rating-value">{{ product.rating }}</text>
</view>
<text class="reviews-count">{{ product.reviews }}条评价</text>
</view>
<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-actions">
<view class="add-to-cart" @click.stop="addToCart(product)">
<text class="cart-icon">🛒</text>
</view>
</view>
</view>
</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<view v-if="!hasMore && recommendedProducts.length > 0" class="no-more">
<text class="no-more-text">--- 已加载全部内容 ---</text>
</view>
</view>
<!-- 健康提醒 -->
<view class="health-reminder">
<view class="reminder-content">
<text class="reminder-icon">⏰</text>
<view class="reminder-text">
<text class="reminder-title">健康提醒</text>
<text class="reminder-desc">您有1个待用药提醒点击查看详情</text>
</view>
<view class="reminder-action" @click="navigateToReminders">
<text class="action-text">查看</text>
</view>
</view>
</view>
<!-- 底部安全区域 -->
<view class="safe-area"></view>
</scroll-view>
</view>
</template>
<script setup lang="uts">
import { ref, reactive, onMounted } from 'vue'
// 响应式数据
const statusBarHeight = ref(0)
const scrollHeight = ref(0)
const refreshing = ref(false)
const loading = ref(false)
const hasMore = ref(true)
const activeSort = ref('sales')
const activeFilter = ref('recommend')
const currentPage = ref(1)
// 屏幕尺寸检测
const isMobile = ref(false)
// 导航栏显示控制
const showNavbar = ref(true)
const lastScrollTop = ref(0)
const scrollThreshold = 30 // 降低滚动阈值,使其更灵敏
const scrollingUp = ref(false)
// 分类数据
const categories = [
{ 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' }
]
// 排序标签
const sortTabs = [
{ id: 'sales', name: '销量' },
{ id: 'price', name: '价格' },
{ id: 'new', name: '新品' },
{ id: 'recommend', name: '推荐' }
]
// 推荐筛选器
const recommendFilters = [
{ id: 'recommend', name: '智能推荐' },
{ id: 'hot', name: '热门商品' },
{ id: 'discount', name: '限时优惠' },
{ id: 'quality', name: '品质优选' }
]
// 健康资讯
const healthNews = [
{
id: 'news1',
title: '秋季流感预防指南,科学防护健康过冬',
tag: '健康科普',
image: 'https://picsum.photos/800/400?random=health1'
},
{
id: 'news2',
title: '家庭常备药清单,为家人健康保驾护航',
tag: '家庭用药',
image: 'https://picsum.photos/800/400?random=health2'
},
{
id: 'news3',
title: '慢性病科学管理,提高生活质量',
tag: '健康管理',
image: 'https://picsum.photos/800/400?random=health3'
}
]
// 热销药品
const hotProducts = [
{
id: 'hot1',
name: '布洛芬缓释胶囊',
specification: '0.3g*24粒',
price: 18.5,
originalPrice: 25.8,
image: 'https://picsum.photos/300/300?random=medicine1',
manufacturer: '修正药业',
sales: 2560,
badge: '热销'
},
{
id: 'hot2',
name: '板蓝根颗粒',
specification: '10g*20袋',
price: 22.8,
originalPrice: 29.9,
image: 'https://picsum.photos/300/300?random=medicine2',
manufacturer: '白云山',
sales: 1890,
badge: '推荐'
},
{
id: 'hot3',
name: '维生素C片',
specification: '100mg*100片',
price: 15.9,
originalPrice: 19.9,
image: 'https://picsum.photos/300/300?random=medicine3',
manufacturer: '养生堂',
sales: 1420,
badge: '特价'
},
{
id: 'hot4',
name: '胃康灵胶囊',
specification: '0.4g*24粒',
price: 32.8,
originalPrice: 38.5,
image: 'https://picsum.photos/300/300?random=medicine4',
manufacturer: '三九医药',
sales: 890,
badge: '新品'
}
]
// 家庭常备药
const familyItems = [
{
id: 'family1',
name: '创可贴',
desc: '伤口护理',
icon: '🩹',
color: '#FF5722',
categoryId: 'external'
},
{
id: 'family2',
name: '体温计',
desc: '健康监测',
icon: '🌡️',
color: '#2196F3',
categoryId: 'device'
},
{
id: 'family3',
name: '消毒酒精',
desc: '环境消毒',
icon: '🧪',
color: '#4CAF50',
categoryId: 'external'
},
{
id: 'family4',
name: '口罩',
desc: '日常防护',
icon: '😷',
color: '#607D8B',
categoryId: 'device'
},
{
id: 'family5',
name: '退热贴',
desc: '物理降温',
icon: '🧊',
color: '#00BCD4',
categoryId: 'cold'
},
{
id: 'family6',
name: '棉签纱布',
desc: '伤口处理',
icon: '🩹',
color: '#FF9800',
categoryId: 'external'
}
]
// 推荐商品
const recommendedProducts = [
{
id: 'rec1',
name: '阿莫西林胶囊',
specification: '0.25g*24粒',
price: 28.5,
originalPrice: 35.0,
image: 'https://picsum.photos/350/350?random=rec1',
rating: 4.8,
reviews: 156,
tag: '处方药',
featured: '医生推荐'
},
{
id: 'rec2',
name: '连花清瘟胶囊',
specification: '0.35g*36粒',
price: 42.8,
originalPrice: 48.0,
image: 'https://picsum.photos/350/350?random=rec2',
rating: 4.9,
reviews: 289,
tag: '中成药',
featured: '热销爆款'
},
{
id: 'rec3',
name: '盐酸氨溴索口服液',
specification: '100ml',
price: 35.9,
originalPrice: 42.0,
image: 'https://picsum.photos/350/350?random=rec3',
rating: 4.7,
reviews: 132,
tag: '止咳化痰',
featured: '家庭必备'
},
{
id: 'rec4',
name: '氯雷他定片',
specification: '10mg*6片',
price: 18.6,
originalPrice: 22.0,
image: 'https://picsum.photos/350/350?random=rec4',
rating: 4.6,
reviews: 98,
tag: '抗过敏',
featured: '季节必备'
}
]
// 生命周期
onMounted(() => {
initPage()
})
// 页面显示时重置状态
onShow(() => {
console.log('=== index页面onShow被调用 ===')
console.log('主页重新显示,重置页面状态')
// 重置导航栏显示状态
showNavbar.value = true
lastScrollTop.value = 0
// 重置滚动位置到顶部
// 注意这里不能直接操作scroll-view的滚动位置
// 但可以重置一些页面状态
// 注意这里不再清除selectedCategory
// 让分类页面在成功读取后自行清除
// 这样可以确保分类页面能正确读取到传递的数据
console.log('=== index页面onShow执行完成 ===')
})
// 初始化页面
const initPage = () => {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
// 计算滚动区域高度 - 使用整个窗口高度
const windowHeight = systemInfo.windowHeight
scrollHeight.value = windowHeight
// 检测屏幕尺寸
const screenWidth = systemInfo.screenWidth || systemInfo.windowWidth
isMobile.value = screenWidth < 768 // 小于768px为小屏幕
}
// 处理滚动事件
const handleScroll = (event: any) => {
const scrollTop = event.detail.scrollTop
const currentTime = Date.now()
// 判断滚动方向
if (scrollTop > lastScrollTop.value) {
// 向下滚动
scrollingUp.value = false
// 向下滚动超过阈值时隐藏导航栏
if (scrollTop > scrollThreshold && showNavbar.value) {
showNavbar.value = false
}
} else if (scrollTop < lastScrollTop.value) {
// 向上滚动
scrollingUp.value = true
// 向上滚动时显示导航栏
if (!showNavbar.value) {
showNavbar.value = true
}
}
// 滚动到顶部时强制显示导航栏
if (scrollTop <= 10) {
showNavbar.value = true
}
lastScrollTop.value = scrollTop
// 调试信息(开发时可启用)
// console.log(`Scroll: ${scrollTop}, ShowNavbar: ${showNavbar.value}, ScrollingUp: ${scrollingUp.value}`)
}
// 重置导航栏显示状态(例如点击回到顶部时)
const resetNavbar = () => {
showNavbar.value = true
lastScrollTop.value = 0
}
// 切换分类 - 跳转到分类页面并传递分类ID
const switchCategory = (category: any) => {
console.log('=== switchCategory函数开始执行 ===')
console.log('分类ID:', category.id, '分类名称:', category.name)
// 清除可能存在的旧数据
uni.removeStorageSync('selectedCategory')
// 生成唯一的时间戳和随机参数,确保每次跳转都是新的页面
const timestamp = Date.now()
const randomParam = Math.random().toString(36).substring(2, 8)
// 构建带参数的URL直接通过URL传递分类信息
const url = `/pages/mall/consumer/category?categoryId=${category.id}&name=${encodeURIComponent(category.name)}&timestamp=${timestamp}&random=${randomParam}`
console.log('跳转URL:', url)
console.log('分类ID参数:', category.id)
console.log('时间戳:', timestamp)
console.log('随机参数:', randomParam)
// 使用uni.reLaunch跳转到分类页面关闭所有页面并打开新页面
// 这样可以确保每次跳转都是全新的页面实例,避免页面缓存问题
// 虽然这会关闭当前主页,但可以确保分类页面总是重新加载
uni.reLaunch({
url: url,
success: () => {
console.log('✅ 使用reLaunch跳转到分类页面成功')
console.log('=== switchCategory函数执行完成 ===')
},
fail: (err) => {
console.error('❌ 跳转到分类页面失败:', err)
console.log('=== switchCategory函数执行完成 ===')
}
})
}
// 切换排序
const switchSort = (sortId: string) => {
activeSort.value = sortId
// 这里可以添加排序逻辑
}
// 切换筛选器
const switchFilter = (filterId: string) => {
activeFilter.value = filterId
// 这里可以添加筛选逻辑
}
// 查看新闻详情
const viewNewsDetail = (news: any) => {
uni.navigateTo({
url: `/pages/news/detail?id=${news.id}`
})
}
// 下拉刷新
const onRefresh = () => {
refreshing.value = true
setTimeout(() => {
refreshing.value = false
uni.showToast({
title: '刷新成功',
icon: 'success'
})
}, 1500)
}
// 加载更多
const loadMore = () => {
if (loading.value || !hasMore.value) return
loading.value = true
setTimeout(() => {
// 模拟加载更多数据
const newProducts = [...recommendedProducts].map((item, index) => ({
...item,
id: `new${index}`,
price: Math.floor(item.price * 0.9 + Math.random() * 10)
}))
// 实际项目中应该合并数据
loading.value = false
hasMore.value = recommendedProducts.length < 20
uni.showToast({
title: '加载完成',
icon: 'success'
})
}, 2000)
}
// 添加到购物车
const addToCart = (product: any) => {
uni.showToast({
title: '已添加到购物车',
icon: 'success'
})
}
// 导航函数
const navigateToSearch = () => uni.navigateTo({ url: '/pages/mall/consumer/search' })
const navigateToNews = () => uni.navigateTo({ url: '/pages/news/list' })
const navigateToProduct = (product: any) => {
uni.navigateTo({
url: `/pages/medicine/detail?id=${product.id}`
})
}
const navigateToCategory = (categoryId: string) => {
uni.navigateTo({
url: `/pages/medicine/category?id=${categoryId}`
})
}
const navigateToConsultation = () => uni.navigateTo({ url: '/pages/medicine/consultation' })
const navigateToPrescription = () => uni.navigateTo({ url: '/pages/medicine/prescription' })
const navigateToOTC = () => uni.navigateTo({ url: '/pages/medicine/otc' })
const navigateToHealthTools = () => uni.navigateTo({ url: '/pages/medicine/tools' })
const navigateToReminders = () => uni.navigateTo({ url: '/pages/user/reminders' })
</script>
<style>
/* 全局重置 */
.medic-home * {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.medic-home {
width: 100%;
min-height: 100vh;
background: #f8fafc;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
line-height: 1.5;
display: flex;
flex-direction: column;
}
/* 智能导航栏 - 重新设计布局 */
.smart-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
z-index: 1000;
box-shadow: 0 2px 20px rgba(76, 175, 80, 0.15);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, opacity;
pointer-events: auto; /* 确保导航栏可以交互 */
backface-visibility: hidden; /* 改善动画性能 */
-webkit-backface-visibility: hidden;
}
.nav-container {
height: 100px; /* 增加导航栏高度 */
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1400px;
margin: 0 auto;
width: 100%;
}
/* 品牌区域 - 重新设计为自适应平铺 */
.brand-section {
display: flex;
align-items: center;
width: 100%;
gap: 20px;
flex-wrap: wrap;
justify-content: space-between;
}
/* 品牌标识区域 - 自适应平铺 */
.brand-logo-area {
flex-shrink: 1;
min-width: 120px;
max-width: 200px;
display: flex;
align-items: center;
flex-grow: 0;
}
/* 小屏幕隐藏品牌标识 */
.brand-logo-area.hidden-on-mobile {
display: none;
}
/* 小屏幕隐藏搜索工具 */
.nav-search-tools.hidden-on-mobile {
display: none;
}
.brand-info {
display: flex;
flex-direction: column;
}
.brand-name {
font-size: 18px;
font-weight: bold;
color: white;
letter-spacing: 0.5px;
}
.brand-tag {
font-size: 11px;
color: rgba(255, 255, 255, 0.9);
margin-top: 2px;
}
/* 导航栏搜索框容器 - 自适应平铺 */
.nav-search-container {
flex: 1;
min-width: 0; /* 允许缩小 */
max-width: 100%; /* 确保在小屏幕上不会溢出 */
flex-grow: 1;
}
.nav-search {
width: 100%;
}
.nav-search-box {
background: rgba(255, 255, 255, 0.95);
border-radius: 25px;
padding: 12px 20px;
display: flex;
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
width: 100%;
}
.nav-search-box:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
border-color: rgba(255, 255, 255, 0.3);
}
.nav-search-icon {
font-size: 18px;
color: #4CAF50;
margin-right: 12px;
flex-shrink: 0;
}
.nav-search-tools {
display: flex;
gap: 8px;
margin-left: 12px;
flex-shrink: 0;
}
.nav-tool-item {
font-size: 12px;
color: #4CAF50;
padding: 4px 10px;
background: rgba(76, 175, 80, 0.1);
border-radius: 12px;
white-space: nowrap;
}
/* 导航栏占位符 */
.navbar-placeholder {
width: 100%;
flex-shrink: 0;
}
/* 主内容区域 */
.main-scroll {
flex: 1;
padding: 16px;
max-width: 1400px;
margin-left: auto;
margin-right: auto;
width: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch; /* 改善iOS滚动体验 */
}
/* 智能健康卡片 */
.smart-health-card {
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
color: white;
}
.health-content {
display: flex;
flex-direction: column;
gap: 12px;
}
.health-header {
display: flex;
flex-direction: column;
gap: 4px;
}
.health-title {
font-size: 20px;
font-weight: bold;
}
.health-subtitle {
font-size: 14px;
opacity: 0.9;
}
.health-tips {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 8px;
}
.tip-item {
font-size: 13px;
padding: 6px 12px;
background: rgba(255, 255, 255, 0.2);
border-radius: 20px;
backdrop-filter: blur(10px);
}
/* 智能分类网格 */
.smart-categories {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 20px;
}
.section-title {
font-size: 18px;
font-weight: bold;
color: #333;
}
.section-desc {
font-size: 14px;
color: #666;
}
/* 分类网格布局 */
.category-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 16px;
}
.category-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
background: #f8f9fa;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid transparent;
}
.category-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
border-color: var(--card-color, #4CAF50);
}
.card-icon {
width: 56px;
height: 56px;
border-radius: 28px;
background: var(--card-color, #4CAF50);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
}
.card-icon text {
font-size: 24px;
color: white;
}
.card-name {
font-size: 15px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
text-align: center;
}
.card-desc {
font-size: 12px;
color: #666;
text-align: center;
}
/* 健康资讯 */
.health-news {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.news-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.news-title {
font-size: 18px;
font-weight: bold;
color: #333;
}
.news-more {
font-size: 14px;
color: #4CAF50;
cursor: pointer;
}
.news-swiper {
height: 200px;
border-radius: 12px;
overflow: hidden;
}
.news-content {
position: relative;
height: 100%;
border-radius: 12px;
overflow: hidden;
}
.news-image {
width: 100%;
height: 100%;
display: block;
}
.news-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent);
padding: 20px;
color: white;
}
.news-tag {
display: inline-block;
background: #4CAF50;
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
margin-bottom: 8px;
}
.news-caption {
font-size: 16px;
font-weight: 600;
display: block;
line-height: 1.4;
}
/* 智能服务 */
.smart-services {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px;
}
.service-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
background: #f8f9fa;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
}
.service-card:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.service-icon {
width: 60px;
height: 60px;
border-radius: 30px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
}
.service-icon text {
font-size: 28px;
color: white;
}
.service-name {
font-size: 15px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
}
.service-desc {
font-size: 12px;
color: #666;
}
/* 热销药品 */
.hot-products {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.title-section {
display: flex;
align-items: center;
gap: 8px;
}
.section-icon {
font-size: 20px;
color: #4CAF50;
}
.sort-tabs {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
justify-content: flex-start;
}
.sort-tab {
font-size: 13px;
color: #666;
padding: 6px 16px;
border-radius: 20px;
border: 1px solid #e0e0e0;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
flex-shrink: 0;
flex-grow: 0;
}
.sort-tab.active {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.sort-tab:hover {
background: #f5f5f5;
}
.sort-tab.active:hover {
background: #388E3C;
}
/* 产品网格 */
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
margin-top: 20px;
}
.product-card {
background: #f8f9fa;
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;
}
.cart-text {
font-size: 13px;
}
/* 家庭常备药 */
.family-medicine {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.section-subtitle {
font-size: 14px;
color: #666;
margin-left: 12px;
}
.family-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 16px;
margin-top: 20px;
}
.family-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
background: #f8f9fa;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
}
.family-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.family-icon {
width: 48px;
height: 48px;
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
}
.family-icon text {
font-size: 20px;
color: white;
}
.family-name {
font-size: 14px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
}
.family-desc {
font-size: 12px;
color: #666;
}
/* 智能推荐 */
.smart-recommend {
background: white;
border-radius: 16px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.recommend-filters {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
justify-content: flex-start;
}
.filter-item {
font-size: 13px;
color: #666;
padding: 6px 16px;
border-radius: 20px;
border: 1px solid #e0e0e0;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
flex-shrink: 0;
flex-grow: 0;
}
.filter-item.active {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.filter-item:hover {
background: #f5f5f5;
}
.filter-item.active:hover {
background: #388E3C;
}
.recommend-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-top: 20px;
}
.recommend-product {
background: #f8f9fa;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid #e0e0e0;
}
.recommend-product:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.product-image-container {
position: relative;
height: 180px;
}
.product-image {
width: 100%;
height: 100%;
object-fit: cover;
background: white;
}
.product-tags {
position: absolute;
top: 12px;
left: 12px;
display: flex;
gap: 8px;
}
.product-tag, .featured-tag {
padding: 4px 10px;
border-radius: 10px;
font-size: 11px;
font-weight: 600;
color: white;
}
.product-tag {
background: rgba(76, 175, 80, 0.9);
}
.featured-tag {
background: rgba(255, 87, 34, 0.9);
}
.product-details {
padding: 16px;
}
.product-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
display: block;
line-height: 1.4;
}
.product-specification {
font-size: 13px;
color: #666;
margin-bottom: 12px;
display: block;
}
.product-rating {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-size: 13px;
}
.rating-stars {
display: flex;
align-items: center;
gap: 4px;
}
.star-icon {
font-size: 14px;
color: #FFC107;
}
.rating-value {
font-weight: 600;
color: #333;
}
.reviews-count {
color: #666;
}
.product-actions {
display: flex;
justify-content: flex-end;
margin-top: 12px;
}
.add-to-cart {
width: 36px;
height: 36px;
border-radius: 18px;
background: #4CAF50;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
}
.add-to-cart:hover {
background: #388E3C;
transform: scale(1.1);
}
.cart-icon {
font-size: 16px;
color: white;
}
/* 健康提醒 */
.health-reminder {
background: linear-gradient(135deg, #FF9800 0%, #F57C00 100%);
border-radius: 16px;
padding: 16px 20px;
margin-bottom: 20px;
color: white;
}
.reminder-content {
display: flex;
align-items: center;
gap: 12px;
}
.reminder-icon {
font-size: 24px;
}
.reminder-text {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
}
.reminder-title {
font-size: 15px;
font-weight: 600;
}
.reminder-desc {
font-size: 13px;
opacity: 0.9;
}
.reminder-action {
padding: 6px 16px;
background: rgba(255, 255, 255, 0.2);
border-radius: 20px;
cursor: pointer;
transition: all 0.2s ease;
}
.reminder-action:hover {
background: rgba(255, 255, 255, 0.3);
}
.action-text {
font-size: 13px;
font-weight: 500;
}
/* 加载状态 */
.loading-state {
padding: 40px 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.loading-spinner {
width: 32px;
height: 32px;
border: 3px solid #f0f0f0;
border-top-color: #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 12px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 14px;
color: #666;
}
.no-more {
padding: 30px 0;
text-align: center;
border-top: 1px solid #f0f0f0;
margin-top: 10px;
}
.no-more-text {
font-size: 13px;
color: #999;
}
/* 安全区域 */
.safe-area {
height: 20px;
width: 100%;
}
/* ===== 响应式设计 ===== */
/* 小屏手机 (小于414px) */
@media screen and (max-width: 414px) {
.nav-container {
padding: 0 12px;
height: 90px;
}
.brand-section {
flex-direction: column;
align-items: stretch;
gap: 12px;
justify-content: flex-start;
}
.brand-logo-area {
min-width: auto;
max-width: 100%;
flex-shrink: 0;
width: 100%;
justify-content: center;
}
.brand-info {
align-items: center;
text-align: center;
}
.brand-name {
font-size: 16px;
}
.brand-tag {
font-size: 10px;
}
.nav-search-container {
flex: 1;
width: 100%;
flex-grow: 1;
}
.nav-search-box {
padding: 10px 16px;
}
.nav-search-tools {
display: none;
}
.main-scroll {
padding: 12px;
}
.category-grid {
grid-template-columns: repeat(2, 1fr);
gap: 12px;
}
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.products-grid {
grid-template-columns: 1fr;
}
.recommend-grid {
grid-template-columns: 1fr;
}
.family-grid {
grid-template-columns: repeat(2, 1fr);
}
.news-swiper {
height: 160px;
}
.sort-tabs,
.recommend-filters {
gap: 8px;
justify-content: center;
}
.sort-tab,
.filter-item {
padding: 5px 12px;
font-size: 12px;
flex-grow: 1;
text-align: center;
min-width: 60px;
}
.section-header {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.title-section {
justify-content: center;
}
.sort-tabs,
.recommend-filters {
width: 100%;
}
}
/* 中屏手机/小平板 (415px-768px) */
@media screen and (min-width: 415px) and (max-width: 768px) {
.nav-container {
padding: 0 16px;
height: 95px;
}
.brand-section {
flex-direction: row;
align-items: center;
gap: 15px;
flex-wrap: nowrap;
justify-content: space-between;
}
.brand-logo-area {
min-width: 140px;
max-width: 160px;
flex-shrink: 1;
flex-grow: 0;
}
.brand-name {
font-size: 17px;
}
.nav-search-container {
flex: 1;
min-width: 0;
flex-grow: 1;
}
.nav-search-tools {
display: none;
}
.main-scroll {
/* 移除 margin-top */
}
.category-grid {
grid-template-columns: repeat(3, 1fr);
}
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.products-grid {
grid-template-columns: repeat(2, 1fr);
}
.recommend-grid {
grid-template-columns: repeat(2, 1fr);
}
.family-grid {
grid-template-columns: repeat(3, 1fr);
}
.sort-tabs,
.recommend-filters {
gap: 10px;
justify-content: flex-start;
}
.sort-tab,
.filter-item {
padding: 6px 14px;
font-size: 12px;
flex-grow: 0;
}
.section-header {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.title-section {
justify-content: center;
}
.sort-tabs,
.recommend-filters {
width: 100%;
justify-content: center;
}
}
/* 平板设备 (769px-1024px) */
@media screen and (min-width: 769px) and (max-width: 1024px) {
.nav-container {
padding: 0 24px;
max-width: 100%;
height: 100px;
}
.nav-search-tools .nav-tool-item {
display: none;
}
.main-scroll {
max-width: 100%;
padding: 20px 24px;
}
.category-grid {
grid-template-columns: repeat(4, 1fr);
}
.services-grid {
grid-template-columns: repeat(4, 1fr);
}
.products-grid {
grid-template-columns: repeat(3, 1fr);
}
.recommend-grid {
grid-template-columns: repeat(2, 1fr);
}
.family-grid {
grid-template-columns: repeat(3, 1fr);
}
.news-swiper {
height: 240px;
}
}
/* 桌面端 (1025px以上) */
@media screen and (min-width: 1025px) {
.nav-container {
padding: 0 32px;
height: 100px;
}
.main-scroll {
padding: 24px 32px;
}
.category-grid {
grid-template-columns: repeat(5, 1fr);
}
.services-grid {
grid-template-columns: repeat(4, 1fr);
}
.products-grid {
grid-template-columns: repeat(4, 1fr);
}
.recommend-grid {
grid-template-columns: repeat(3, 1fr);
}
.family-grid {
grid-template-columns: repeat(3, 1fr);
}
.news-swiper {
height: 260px;
}
}
/* 大桌面端 (1400px以上) */
@media screen and (min-width: 1400px) {
.category-grid {
grid-template-columns: repeat(5, 1fr);
gap: 24px;
}
.products-grid {
grid-template-columns: repeat(4, 1fr);
}
.recommend-grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* 暗黑模式适配 */
@media (prefers-color-scheme: dark) {
.medic-home {
background: #121212;
}
.smart-categories,
.health-news,
.smart-services,
.hot-products,
.family-medicine,
.smart-recommend {
background: #1e1e1e;
border-color: #333;
}
.nav-search-box {
background: rgba(30, 30, 30, 0.95);
border-color: #444;
}
.category-card,
.service-card,
.product-card,
.family-item,
.recommend-product {
background: #2d2d2d;
border-color: #444;
}
.section-title,
.card-name,
.service-name,
.product-name,
.family-name,
.product-title,
.section-desc,
.card-desc,
.service-desc,
.product-spec,
.product-specification,
.family-desc {
color: #aaa;
}
.sort-tab,
.filter-item {
background: #333;
border-color: #444;
color: #ccc;
}
.sort-tab.active,
.filter-item.active {
background: #4CAF50;
color: white;
}
.sort-tab:hover,
.filter-item:hover {
background: #444;
}
.sort-tab.active:hover,
.filter-item.active:hover {
background: #388E3C;
}
.nav-tool-item {
background: rgba(76, 175, 80, 0.2);
color: #4CAF50;
}
.manufacturer,
.sales-count,
.reviews-count,
.original-price {
color: #888;
}
}
</style>