JewelryMall/miniprogram/store/cart.ts
2026-03-05 00:43:04 +08:00

116 lines
3.3 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { CartItem } from '../types'
import { getCartList, addToCart as apiAddToCart, deleteCartItem as apiDeleteCartItem, updateCartItem as apiUpdateCartItem } from '../api/cart'
export const useCartStore = defineStore('cart', () => {
const items = ref<CartItem[]>([])
const checkedItems = computed(() => items.value.filter((item) => item.checked))
const totalAmount = computed(() =>
checkedItems.value.reduce((sum, item) => sum + (item.specData?.totalPrice || 0) * item.quantity, 0),
)
async function fetchCart() {
const token = uni.getStorageSync('token')
if (!token) return
try {
const list: any[] = await getCartList() as any
items.value = list.map((row: any) => {
let imgs = row.bannerImages || []
if (typeof imgs === 'string') {
try { imgs = JSON.parse(imgs) } catch { imgs = [] }
}
return {
id: row.id,
userId: 0,
productId: row.productId,
specDataId: row.specDataId,
quantity: row.quantity,
checked: true,
product: {
id: row.productId,
name: row.productName,
basePrice: row.basePrice,
styleNo: row.styleNo || '',
bannerImages: imgs,
thumb: row.thumb || '',
},
specData: {
id: row.specDataId,
modelName: row.modelName,
fineness: row.fineness,
mainStone: row.mainStone,
ringSize: row.ringSize,
goldTotalWeight: row.goldTotalWeight || 0,
totalPrice: row.unitPrice || 0,
},
}
})
} catch {
// 未登录或网络异常,保留本地数据
}
}
function addToCart(item: CartItem) {
const tempId = item.id
items.value.push(item)
apiAddToCart({
productId: item.productId,
specDataId: item.specDataId,
quantity: item.quantity,
}).then((res: any) => {
const realId = res?.cartItemId
if (realId) {
const found = items.value.find((i) => i.id === tempId)
if (found) found.id = realId
}
}).catch(() => { /* 静默处理 */ })
}
function removeFromCart(id: number) {
const index = items.value.findIndex((item) => item.id === id)
if (index !== -1) {
items.value.splice(index, 1)
apiDeleteCartItem(id).catch(() => { /* 静默处理 */ })
}
}
function updateQuantity(id: number, quantity: number) {
const item = items.value.find((item) => item.id === id)
if (item) {
item.quantity = quantity
apiUpdateCartItem(id, { quantity }).catch(() => { /* 静默处理 */ })
}
}
/** 切换勾选状态(纯本地操作) */
function toggleCheck(id: number) {
const item = items.value.find((item) => item.id === id)
if (item) {
item.checked = !item.checked
}
}
/** 全选/取消全选(纯本地操作) */
function toggleCheckAll() {
const allChecked = items.value.every((item) => item.checked)
items.value.forEach((item) => {
item.checked = !allChecked
})
}
return {
items,
checkedItems,
totalAmount,
fetchCart,
addToCart,
removeFromCart,
updateQuantity,
toggleCheck,
toggleCheckAll,
}
})