consumer模块完成度95%,优化安卓端界面和小程序测试2
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<!-- pages/main/cart.uvue -->
|
||||
<!-- pages/main/cart.uvue -->
|
||||
<template>
|
||||
<view class="cart-page">
|
||||
<!-- 智能顶部导航栏 - 与消息页保持一致 -->
|
||||
@@ -103,6 +103,7 @@
|
||||
<view v-if="!isManageMode" class="total-info">
|
||||
<text class="total-text">合计:</text>
|
||||
<text class="total-price">¥{{ totalPrice }}</text>
|
||||
<text v-if="parseFloat(memberSavedAmount) > 0" class="member-saved">会员已省¥{{ memberSavedAmount }}</text>
|
||||
</view>
|
||||
<button v-if="!isManageMode" class="checkout-btn" @click="goToCheckout">
|
||||
去结算({{ selectedCount }})
|
||||
@@ -188,6 +189,8 @@ type LocalCartItem = {
|
||||
shopName: string
|
||||
name: string
|
||||
price: number
|
||||
originalPrice: number // 原价
|
||||
memberPrice: number // 会员价
|
||||
image: string
|
||||
spec: string
|
||||
quantity: number
|
||||
@@ -284,7 +287,19 @@ const selectedCount = computed(() => {
|
||||
const totalPrice = computed(() => {
|
||||
return cartItems.value
|
||||
.filter((item: LocalCartItem) => item.selected)
|
||||
.reduce((sum: number, item: LocalCartItem) => sum + item.price * item.quantity, 0)
|
||||
.reduce((sum: number, item: LocalCartItem) => {
|
||||
// 优先使用会员价,如果没有会员价则使用原价
|
||||
const finalPrice = item.memberPrice > 0 && item.memberPrice < item.price ? item.memberPrice : item.price
|
||||
return sum + finalPrice * item.quantity
|
||||
}, 0)
|
||||
.toFixed(2)
|
||||
})
|
||||
|
||||
// 计算会员节省金额
|
||||
const memberSavedAmount = computed(() => {
|
||||
return cartItems.value
|
||||
.filter((item: LocalCartItem) => item.selected && item.memberPrice > 0 && item.memberPrice < item.price)
|
||||
.reduce((sum: number, item: LocalCartItem) => sum + (item.price - item.memberPrice) * item.quantity, 0)
|
||||
.toFixed(2)
|
||||
})
|
||||
|
||||
@@ -393,6 +408,18 @@ const loadCartData = async () => {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
// 获取会员折扣信息
|
||||
let memberDiscount = 1.0
|
||||
try {
|
||||
const memberInfo = await supabaseService.getUserMemberInfo()
|
||||
const discountRaw = memberInfo.get('discount')
|
||||
if (discountRaw != null) {
|
||||
memberDiscount = discountRaw as number
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('获取会员信息失败,使用默认折扣:', e)
|
||||
}
|
||||
|
||||
// 从Supabase加载购物车数据
|
||||
const supabaseCartItems = await supabaseService.getCartItems()
|
||||
|
||||
@@ -405,12 +432,21 @@ const loadCartData = async () => {
|
||||
const shopId = (item.shop_id != null && item.shop_id !== '') ? item.shop_id : 'default_shop'
|
||||
const shopName = (item.shop_name != null && item.shop_name !== '') ? item.shop_name : '商城优选'
|
||||
|
||||
// 计算会员价
|
||||
const originalPrice = item.product_price != null ? item.product_price : 0
|
||||
let memberPrice = 0
|
||||
if (memberDiscount > 0 && memberDiscount < 1 && originalPrice > 0) {
|
||||
memberPrice = Math.round(originalPrice * memberDiscount * 100) / 100
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
shopId: shopId,
|
||||
shopName: shopName,
|
||||
name: item.product_name ?? '未知商品',
|
||||
price: item.product_price != null ? item.product_price : 0,
|
||||
price: originalPrice,
|
||||
originalPrice: originalPrice,
|
||||
memberPrice: memberPrice,
|
||||
image: item.product_image ?? '/static/images/default-product.png',
|
||||
spec: item.product_specification ?? '标准规格',
|
||||
quantity: item.quantity ?? 1,
|
||||
@@ -534,6 +570,8 @@ const toggleShopSelect = async (shopId: string) => {
|
||||
shopName: item.shopName,
|
||||
name: item.name,
|
||||
price: item.price,
|
||||
originalPrice: item.originalPrice,
|
||||
memberPrice: item.memberPrice,
|
||||
image: item.image,
|
||||
spec: item.spec,
|
||||
quantity: item.quantity,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<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>
|
||||
<text class="search-placeholder">请输入商品名称、店铺</text>
|
||||
|
||||
<!-- 扫码图标 -->
|
||||
<view class="nav-icon-btn" @click.stop="onScan">
|
||||
@@ -100,10 +100,16 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<!-- 加载中状态 -->
|
||||
<view v-else-if="loading" class="loading-state">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 - 仅在非加载状态且无商品时显示 -->
|
||||
<view v-else class="empty-state">
|
||||
<text class="empty-icon">💊</text>
|
||||
<text class="empty-text">暂无相关药品</text>
|
||||
<text class="empty-icon"><EFBFBD></text>
|
||||
<text class="empty-text">暂无相关商品</text>
|
||||
<text class="empty-desc">该分类下暂无商品,敬请期待</text>
|
||||
</view>
|
||||
|
||||
@@ -1095,6 +1101,37 @@ function onScan(): void {
|
||||
margin-right: 6px; /* gap replacement */
|
||||
}
|
||||
|
||||
/* 加载中状态 */
|
||||
.loading-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 3px solid #f0f0f0;
|
||||
border-top-color: #ff5000;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- pages/main/index.uvue -->
|
||||
<!-- pages/main/index.uvue -->
|
||||
<template>
|
||||
<view class="medic-home">
|
||||
<!-- 智能顶部导航栏 - 添加滚动隐藏效果 -->
|
||||
@@ -12,7 +12,7 @@
|
||||
<view class="search-container">
|
||||
<view class="search-box" @click="navigateToSearch" :style="{ height: '30px' }">
|
||||
<!-- 模拟输入框 -->
|
||||
<text class="search-placeholder">请输入药品名称、症状或品牌</text>
|
||||
<text class="search-placeholder">请输入商品名称、店铺</text>
|
||||
|
||||
<!-- 扫码图标 -->
|
||||
<view class="nav-icon-btn" @click.stop="onScan">
|
||||
@@ -681,37 +681,43 @@ onShow(() => {
|
||||
|
||||
// 处理滚动事件
|
||||
const handleScroll = (event: any) => {
|
||||
const eventObj = event as UTSJSONObject
|
||||
const detail = eventObj.get('detail') as UTSJSONObject
|
||||
const scrollTop = detail.getNumber('scrollTop') ?? 0
|
||||
const currentTime = Date.now()
|
||||
|
||||
// 判断滚动方向
|
||||
if (scrollTop > lastScrollTop.value) {
|
||||
// 向下滚动
|
||||
scrollingUp.value = false
|
||||
// 向下滚动超过阈值时隐藏导航栏
|
||||
if (scrollTop > scrollThreshold && showNavbar.value) {
|
||||
showNavbar.value = false
|
||||
try {
|
||||
const eventObj = event as UTSJSONObject
|
||||
const detailRaw = eventObj.get('detail')
|
||||
if (detailRaw == null) return
|
||||
const detail = detailRaw as UTSJSONObject
|
||||
const scrollTop = detail.getNumber('scrollTop') ?? 0
|
||||
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
|
||||
}
|
||||
}
|
||||
} else if (scrollTop < lastScrollTop.value) {
|
||||
// 向上滚动
|
||||
scrollingUp.value = true
|
||||
// 向上滚动时显示导航栏
|
||||
if (!showNavbar.value) {
|
||||
|
||||
// 滚动到顶部时强制显示导航栏
|
||||
if (scrollTop <= 10) {
|
||||
showNavbar.value = true
|
||||
}
|
||||
|
||||
lastScrollTop.value = scrollTop
|
||||
|
||||
// 调试信息(开发时可启用)
|
||||
// console.log(`Scroll: ${scrollTop}, ShowNavbar: ${showNavbar.value}, ScrollingUp: ${scrollingUp.value}`)
|
||||
} catch (e) {
|
||||
// 忽略滚动事件处理错误
|
||||
}
|
||||
|
||||
// 滚动到顶部时强制显示导航栏
|
||||
if (scrollTop <= 10) {
|
||||
showNavbar.value = true
|
||||
}
|
||||
|
||||
lastScrollTop.value = scrollTop
|
||||
|
||||
// 调试信息(开发时可启用)
|
||||
// console.log(`Scroll: ${scrollTop}, ShowNavbar: ${showNavbar.value}, ScrollingUp: ${scrollingUp.value}`)
|
||||
}
|
||||
|
||||
// 重置导航栏显示状态(例如点击回到顶部时)
|
||||
|
||||
Reference in New Issue
Block a user