116 lines
3.3 KiB
TypeScript
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,
|
|
}
|
|
})
|