Files
bid-setup.tootaio.com/app/composables/items.ts
xiaomai e05c41eb07 feat(items): implement initial item management system
This commit introduces the foundational structure and core features for the item management application.

Key features implemented:
- **Item Listing:** A main page displaying all items in a searchable UTable.
- **Item Creation:** An "Add Item" modal with a UForm for input and validation using Zod.
- **State Management:** A `useItemsStore` composable built with `@vueuse/core`'s `useLocalStorage` to persist item data
in the browser.
- **UI Framework:** Integrated Nuxt UI for components like tables, modals, forms, and the overall layout.
- **Application Shell:** Established a default layout with a header, navigation menu, and placeholders for Export and
History pages.
- **Project Setup:** Configured pnpm workspace, Tailwind CSS, and VSCode editor settings for an improved development
experience.
2025-10-14 09:36:59 +08:00

62 lines
1.6 KiB
TypeScript

import { useLocalStorage, createSharedComposable } from "@vueuse/core";
// 类型定义
export type Item = {
id: number;
name: string;
imageUrl?: string | null;
description?: string | null;
tags?: string[] | null;
createdAt: Date;
updatedAt: Date;
};
const _useItems = () => {
const items = useLocalStorage<Item[]>("item-database", [], {
serializer: {
read: (v) => {
const parsed = JSON.parse(v);
return parsed.map((item: any) => ({
...item,
createdAt: new Date(item.createdAt),
updatedAt: new Date(item.updatedAt),
}));
},
write: (v) => JSON.stringify(v),
},
});
const stats = {
totalItems: computed(() => items.value.length),
addedThisMonth: computed(() => {
const now = new Date();
const thisMonth = now.getMonth();
const thisYear = now.getFullYear();
let count = 0;
for (const item of items.value) {
const date = item.createdAt;
if (date.getMonth() === thisMonth && date.getFullYear() === thisYear) {
count++;
}
}
return count;
}),
latestId: computed(
() => (items.value[items.value.length - 1]?.id ?? 0) + 1
),
};
const isNameAvailable = (name: string) =>
!items.value.some((item) => item.name === name);
const addItem = (item: Item) => items.value.push(item);
const removeItem = (id: number) =>
(items.value = items.value.filter((i) => i.id !== id));
return { items, stats, isNameAvailable, addItem, removeItem };
};
export const useItemsStore = createSharedComposable(_useItems);