feat(购物车): 添加单一商品模式支持
在购物车功能中引入单一商品模式,允许用户在不同场景下选择单一商品或多商品模式。修改了购物车上下文逻辑,确保在单一商品模式下,购物车仅能包含一件商品。同时更新了相关页面逻辑,以适配新模式。
Showing
3 changed files
with
27 additions
and
3 deletions
| ... | @@ -19,7 +19,7 @@ import { apiList } from "@/api/wx/jsApiList.js"; | ... | @@ -19,7 +19,7 @@ import { apiList } from "@/api/wx/jsApiList.js"; |
| 19 | import { wxInfo, getUrlParams, stringifyQuery } from "@/utils/tools"; | 19 | import { wxInfo, getUrlParams, stringifyQuery } from "@/utils/tools"; |
| 20 | 20 | ||
| 21 | provideAuth(); // 提供全局认证状态 | 21 | provideAuth(); // 提供全局认证状态 |
| 22 | -provideCart(); // 提供全局购物车状态 | 22 | +provideCart('single'); // 提供全局购物车状态,单一商品模式 |
| 23 | </script> | 23 | </script> |
| 24 | 24 | ||
| 25 | <template> | 25 | <template> | ... | ... |
| ... | @@ -3,9 +3,16 @@ import { useRouter } from 'vue-router' | ... | @@ -3,9 +3,16 @@ import { useRouter } from 'vue-router' |
| 3 | 3 | ||
| 4 | const CartSymbol = Symbol() | 4 | const CartSymbol = Symbol() |
| 5 | 5 | ||
| 6 | -export function provideCart() { | 6 | +// 购物车模式配置 |
| 7 | +const CartMode = { | ||
| 8 | + SINGLE: 'single', // 单一商品模式 | ||
| 9 | + MULTIPLE: 'multiple' // 多商品模式 | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +export function provideCart(mode = CartMode.MULTIPLE) { | ||
| 7 | const router = useRouter() | 13 | const router = useRouter() |
| 8 | const cartItems = ref([]) | 14 | const cartItems = ref([]) |
| 15 | + const cartMode = ref(mode) | ||
| 9 | 16 | ||
| 10 | // 从localStorage加载购物车数据 | 17 | // 从localStorage加载购物车数据 |
| 11 | try { | 18 | try { |
| ... | @@ -25,6 +32,11 @@ export function provideCart() { | ... | @@ -25,6 +32,11 @@ export function provideCart() { |
| 25 | 32 | ||
| 26 | // 添加商品到购物车 | 33 | // 添加商品到购物车 |
| 27 | function addToCart(item) { | 34 | function addToCart(item) { |
| 35 | + if (cartMode.value === CartMode.SINGLE) { | ||
| 36 | + // 单一商品模式:直接替换现有商品 | ||
| 37 | + cartItems.value = [{ ...item, quantity: 1 }] | ||
| 38 | + } else { | ||
| 39 | + // 多商品模式:累加商品数量 | ||
| 28 | const existingItemIndex = cartItems.value.findIndex( | 40 | const existingItemIndex = cartItems.value.findIndex( |
| 29 | i => i.id === item.id && i.type === item.type | 41 | i => i.id === item.id && i.type === item.type |
| 30 | ) | 42 | ) |
| ... | @@ -40,6 +52,7 @@ export function provideCart() { | ... | @@ -40,6 +52,7 @@ export function provideCart() { |
| 40 | cartItems.value = [...cartItems.value, { ...item, quantity: 1 }] | 52 | cartItems.value = [...cartItems.value, { ...item, quantity: 1 }] |
| 41 | } | 53 | } |
| 42 | } | 54 | } |
| 55 | + } | ||
| 43 | 56 | ||
| 44 | // 从购物车移除商品 | 57 | // 从购物车移除商品 |
| 45 | function removeFromCart(itemId, itemType) { | 58 | function removeFromCart(itemId, itemType) { |
| ... | @@ -52,12 +65,20 @@ export function provideCart() { | ... | @@ -52,12 +65,20 @@ export function provideCart() { |
| 52 | function updateQuantity(itemId, itemType, quantity) { | 65 | function updateQuantity(itemId, itemType, quantity) { |
| 53 | if (quantity < 1) return | 66 | if (quantity < 1) return |
| 54 | 67 | ||
| 68 | + if (cartMode.value === CartMode.SINGLE) { | ||
| 69 | + // 单一商品模式:直接更新数量 | ||
| 70 | + if (cartItems.value.length === 1) { | ||
| 71 | + cartItems.value = [{ ...cartItems.value[0], quantity }] | ||
| 72 | + } | ||
| 73 | + } else { | ||
| 74 | + // 多商品模式:更新指定商品数量 | ||
| 55 | cartItems.value = cartItems.value.map(item => | 75 | cartItems.value = cartItems.value.map(item => |
| 56 | item.id === itemId && item.type === itemType | 76 | item.id === itemId && item.type === itemType |
| 57 | ? { ...item, quantity } | 77 | ? { ...item, quantity } |
| 58 | : item | 78 | : item |
| 59 | ) | 79 | ) |
| 60 | } | 80 | } |
| 81 | + } | ||
| 61 | 82 | ||
| 62 | // 清空购物车 | 83 | // 清空购物车 |
| 63 | function clearCart() { | 84 | function clearCart() { |
| ... | @@ -122,6 +143,7 @@ export function provideCart() { | ... | @@ -122,6 +143,7 @@ export function provideCart() { |
| 122 | 143 | ||
| 123 | const cart = { | 144 | const cart = { |
| 124 | items: cartItems, | 145 | items: cartItems, |
| 146 | + mode: cartMode, | ||
| 125 | addToCart, | 147 | addToCart, |
| 126 | removeFromCart, | 148 | removeFromCart, |
| 127 | updateQuantity, | 149 | updateQuantity, | ... | ... |
| ... | @@ -58,6 +58,7 @@ | ... | @@ -58,6 +58,7 @@ |
| 58 | </p> | 58 | </p> |
| 59 | </div> | 59 | </div> |
| 60 | <button | 60 | <button |
| 61 | + v-if="mode === 'multiple'" | ||
| 61 | @click="() => { | 62 | @click="() => { |
| 62 | itemToDelete = item | 63 | itemToDelete = item |
| 63 | showConfirmDialog = true | 64 | showConfirmDialog = true |
| ... | @@ -215,6 +216,7 @@ | ... | @@ -215,6 +216,7 @@ |
| 215 | <span class="text-lg font-bold text-green-600">{{ formatPrice(getTotalPrice()) }}</span> | 216 | <span class="text-lg font-bold text-green-600">{{ formatPrice(getTotalPrice()) }}</span> |
| 216 | </div> | 217 | </div> |
| 217 | <button | 218 | <button |
| 219 | + v-if="mode === 'multiple'" | ||
| 218 | type="button" | 220 | type="button" |
| 219 | @click="() => { | 221 | @click="() => { |
| 220 | showConfirmDialog = true | 222 | showConfirmDialog = true |
| ... | @@ -277,7 +279,7 @@ const $route = useRoute(); | ... | @@ -277,7 +279,7 @@ const $route = useRoute(); |
| 277 | const $router = useRouter(); | 279 | const $router = useRouter(); |
| 278 | useTitle($route.meta.title); | 280 | useTitle($route.meta.title); |
| 279 | const router = useRouter() | 281 | const router = useRouter() |
| 280 | -const { items: cartItems, getTotalPrice, handleCheckout, clearCart, removeFromCart } = useCart() | 282 | +const { items: cartItems, mode, getTotalPrice, handleCheckout, clearCart, removeFromCart } = useCart() |
| 281 | 283 | ||
| 282 | // Form state | 284 | // Form state |
| 283 | const formData = ref({ | 285 | const formData = ref({ | ... | ... |
-
Please register or login to post a comment