campus-errand/miniapp/stores/cart.js
18631081161 1fd330b233
Some checks reported errors
continuous-integration/drone/push Build encountered an error
下单优化
2026-04-03 15:40:09 +08:00

156 lines
4.4 KiB
JavaScript
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.

/**
* 购物车状态管理(多门店版)
* 按门店分组存储菜品,支持跨门店下单
*/
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCartStore = defineStore('cart', () => {
// 按门店分组存储: { shopId: { shopInfo, items: [{ dish, quantity }] } }
const shops = ref({})
// 当前门店 ID门店详情页使用
const currentShopId = ref(null)
// ==================== 计算属性 ====================
/** 所有门店列表 */
const shopList = computed(() => {
return Object.values(shops.value).filter(s => s.items.length > 0)
})
/** 当前门店的商品列表 */
const items = computed(() => {
if (!currentShopId.value || !shops.value[currentShopId.value]) return []
return shops.value[currentShopId.value].items
})
/** 当前门店信息 */
const shopInfo = computed(() => {
if (!currentShopId.value || !shops.value[currentShopId.value]) return null
return shops.value[currentShopId.value].shopInfo
})
/** 所有门店总数量 */
const totalCount = computed(() => {
let count = 0
for (const shop of Object.values(shops.value)) {
count += shop.items.reduce((sum, item) => sum + item.quantity, 0)
}
return count
})
/** 所有门店商品总价(不含打包费) */
const totalPrice = computed(() => {
let price = 0
for (const shop of Object.values(shops.value)) {
price += shop.items.reduce((sum, item) => sum + item.quantity * item.dish.price, 0)
}
return price
})
/** 所有门店打包费总和 */
const packingFee = computed(() => {
let fee = 0
for (const shop of Object.values(shops.value)) {
if (shop.items.length === 0) continue
const { packingFeeType, packingFeeAmount } = shop.shopInfo
if (!packingFeeAmount) continue
if (packingFeeType === 'Fixed') {
fee += packingFeeAmount
} else {
const shopCount = shop.items.reduce((s, i) => s + i.quantity, 0)
fee += shopCount * packingFeeAmount
}
}
return fee
})
/** 含打包费的总金额 */
const totalPriceWithFee = computed(() => {
return totalPrice.value + packingFee.value
})
/** 当前门店的商品数量 */
const currentShopCount = computed(() => {
if (!currentShopId.value || !shops.value[currentShopId.value]) return 0
return shops.value[currentShopId.value].items.reduce((sum, item) => sum + item.quantity, 0)
})
// ==================== 方法 ====================
/** 设置当前门店信息 */
function setShopInfo(info) {
currentShopId.value = info.id
if (!shops.value[info.id]) {
shops.value[info.id] = { shopInfo: info, items: [] }
} else {
// 更新门店信息
shops.value[info.id].shopInfo = info
}
}
/** 获取菜品在当前门店购物车中的数量 */
function getQuantity(dishId) {
if (!currentShopId.value || !shops.value[currentShopId.value]) return 0
const item = shops.value[currentShopId.value].items.find(i => i.dish.id === dishId)
return item ? item.quantity : 0
}
/** 添加菜品到当前门店购物车 */
function addItem(dish) {
if (!currentShopId.value) return
// 门店被清空后自动重建
if (!shops.value[currentShopId.value]) {
shops.value[currentShopId.value] = { shopInfo: { id: currentShopId.value }, items: [] }
}
const shop = shops.value[currentShopId.value]
const existing = shop.items.find(i => i.dish.id === dish.id)
if (existing) {
existing.quantity += 1
} else {
shop.items.push({ dish: { ...dish }, quantity: 1 })
}
}
/** 减少当前门店菜品数量 */
function removeItem(dishId) {
if (!currentShopId.value) return
const shop = shops.value[currentShopId.value]
if (!shop) return
const index = shop.items.findIndex(i => i.dish.id === dishId)
if (index === -1) return
shop.items[index].quantity -= 1
if (shop.items[index].quantity <= 0) {
shop.items.splice(index, 1)
}
}
/** 清空所有购物车 */
function clearCart() {
shops.value = {}
}
/** 获取所有门店的 foodItems下单用 */
function getAllFoodItems() {
const foodItems = []
for (const shop of Object.values(shops.value)) {
for (const item of shop.items) {
foodItems.push({
shopId: shop.shopInfo.id,
dishId: item.dish.id,
quantity: item.quantity,
unitPrice: item.dish.price
})
}
}
return foodItems
}
return {
shops, currentShopId, shopList, items, shopInfo,
totalCount, totalPrice, packingFee, totalPriceWithFee, currentShopCount,
setShopInfo, getQuantity, addItem, removeItem, clearCart, getAllFoodItems
}
})