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

1374 lines
33 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/cart.uvue -->
<template>
<view class="cart-page">
<!-- 鏅鸿兘椤堕儴瀵艰埅鏍?- 涓庢秷鎭〉淇濇寔涓€鑷?-->
<view class="smart-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-container">
<text class="nav-title">璐墿杞?/text>
<view class="nav-actions">
<view class="action-btn" @click="toggleManageMode">
<text class="action-icon">{{ isManageMode ? '鉁? : '鈿欙笍' }}</text>
<text class="action-text">{{ isManageMode ? '瀹屾垚' : '绠$悊' }}</text>
</view>
</view>
</view>
</view>
<!-- 瀵艰埅鏍忓崰浣嶇 - 宸茬Щ闄?-->
<!-- <view class="navbar-placeholder" :style="{ height: (statusBarHeight + 44) + 'px' }"></view> -->
<!-- 璐墿杞﹀唴瀹?-->
<scroll-view scroll-y class="cart-content" :style="{ paddingTop: (statusBarHeight + 10) + 'px' }">
<!-- 绌鸿喘鐗╄溅 -->
<view v-if="!loading && cartItems.length === 0" class="empty-cart">
<text class="empty-icon">馃洅</text>
<text class="empty-title">璐墿杞︽槸绌虹殑</text>
<text class="empty-desc">蹇幓鎸戦€夊枩娆㈢殑鍟嗗搧鍚?/text>
<button class="go-shopping-btn" @click="goShopping">鍘婚€涢€?/button>
</view>
<!-- 璐墿杞﹀晢鍝佸垪琛?-->
<view v-else class="cart-list">
<view
v-for="group in cartGroups"
:key="group.shopId"
class="shop-group"
>
<!-- 搴楅摵澶撮儴 -->
<view class="shop-header">
<view class="shop-select" @click="toggleShopSelect(group.shopId)">
<text v-if="isShopSelected(group.shopId)" class="selected-icon">鉁?/text>
<text v-else class="unselected-icon"></text>
</view>
<text class="shop-icon">馃彧</text>
<text class="shop-name">{{ group.shopName }}</text>
<text class="shop-arrow">></text>
</view>
<!-- 搴楅摵鍟嗗搧 -->
<view
v-for="item in group.items"
:key="item.id"
class="cart-item"
>
<view class="item-select" @click="toggleSelect(item.id)">
<text v-if="item.selected" class="selected-icon">鉁?/text>
<text v-else class="unselected-icon"></text>
</view>
<image
class="item-image"
:src="item.image"
mode="aspectFill"
@click="navigateToProduct(item)"
/>
<view class="item-info">
<view class="info-top">
<text class="item-name">{{ item.name }}</text>
<text class="item-spec">{{ item.spec }}</text>
</view>
<view class="item-footer">
<text class="item-price">楼{{ item.price }}</text>
<view class="quantity-control">
<text class="quantity-btn" @click="decreaseQuantity(item.id)">-</text>
<text class="quantity-value">{{ item.quantity }}</text>
<text class="quantity-btn" @click="increaseQuantity(item.id)">+</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 璐墿杞︽搷浣滄爮 (绉昏嚦鎺ㄨ崘鍟嗗搧涓婃柟) -->
<view v-if="cartItems.length > 0" class="cart-action-bar">
<view class="action-bar-content">
<view class="action-left">
<view class="select-all" @click="toggleSelectAll">
<text v-if="allSelected" class="selected-icon">鉁?/text>
<text v-else class="unselected-icon"></text>
<text class="select-all-text">鍏ㄩ€?/text>
</view>
</view>
<view class="action-right">
<view v-if="!isManageMode" class="total-info">
<text class="total-text">鍚堣:</text>
<text class="total-price">楼{{ totalPrice }}</text>
</view>
<button v-if="!isManageMode" class="checkout-btn" @click="goToCheckout">
鍘荤粨绠?{{ selectedCount }})
</button>
<button v-else class="delete-btn" @click="deleteSelectedItems">
鍒犻櫎({{ selectedCount }})
</button>
</view>
</view>
</view>
<!-- 鎺ㄨ崘鍟嗗搧 -->
<view v-if="recommendProducts.length > 0" class="recommend-section">
<view class="section-header">
<text class="section-title">鐚滀綘鍠滄</text>
</view>
<view class="recommend-list">
<view
v-for="product in recommendProducts"
:key="product.id"
class="recommend-item"
@click="navigateToProduct(product)"
>
<image
class="recommend-image"
:src="product.image"
mode="aspectFill"
/>
<text class="recommend-name">{{ product.name }}</text>
<view class="recommend-bottom">
<text class="recommend-price">楼{{ product.price }}</text>
<view class="recommend-add-btn" @click.stop="addToCart(product)">
<text class="recommend-add-icon">+</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 搴曢儴缁撶畻鏍?- 宸茬Щ闄わ紝绉诲姩鍒板唴瀹瑰尯鍩?-->
<!-- <view v-if="cartItems.length > 0" class="cart-footer">
<view class="footer-content">
<view class="footer-left">
<view class="select-all" @click="toggleSelectAll">
<text v-if="allSelected" class="selected-icon">鉁?/text>
<text v-else class="unselected-icon"></text>
<text class="select-all-text">鍏ㄩ€?/text>
</view>
</view>
<view class="footer-right">
<view v-if="!isManageMode" class="total-info">
<text class="total-text">鍚堣:</text>
<text class="total-price">楼{{ totalPrice }}</text>
</view>
<button v-if="!isManageMode" class="checkout-btn" @click="goToCheckout">
鍘荤粨绠?{{ selectedCount }})
</button>
<button v-else class="delete-btn" @click="deleteSelectedItems">
鍒犻櫎({{ selectedCount }})
</button>
</view>
</view>
</view> -->
</view>
</template>
<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { supabaseService, type CartItem as SupabaseCartItem } from '@/utils/supabaseService.uts'
// 鍝嶅簲寮忔暟鎹?
const cartItems = ref<any[]>([])
const recommendProducts = ref<any[]>([])
const loading = ref<boolean>(false)
const statusBarHeight = ref(0)
const isManageMode = ref(false)
const mockRecommendProducts = [
{
id: 'rec_001',
shopId: 'shop_rec_1',
shopName: '娼祦杩愬姩鏃楄埌搴?,
name: '杩愬姩淇濇俯鏉?,
price: 59,
image: 'https://picsum.photos/100/100?random=11',
specification: '棰滆壊锛氭槦绌洪粦 | 瀹归噺锛?00ml | 鏉愯川锛?04涓嶉攬閽?,
specDetails: {
color: '鏄熺┖榛?,
capacity: '500ml',
material: '304涓嶉攬閽?
}
},
{
id: 'rec_002',
shopId: 'shop_rec_2',
shopName: '鏅鸿兘瀹跺眳鐢熸椿棣?,
name: '澹版尝鐢靛姩鐗欏埛',
price: 129,
image: 'https://picsum.photos/100/100?random=12',
specification: '棰滆壊锛氱弽鐝犵櫧 | 鍒峰ご锛氭晱鎰熷瀷脳2 | 缁埅锛?0澶?,
specDetails: {
color: '鐝嶇彔鐧?,
brushHead: '鏁忔劅鍨嬅?',
batteryLife: '30澶?
}
},
{
id: 'rec_003',
shopId: 'shop_rec_3',
shopName: '鍋ュ悍闃叉姢涓撳搴?,
name: '鍖荤敤鎶ょ悊鍙g僵',
price: 29.9,
image: 'https://picsum.photos/100/100?random=13',
specification: '瑙勬牸锛氫笁灞傞槻鎶?| 鏁伴噺锛?0鍙嫭绔嬭 | 鎵ц鏍囧噯锛歒Y0469',
specDetails: {
layers: '涓夊眰闃叉姢',
quantity: '50鍙?,
standard: 'YY0469'
}
},
{
id: 'rec_004',
shopId: 'shop_rec_4',
shopName: '鎴峰杩愬姩瑁呭搴?,
name: '涓撲笟鎶よ啙',
price: 45,
image: 'https://picsum.photos/100/100?random=14',
specification: '灏虹爜锛歀鐮?| 鏉愯川锛氳蹇嗘+寮瑰姏甯?| 閫傜敤锛氱鐞?璺戞',
specDetails: {
size: 'L鐮?,
material: '璁板繂妫?寮瑰姏甯?,
suitableFor: '绡悆/璺戞'
}
}
]
// 璁$畻灞炴€?
const cartGroups = computed(() => {
const groups = new Map<string, any>()
cartItems.value.forEach(item => {
if (!groups.has(item.shopId)) {
groups.set(item.shopId, {
shopId: item.shopId,
shopName: item.shopName,
items: [] as any[]
})
}
const group = groups.get(item.shopId)
if (group) {
group.items.push(item)
}
})
return Array.from(groups.values())
})
const allSelected = computed(() => {
return cartItems.value.length > 0 && cartItems.value.every(item => item.selected)
})
const selectedCount = computed(() => {
return cartItems.value.filter(item => item.selected).reduce((sum, item) => sum + item.quantity, 0)
})
const totalPrice = computed(() => {
return cartItems.value
.filter(item => item.selected)
.reduce((sum, item) => sum + item.price * item.quantity, 0)
.toFixed(2)
})
// 妫€鏌ュ簵閾烘槸鍚﹀叏閫?
const isShopSelected = (shopId: string) => {
const group = cartGroups.value.find(g => g.shopId === shopId)
return group ? group.items.every(item => item.selected) : false
}
const toggleManageMode = () => {
isManageMode.value = !isManageMode.value
}
// 鍒濆鍖栭〉闈㈡暟鎹?
const initPage = () => {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
}
// 鐢熷懡鍛ㄦ湡
onMounted(() => {
initPage()
})
onShow(() => {
loadCartData()
})
// 鍔犺浇鏁版嵁
const loadCartData = async () => {
loading.value = true
try {
// 浠嶴upabase鍔犺浇璐墿杞︽暟鎹?
const supabaseCartItems = await supabaseService.getCartItems()
// 杞崲鏁版嵁鏍煎紡浠ュ尮閰嶅墠绔晫闈?
const transformedItems = supabaseCartItems.map((item: SupabaseCartItem) => ({
id: item.id,
shopId: item.shop_id || 'unknown_shop',
shopName: item.shop_name || '鏈煡搴楅摵',
name: item.product_name || '鍟嗗搧',
price: item.product_price || 0,
image: item.product_image || '/static/product1.jpg',
spec: item.product_specification || '榛樿瑙勬牸',
quantity: item.quantity || 1,
selected: item.selected || false,
productId: item.product_id // 淇濈暀productId鐢ㄤ簬鍚庣画鎿嶄綔
}))
cartItems.value = transformedItems
// 鍔犺浇鎺ㄨ崘鍟嗗搧锛堟殏鏃朵繚鎸丮ock鏁版嵁锛?
recommendProducts.value = [...mockRecommendProducts]
} catch (error) {
console.error('鍔犺浇璐墿杞︽暟鎹け璐?', error)
// 濡傛灉API璋冪敤澶辫触锛屽皾璇曚粠鏈湴瀛樺偍鍔犺浇
const cartData = uni.getStorageSync('cart')
if (cartData) {
try {
cartItems.value = JSON.parse(cartData as string) as any[]
} catch (e) {
console.error('瑙f瀽璐墿杞︽暟鎹け璐?, e)
cartItems.value = []
}
}
} finally {
loading.value = false
}
}
// 鍟嗗搧鎿嶄綔 - 鏇存柊閫変腑鐘舵€佸埌Supabase
const toggleSelect = async (itemId: string) => {
const index = cartItems.value.findIndex(item => item.id === itemId)
if (index !== -1) {
const newSelected = !cartItems.value[index].selected
cartItems.value[index].selected = newSelected
cartItems.value = [...cartItems.value] // 瑙﹀彂鍝嶅簲寮忔洿鏂?
// 鏇存柊鍒癝upabase
const success = await supabaseService.updateCartItemSelection(itemId, newSelected)
if (!success) {
console.error('鏇存柊閫変腑鐘舵€佸け璐?)
// 鎭㈠鐘舵€?
cartItems.value[index].selected = !newSelected
cartItems.value = [...cartItems.value]
}
}
}
const toggleShopSelect = async (shopId: string) => {
const group = cartGroups.value.find((g: any) => g.shopId === shopId)
if (!group) return
// 妫€鏌ュ綋鍓嶆槸鍚﹀叏閫?
const isAllShopSelected = (group.items as any[]).every((item: any) => item.selected)
const newState = !isAllShopSelected
// 鑾峰彇璇ュ簵閾轰笅鎵€鏈夊晢鍝佺殑ID
const shopItemIds = cartItems.value
.filter(item => item.shopId === shopId)
.map(item => item.id)
// 鎵归噺鏇存柊鍒癝upabase
const success = await supabaseService.batchUpdateCartItemSelection(shopItemIds, newState)
if (success) {
// 鏇存柊鏈湴鐘舵€?
cartItems.value.forEach(item => {
if (item.shopId === shopId) {
item.selected = newState
}
})
cartItems.value = [...cartItems.value]
} else {
console.error('鎵归噺鏇存柊搴楅摵鍟嗗搧閫変腑鐘舵€佸け璐?)
uni.showToast({
title: '鎿嶄綔澶辫触',
icon: 'none'
})
}
}
const toggleSelectAll = async () => {
const newSelectedState = !allSelected.value
const selectedItems = cartItems.value.map(item => ({
...item,
selected: newSelectedState
}))
// 鏇存柊鍒癝upabase
const itemIds = cartItems.value.map(item => item.id)
const success = await supabaseService.batchUpdateCartItemSelection(itemIds, newSelectedState)
if (success) {
cartItems.value = selectedItems
} else {
console.error('鎵归噺鏇存柊閫変腑鐘舵€佸け璐?)
uni.showToast({
title: '鎿嶄綔澶辫触',
icon: 'none'
})
}
}
const increaseQuantity = async (itemId: string) => {
const index = cartItems.value.findIndex(item => item.id === itemId)
if (index !== -1) {
const newQuantity = cartItems.value[index].quantity + 1
cartItems.value[index].quantity = newQuantity
cartItems.value = [...cartItems.value]
// 鏇存柊鍒癝upabase
const success = await supabaseService.updateCartItemQuantity(itemId, newQuantity)
if (!success) {
console.error('鏇存柊鍟嗗搧鏁伴噺澶辫触')
// 鎭㈠鐘舵€?
cartItems.value[index].quantity = newQuantity - 1
cartItems.value = [...cartItems.value]
}
}
}
const decreaseQuantity = async (itemId: string) => {
const index = cartItems.value.findIndex(item => item.id === itemId)
if (index !== -1) {
if (cartItems.value[index].quantity > 1) {
const newQuantity = cartItems.value[index].quantity - 1
cartItems.value[index].quantity = newQuantity
cartItems.value = [...cartItems.value]
// 鏇存柊鍒癝upabase
const success = await supabaseService.updateCartItemQuantity(itemId, newQuantity)
if (!success) {
console.error('鏇存柊鍟嗗搧鏁伴噺澶辫触')
// 鎭㈠鐘舵€?
cartItems.value[index].quantity = newQuantity + 1
cartItems.value = [...cartItems.value]
}
} else {
// 鏁伴噺涓?鏃讹紝璇㈤棶鏄惁鍒犻櫎
uni.showModal({
title: '鎻愮ず',
content: '纭畾瑕佷粠璐墿杞︾Щ闄よ鍟嗗搧鍚楋紵',
success: async (res) => {
if (res.confirm) {
// 浠嶴upabase鍒犻櫎
const success = await supabaseService.deleteCartItem(itemId)
if (success) {
cartItems.value.splice(index, 1)
cartItems.value = [...cartItems.value]
uni.showToast({
title: '宸茬Щ闄?,
icon: 'none'
})
} else {
console.error('鍒犻櫎鍟嗗搧澶辫触')
uni.showToast({
title: '鍒犻櫎澶辫触',
icon: 'none'
})
}
}
}
})
}
}
}
// 鍒犻櫎鍟嗗搧 - 澧炲姞淇濆瓨閫昏緫
const deleteSelectedItems = async () => {
if (selectedCount.value === 0) {
uni.showToast({
title: '璇烽€夋嫨瑕佸垹闄ょ殑鍟嗗搧',
icon: 'none'
})
return
}
uni.showModal({
title: '鎻愮ず',
content: `纭畾瑕佸垹闄ら€変腑鐨?${selectedCount.value} 浠跺晢鍝佸悧锛焋,
success: async (res) => {
if (res.confirm) {
// 鑾峰彇閫変腑鐨勫晢鍝両D
const selectedItemIds = cartItems.value
.filter(item => item.selected)
.map(item => item.id)
// 鎵归噺鍒犻櫎鍒癝upabase
const success = await supabaseService.batchDeleteCartItems(selectedItemIds)
if (success) {
// 浠庢湰鍦板垪琛ㄧЩ闄?
cartItems.value = cartItems.value.filter(item => !item.selected)
// 濡傛灉璐墿杞﹀垹绌轰簡锛岄€€鍑虹鐞嗘ā寮?
if (cartItems.value.length === 0) {
isManageMode.value = false
}
uni.showToast({
title: '鍒犻櫎鎴愬姛',
icon: 'success'
})
} else {
console.error('鎵归噺鍒犻櫎鍟嗗搧澶辫触')
uni.showToast({
title: '鍒犻櫎澶辫触',
icon: 'none'
})
}
}
}
})
}
const addToCart = (product: any) => {
// 鑾峰彇鐜版湁璐墿杞︽暟鎹?
const cartData = uni.getStorageSync('cart')
let currentItems: any[] = []
if (cartData) {
try {
currentItems = JSON.parse(cartData as string) as any[]
} catch (e) {
console.error('瑙f瀽璐墿杞︽暟鎹け璐?, e)
}
}
// 妫€鏌ュ晢鍝佹槸鍚﹀凡瀛樺湪 (浣跨敤鍟嗗搧ID鍖归厤锛屽洜涓烘帹鑽愬晢鍝佹病鏈塖KU)
const existingItem = currentItems.find((item: any) =>
item.productId === product.id || item.id === product.id
)
if (existingItem) {
existingItem.quantity++
} else {
// 娣诲姞鏂板晢鍝?
currentItems.push({
id: product.id, // 鍟嗗搧ID锛堝洜涓烘病鏈塖KU锛?
productId: product.id, // 鍚屾牱瀛樺偍鍟嗗搧ID
shopId: product.shopId || 'shop_recommend',
shopName: product.shopName || '鎺ㄨ崘濂界墿',
name: product.name,
price: product.price,
image: product.image,
spec: product.specification || '榛樿瑙勬牸', // 浼樺厛浣跨敤鍟嗗搧鑷甫鐨勮鏍?
quantity: 1,
selected: true
})
}
// 淇濆瓨鍥炲瓨鍌?
uni.setStorageSync('cart', JSON.stringify(currentItems))
uni.showToast({
title: '宸叉坊鍔犲埌璐墿杞?,
icon: 'success'
})
// 绔嬪嵆鍒锋柊褰撳墠鍒楄〃
loadCartData()
}
// 瀵艰埅鍑芥暟
const goShopping = () => {
uni.switchTab({ url: '/pages/mall/consumer/index' })
}
const navigateToProduct = (product: any) => {
// 浣跨敤productId锛堝鏋滃瓨鍦級浣滀负璺宠浆鐨勫晢鍝両D锛屽惁鍒欎娇鐢╥d
const productId = product.productId || product.id
// 浼犻€掑畬鏁寸殑鍙傛暟锛岀‘淇濆晢鍝佽鎯呴〉鑳芥纭姞杞?
const params = new URLSearchParams()
params.append('id', productId)
params.append('productId', productId)
params.append('price', product.price?.toString() || '0')
// 鍟嗗搧璇︽儏椤垫湡鏈涚殑鍙傛暟鍚嶆槸originalPrice
params.append('originalPrice', (product.original_price || product.originalPrice || (product.price * 1.2).toFixed(2))?.toString())
params.append('name', encodeURIComponent(product.name || ''))
params.append('image', encodeURIComponent(product.image || '/static/product1.jpg'))
uni.navigateTo({
url: `/pages/mall/consumer/product-detail?${params.toString()}`
})
}
const goToCheckout = () => {
if (selectedCount.value === 0) {
uni.showToast({
title: '璇烽€夋嫨鍟嗗搧',
icon: 'none'
})
return
}
// 鑾峰彇閫変腑鐨勫晢鍝?(鐩存帴杩囨护cartItems锛屼笉渚濊禆cartGroups)
const selectedItems = cartItems.value
.filter(item => item.selected)
.map(item => ({
id: item.id,
product_id: item.id, // 浣跨敤鍟嗗搧ID浣滀负product_id
sku_id: item.id, // 浣跨敤鍟嗗搧ID浣滀负sku_id
product_name: item.name,
product_image: item.image,
sku_specifications: item.spec,
price: Number(item.price), // 纭繚鏄暟瀛?
quantity: Number(item.quantity) // 纭繚鏄暟瀛?
}))
// 鍏抽敭淇锛氬皢缁撶畻鏁版嵁鍐欏叆 Storage锛岀淇?checkout 椤甸潰鑳界ǔ瀹氳幏鍙?
uni.setStorageSync('checkout_type', 'cart')
uni.setStorageSync('checkout_items', JSON.stringify(selectedItems))
// 璺宠浆鍒扮粨绠楅〉闈㈠苟浼犻€掓暟鎹?
uni.navigateTo({
url: '/pages/mall/consumer/checkout',
success: (res) => {
// 閫氳繃eventChannel浼犻€掓暟鎹?
res.eventChannel.emit('acceptData', {
selectedItems: selectedItems
})
}
})
}
</script>
<style>
.cart-page {
width: 100%;
height: 100vh;
background-color: #f5f5f5;
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 12px rgba(76, 175, 80, 0.15);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.nav-container {
padding: 0 16px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 1400px;
margin: 0 auto;
height: 44px; /* 缁熶竴楂樺害 44px */
}
.nav-title {
font-size: 18px;
font-weight: bold;
color: white;
}
.nav-actions {
display: flex;
flex-direction: row;
align-items: center;
}
.action-btn {
display: flex;
flex-direction: row;
align-items: center;
background: rgba(255, 255, 255, 0.2);
padding: 4px 12px;
border-radius: 20px;
cursor: pointer;
transition: all 0.2s ease;
}
.action-btn:hover {
background: rgba(255, 255, 255, 0.3);
}
.action-icon {
font-size: 14px;
margin-right: 4px;
color: white;
}
.action-text {
font-size: 12px;
color: white;
font-weight: 500;
}
/* 瀵艰埅鏍忓崰浣嶇 */
.navbar-placeholder {
width: 100%;
flex-shrink: 0;
}
/* 鍐呭鍖?*/
.cart-content {
flex: 1;
height: 0; /* 閰嶅悎 flex: 1 瀹炵幇鑷€傚簲婊氬姩 */
padding-bottom: 60px; /* 涓哄簳閮ㄧ粨绠楁爮鐣欏嚭绌洪棿 */
}
/* 绌鸿喘鐗╄溅 */
.empty-cart {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
text-align: center;
}
.empty-icon {
font-size: 80px;
color: #ddd;
margin-bottom: 20px;
}
.empty-title {
font-size: 18px;
color: #666;
margin-bottom: 10px;
}
.empty-desc {
font-size: 14px;
color: #999;
margin-bottom: 30px;
}
.go-shopping-btn {
background-color: #ff5000;
color: white;
border: none;
border-radius: 25px;
padding: 10px 40px;
font-size: 16px;
}
/* 璐墿杞﹀晢鍝佸垪琛?*/
.cart-list {
background-color: transparent; /* 鑳屾櫙閫忔槑锛屽洜涓烘瘡涓簵閾烘湁鑷繁鐨勫崱鐗?*/
margin: 10px;
border-radius: 0;
overflow: visible;
}
.shop-group {
background-color: white;
border-radius: 12px;
margin-bottom: 12px;
overflow: hidden;
}
.shop-header {
display: flex;
flex-direction: row; /* 寮哄埗妯悜鎺掑垪 */
align-items: center;
justify-content: flex-start; /* 闈犲乏瀵归綈 */
padding: 12px;
border-bottom: 1px solid #f5f5f5;
}
.shop-select {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8px;
flex-shrink: 0; /* 闃叉琚帇缂?*/
}
.shop-icon {
font-size: 16px;
margin-right: 6px;
flex-shrink: 0;
}
.shop-name {
font-size: 14px;
font-weight: 700;
color: #333;
margin-right: 4px;
/* 鑷€傚簲瀹藉害锛屼絾涓嶈秴杩囧墿浣欑┖闂?*/
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.shop-arrow {
font-size: 12px;
color: #999;
flex-shrink: 0;
}
.cart-item {
display: flex;
flex-direction: row; /* 鏄惧紡妯悜鎺掑垪 */
padding: 12px; /* 鍑忓皬鍐呰竟璺?*/
border-bottom: 1px solid #f5f5f5;
align-items: center;
height: 100px; /* 鍥哄畾楂樺害鑺傜渷绌洪棿 */
}
.cart-item:last-child {
border-bottom: none;
}
.item-select {
width: 30px; /* 鍑忓皬閫夋嫨妗嗗尯鍩?*/
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
}
.selected-icon {
width: 18px;
height: 18px;
background-color: #ff5000;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
}
.unselected-icon {
width: 18px;
height: 18px;
border: 1px solid #ddd;
border-radius: 50%;
}
.item-image {
width: 70px; /* 鍑忓皬鍥剧墖灏哄 */
height: 70px;
border-radius: 6px;
margin-right: 10px;
flex-shrink: 0;
}
.item-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 70px; /* 涓庡浘鐗囬珮搴︿竴鑷?*/
overflow: hidden;
}
.info-top {
display: flex;
flex-direction: column;
}
.item-name {
font-size: 14px; /* 绋嶅井鍑忓皬瀛椾綋 */
color: #333;
margin-bottom: 2px;
display: -webkit-box;
-webkit-line-clamp: 1; /* 鍗曡鏄剧ず */
-webkit-box-orient: vertical;
overflow: hidden;
font-weight: 500;
}
.item-spec {
font-size: 12px;
color: #999;
margin-bottom: auto; /* 鑷姩鍗犳嵁涓棿绌洪棿 */
}
.item-footer {
display: flex;
flex-direction: row; /* 鏄惧紡璁剧疆妯悜鎺掑垪 */
justify-content: space-between;
align-items: center;
width: 100%; /* 纭繚鍗犳弧瀹藉害 */
}
.item-price {
font-size: 16px;
color: #ff5000;
font-weight: bold;
}
.quantity-control {
display: flex;
flex-direction: row; /* 鏄惧紡璁剧疆妯悜鎺掑垪 */
align-items: center;
background-color: #f5f5f5;
border-radius: 12px;
overflow: hidden;
height: 24px;
}
.quantity-btn {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
.quantity-value {
width: 30px;
text-align: center;
font-size: 13px;
line-height: 24px;
}
/* 鎺ㄨ崘鍟嗗搧 */
.recommend-section {
margin: 20px 10px;
background-color: white;
border-radius: 10px;
padding: 15px;
}
.section-header {
margin-bottom: 15px;
}
.section-title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.recommend-list {
display: grid;
grid-template-columns: repeat(2, 1fr); /* 鎵嬫満绔粯璁ゅ弻鍒?*/
gap: 12px;
}
.recommend-item {
display: flex;
flex-direction: column;
background: #fff;
border-radius: 8px;
overflow: hidden;
}
.recommend-image {
width: 100%;
aspect-ratio: 1; /* 淇濇寔姝f柟褰㈡瘮渚?*/
height: auto; /* 鑷姩楂樺害 */
object-fit: cover;
border-radius: 8px;
margin-bottom: 8px;
background: #f5f5f5;
}
.recommend-name {
font-size: 13px;
color: #333;
margin-bottom: 5px;
line-height: 1.4;
height: 36px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.recommend-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding-right: 8px;
}
.recommend-price {
font-size: 15px;
color: #ff5000;
font-weight: bold;
}
.recommend-add-btn {
width: 24px;
height: 24px;
background-color: #ff5000;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.recommend-add-icon {
color: white;
font-size: 16px;
line-height: 1;
font-weight: bold;
}
/* 鍝嶅簲寮忓竷灞€浼樺寲 */
@media screen and (min-width: 768px) {
.cart-list,
.recommend-section {
margin: 20px auto;
max-width: 95%;
}
.recommend-list {
grid-template-columns: repeat(4, 1fr); /* 骞虫澘鏄剧ず4鍒?*/
gap: 16px;
}
}
@media screen and (min-width: 1024px) {
/* 妗岄潰绔暣浣撳竷灞€璋冩暣 */
.cart-content {
padding: 20px 40px;
background-color: #f5f5f5;
}
.cart-list,
.recommend-section {
margin: 20px auto;
max-width: 1200px; /* 闄愬埗鏈€澶у搴?*/
}
/* 搴楅摵鍒嗙粍鍦ㄦ闈㈢鏄剧ず涓虹綉鏍煎竷灞€ */
.shop-group {
display: block;
background: transparent;
box-shadow: none;
border-radius: 0;
overflow: visible;
}
.shop-header {
background: white;
border-radius: 12px;
margin-bottom: 12px;
padding: 16px 24px;
}
/* 璐墿杞﹀晢鍝佸垪琛ㄨ浆涓哄垪琛ㄥ竷灞€ */
.cart-item {
background: white;
border-radius: 0;
padding: 15px 30px;
height: 80px; /* 鍥哄畾楂樺害 */
border-bottom: 1px solid #eee;
box-shadow: none;
display: flex;
flex-direction: row; /* 鏄惧紡璁剧疆妯悜鎺掑垪 */
align-items: center; /* 鍨傜洿灞呬腑 */
width: 100%;
}
.cart-item:hover {
background-color: #f9f9f9;
transform: none;
box-shadow: none;
}
.item-image {
width: 50px;
height: 50px;
margin-right: 20px;
flex-shrink: 0;
}
.item-info {
flex: 1;
height: 100%;
display: flex;
flex-direction: row; /* 淇℃伅鍖哄煙妯悜鎺掑垪 */
align-items: center;
justify-content: space-between;
overflow: visible;
}
.info-top {
flex: 1;
display: flex;
flex-direction: row; /* 鍚嶇О鍜岃鏍兼í鍚戞帓鍒?*/
align-items: center;
margin-right: 20px;
height: 100%;
}
.item-name {
font-size: 14px;
width: 250px; /* 鍥哄畾鍚嶇О瀹藉害 */
margin-right: 20px;
/* 闄愬埗琛屾暟 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 0;
}
.item-spec {
width: 150px;
margin-bottom: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-footer {
width: auto;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: 40px;
height: 100%;
}
.item-price {
width: 100px;
text-align: right;
margin-bottom: 0;
}
.quantity-control {
margin-left: 0;
display: flex;
flex-direction: row;
}
/* 鎺ㄨ崘鍟嗗搧浼樺寲 */
.recommend-list {
grid-template-columns: repeat(5, 1fr); /* 妗岄潰绔樉绀?鍒?*/
gap: 20px;
}
.recommend-image {
height: 200px; /* 寮哄埗楂樺害 */
}
/* 搴曢儴缁撶畻鏍忎紭鍖?*/
.cart-footer {
padding: 0 40px;
max-width: 100%;
margin: 0 auto;
box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
}
.footer-content {
max-width: 1200px;
margin: 0 auto;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
}
@media screen and (min-width: 1400px) {
.cart-list,
.recommend-section {
max-width: 1400px;
}
/* 澶у睆涓嬭喘鐗╄溅鍟嗗搧鏄剧ず3鍒?- 绉婚櫎锛屼繚鎸佸崟鍒楀垪琛?*/
/* .cart-list .shop-group > view:not(.shop-header) {
grid-template-columns: repeat(3, 1fr);
} */
.recommend-list {
grid-template-columns: repeat(6, 1fr); /* 澶у睆骞曟樉绀?鍒?*/
}
.footer-content {
max-width: 1400px;
}
}
/* 璐墿杞︽搷浣滄爮鏍峰紡 - 鑷€傚簲妯悜鎺掑垪 */
.cart-action-bar {
background-color: white;
margin: 10px;
border-radius: 12px;
padding: 15px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.action-bar-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.action-left, .action-right {
display: flex;
align-items: center;
flex-wrap: nowrap;
}
.action-right {
justify-content: flex-end;
flex: 1;
min-width: 0; /* 闃叉婧㈠嚭 */
}
/* 鍚堣淇℃伅鍖哄煙 - 鑷€傚簲妯悜鎺掑垪 */
.total-info {
display: flex;
align-items: center;
margin-right: 12px;
flex-shrink: 0;
}
.total-text {
font-size: 14px;
color: #333;
margin-right: 5px;
white-space: nowrap;
}
.total-price {
font-size: 18px;
color: #ff5000;
font-weight: bold;
white-space: nowrap;
}
/* 缁撶畻鎸夐挳 */
.checkout-btn, .delete-btn {
background-color: #ff5000;
color: white;
border: none;
border-radius: 25px;
padding: 8px 20px;
font-size: 14px;
white-space: nowrap;
flex-shrink: 0;
}
.delete-btn {
background-color: #ff3b30; /* 绾㈣壊鍒犻櫎鎸夐挳 */
padding: 8px 25px;
}
/* 鍏ㄩ€夊尯鍩?*/
.select-all {
display: flex;
align-items: center;
}
.select-all-text {
margin-left: 8px;
font-size: 14px;
color: #333;
white-space: nowrap;
}
/* 鍝嶅簲寮忚皟鏁?*/
/* 鎵嬫満绔皬灞忓箷浼樺寲 */
@media screen and (max-width: 375px) {
.action-bar-content {
gap: 8px;
}
.total-text {
font-size: 13px;
}
.total-price {
font-size: 16px;
}
.checkout-btn, .delete-btn {
padding: 8px 15px;
font-size: 13px;
}
.select-all-text {
font-size: 13px;
}
}
/* 骞虫澘绔紭鍖?*/
@media screen and (min-width: 768px) {
.cart-action-bar {
margin: 20px auto;
max-width: 95%;
padding: 20px;
}
.action-bar-content {
gap: 20px;
}
.total-price {
font-size: 20px;
}
.checkout-btn, .delete-btn {
padding: 10px 30px;
font-size: 16px;
}
}
/* 妗岄潰绔紭鍖?*/
@media screen and (min-width: 1024px) {
.cart-action-bar {
max-width: 1200px;
padding: 20px 30px;
}
.action-bar-content {
justify-content: space-between;
}
.total-info {
margin-right: 30px;
}
.total-text {
font-size: 16px;
}
.total-price {
font-size: 22px;
}
.checkout-btn, .delete-btn {
padding: 12px 40px;
font-size: 16px;
}
.select-all-text {
font-size: 16px;
}
}
/* 澶у睆骞曚紭鍖?*/
@media screen and (min-width: 1400px) {
.cart-action-bar {
max-width: 1400px;
}
}
</style>