继续补充功能页面,consumer模块完成度70%

This commit is contained in:
2026-01-26 08:16:41 +08:00
parent 0ed62a8258
commit be90f1213b
17 changed files with 4859 additions and 8793 deletions

View File

@@ -1,18 +1,38 @@
<!-- 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 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">
<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
@@ -94,6 +114,7 @@ import { ref, onMounted } from 'vue'
// 响应式数据
const statusBarHeight = ref(0)
const headerHeight = ref(44) // 默认头部高度
const primaryCategories = ref<any[]>([])
const productList = ref<any[]>([])
const activePrimary = ref<string>('cold')
@@ -126,6 +147,8 @@ const mockProducts = {
cold: [
{
id: 'cold1',
shopId: 'shop_001',
shopName: '修正药业官方旗舰店',
name: '布洛芬缓释胶囊',
specification: '0.3g*24粒',
price: 18.5,
@@ -137,6 +160,8 @@ const mockProducts = {
},
{
id: 'cold2',
shopId: 'shop_002',
shopName: '白云山大药房',
name: '板蓝根颗粒',
specification: '10g*20袋',
price: 22.8,
@@ -148,6 +173,8 @@ const mockProducts = {
},
{
id: 'cold3',
shopId: 'shop_003',
shopName: '以岭药业自营店',
name: '连花清瘟胶囊',
specification: '0.35g*36粒',
price: 42.8,
@@ -159,6 +186,8 @@ const mockProducts = {
},
{
id: 'cold4',
shopId: 'shop_004',
shopName: '强生制药旗舰店',
name: '对乙酰氨基酚片',
specification: '0.5g*12片',
price: 8.9,
@@ -170,6 +199,8 @@ const mockProducts = {
},
{
id: 'cold5',
shopId: 'shop_005',
shopName: '同仁堂大药房',
name: '感冒清热颗粒',
specification: '3g*10袋',
price: 16.5,
@@ -181,6 +212,8 @@ const mockProducts = {
},
{
id: 'cold6',
shopId: 'shop_006',
shopName: '三九医药旗舰店',
name: '复方氨酚烷胺片',
specification: '10片/盒',
price: 12.8,
@@ -195,6 +228,8 @@ const mockProducts = {
stomach: [
{
id: 'stomach1',
shopId: 'shop_006',
shopName: '三九医药旗舰店',
name: '胃康灵胶囊',
specification: '0.4g*24粒',
price: 32.8,
@@ -206,6 +241,8 @@ const mockProducts = {
},
{
id: 'stomach2',
shopId: 'shop_007',
shopName: '阿斯利康医药',
name: '奥美拉唑肠溶胶囊',
specification: '20mg*14粒',
price: 28.5,
@@ -217,6 +254,8 @@ const mockProducts = {
},
{
id: 'stomach3',
shopId: 'shop_008',
shopName: '江中制药旗舰店',
name: '健胃消食片',
specification: '0.8g*32片',
price: 15.9,
@@ -228,6 +267,8 @@ const mockProducts = {
},
{
id: 'stomach4',
shopId: 'shop_009',
shopName: '益普生大药房',
name: '蒙脱石散',
specification: '3g*10袋',
price: 18.6,
@@ -239,6 +280,8 @@ const mockProducts = {
},
{
id: 'stomach5',
shopId: 'shop_010',
shopName: '西安杨森旗舰店',
name: '多潘立酮片',
specification: '10mg*30片',
price: 22.8,
@@ -250,6 +293,8 @@ const mockProducts = {
},
{
id: 'stomach6',
shopId: 'shop_011',
shopName: '拜耳医药自营店',
name: '铝碳酸镁咀嚼片',
specification: '0.5g*20片',
price: 25.9,
@@ -264,6 +309,8 @@ const mockProducts = {
pain: [
{
id: 'pain1',
shopId: 'shop_012',
shopName: '华北制药旗舰店',
name: '阿莫西林胶囊',
specification: '0.25g*24粒',
price: 28.5,
@@ -275,6 +322,8 @@ const mockProducts = {
},
{
id: 'pain2',
shopId: 'shop_013',
shopName: '诺华制药旗舰店',
name: '双氯芬酸钠缓释片',
specification: '75mg*10片',
price: 19.8,
@@ -286,6 +335,8 @@ const mockProducts = {
},
{
id: 'pain3',
shopId: 'shop_014',
shopName: '云南白药旗舰店',
name: '云南白药胶囊',
specification: '0.25g*32粒',
price: 35.9,
@@ -297,6 +348,8 @@ const mockProducts = {
},
{
id: 'pain4',
shopId: 'shop_015',
shopName: '辉瑞医药旗舰店',
name: '塞来昔布胶囊',
specification: '0.2g*10粒',
price: 48.6,
@@ -308,6 +361,8 @@ const mockProducts = {
},
{
id: 'pain5',
shopId: 'shop_016',
shopName: '中美史克大药房',
name: '布洛芬片',
specification: '0.1g*24片',
price: 12.5,
@@ -319,6 +374,8 @@ const mockProducts = {
},
{
id: 'pain6',
shopId: 'shop_002',
shopName: '白云山大药房',
name: '头孢克肟胶囊',
specification: '0.1g*6粒',
price: 32.8,
@@ -344,6 +401,8 @@ const generateDefaultProducts = (categoryId: string) => {
return baseProducts.map((product, index) => ({
id: `${categoryId}${index + 1}`,
shopId: `shop_default_${categoryId}_${index}`, // 确保不同分类店铺ID不同
shopName: '平台自营大药房',
...product,
specification: '规格待定',
originalPrice: product.price * 1.2,
@@ -419,8 +478,15 @@ onLoad((options: any) => {
}, 100)
}
} else {
console.log('⚠️ onLoad中未找到分类参数')
console.log('保持当前分类显示:', activePrimary.value)
console.log('⚠️ onLoad中未找到分类参数,使用默认分类')
// 默认选中第一个分类
const defaultCategory = 'cold'
console.log('默认分类:', defaultCategory)
// 无论如何都重新加载一次默认分类的数据
setTimeout(() => {
selectPrimaryCategory(defaultCategory)
}, 100)
}
console.log('=== category页面onLoad执行完成 ===')
@@ -505,6 +571,10 @@ const initPage = () => {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
// 保持与主页一致的固定高度计算,不进行动态调整
// 这样在移动端会与主页的视觉体验保持一致主页占位符固定为44px
headerHeight.value = 10
// 获取页面参数
const pages = getCurrentPages()
if (pages.length > 0) {
@@ -585,6 +655,41 @@ const selectPrimaryCategory = (categoryId: string) => {
// 添加到购物车
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('解析购物车数据失败', 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'
@@ -597,7 +702,48 @@ const navigateToSearch = () => uni.navigateTo({ url: '/pages/mall/consumer/searc
const navigateToCart = () => uni.navigateTo({ url: '/pages/medicine/cart' })
const navigateToProduct = (product: any) => {
uni.navigateTo({
url: `/pages/medicine/detail?id=${product.id}`
url: `/pages/mall/consumer/product-detail?productId=${product.id}`
})
}
// 相机功能
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>
@@ -611,7 +757,6 @@ const navigateToProduct = (product: any) => {
flex-direction: column;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
}
/* 搜索栏 */
.search-bar {
position: fixed;
@@ -623,8 +768,10 @@ const navigateToProduct = (product: any) => {
box-shadow: 0 2px 12px rgba(76, 175, 80, 0.15);
}
/* 搜索栏 */
/* 导航栏搜索框容器内边距调整 */
.search-container {
height: 60px;
height: 44px; /* 调整为与消息页一致的高度 */
padding: 0 16px;
display: flex;
align-items: center;
@@ -634,44 +781,90 @@ const navigateToProduct = (product: any) => {
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: rgba(255, 255, 255, 0.95);
border-radius: 25px;
padding: 10px 20px;
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;
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;
width: 100%;
height: 32px; /* 减小高度与顶部高度44px适配略小于顶部高度 */
}
.search-placeholder {
font-size: 15px;
color: #666;
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;
@@ -693,14 +886,14 @@ const navigateToProduct = (product: any) => {
.category-content {
display: flex;
flex-direction: row; /* 强制水平排列 */
margin-top: 60px;
/* margin-top: 44px; 已通过 style 动态绑定 */
padding: 0 16px;
max-width: 1400px;
margin-left: auto;
margin-right: auto;
width: 100%;
gap: 20px;
height: calc(100vh - 60px); /* 设置固定高度,减去头部高度 */
/* height: calc(100vh - 44px); 已通过 style 动态绑定 */
overflow: hidden; /* 防止整体滚动 */
}
@@ -996,11 +1189,59 @@ const navigateToProduct = (product: any) => {
}
.product-grid {
grid-template-columns: 1fr;
gap: 12px;
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;
@@ -1175,4 +1416,4 @@ const navigateToProduct = (product: any) => {
font-size: 24px;
}
}
</style>
</style>