Response
```ts
// stores/cart.ts
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
export interface CartItem {
id: string
name: string
price: number
quantity: number
}
export const useCartStore = defineStore('cart', () => {
const items = ref<CartItem[]>([])
function add(item: Omit<CartItem, 'quantity'>, quantity = 1) {
const existing = items.value.find((i) => i.id === item.id)
if (existing) {
existing.quantity += quantity
} else {
items.value.push({ ...item, quantity })
}
}
function remove(id: string, quantity?: number) {
const existing = items.value.find((i) => i.id === id)
if (!existing) return
if (quantity === undefined || existing.quantity <= quantity) {
items.value = items.value.filter((i) => i.id !== id)
} else {
existing.quantity -= quantity
}
}
function clear() {
items.value = []
}
const total = computed(() =>
items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
)
const itemCount = computed(() =>
items.value.reduce((count, item) => count + item.quantity, 0)
)
return { items, add, remove, clear, total, itemCount }
})
```
`add` merges into an existing line's quantity if the `id` already exists; `remove` decrements by `quantity` (default: removes the whole line) and drops the line once it hits zero.