diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c483022 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +shamefully-hoist=true \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d1227e6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "*.css": "tailwindcss" + }, + "editor.quickSuggestions": { + "strings": "on" + }, + "tailwindCSS.classAttributes": ["class", "ui"], + "tailwindCSS.experimental.classRegex": [ + ["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"] + ] +} diff --git a/app/app.vue b/app/app.vue index 09f935b..5acf3c1 100644 --- a/app/app.vue +++ b/app/app.vue @@ -1,6 +1,7 @@ - - - - + + + + + diff --git a/app/assets/css/main.css b/app/assets/css/main.css new file mode 100644 index 0000000..6379526 --- /dev/null +++ b/app/assets/css/main.css @@ -0,0 +1,10 @@ +@import "tailwindcss"; +@import "@nuxt/ui"; + +.router-link-exact-active { + @apply text-blue-600 bg-blue-50; +} + +.router-link-active { + @apply text-blue-600 bg-blue-50; +} diff --git a/app/components/item/AddModal.vue b/app/components/item/AddModal.vue new file mode 100644 index 0000000..189aec6 --- /dev/null +++ b/app/components/item/AddModal.vue @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + 请粘贴您的图床图片链接 + + + + + + + + + + + 用英文逗号隔开 + + + + + + + + + + + + + + + + + diff --git a/app/composables/items.ts b/app/composables/items.ts new file mode 100644 index 0000000..d39c68b --- /dev/null +++ b/app/composables/items.ts @@ -0,0 +1,61 @@ +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-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); diff --git a/app/layouts/default.vue b/app/layouts/default.vue new file mode 100644 index 0000000..5366a0a --- /dev/null +++ b/app/layouts/default.vue @@ -0,0 +1,54 @@ + + + + + 物品数据库 + + + + + + + + + + + + + + + + + + diff --git a/app/pages/export/index.vue b/app/pages/export/index.vue new file mode 100644 index 0000000..b9b4da4 --- /dev/null +++ b/app/pages/export/index.vue @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/pages/history/index.vue b/app/pages/history/index.vue new file mode 100644 index 0000000..b9b4da4 --- /dev/null +++ b/app/pages/history/index.vue @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/pages/index.vue b/app/pages/index.vue new file mode 100644 index 0000000..9190023 --- /dev/null +++ b/app/pages/index.vue @@ -0,0 +1,195 @@ + + + + + + + + + + + + + {{ stat.label }} + {{ stat.value }} + + + + + + + + + + + + + + + + + + + + + + + + {{ row.original.name }} + + + + + + + + {{ + tag + }} + + + + + + + + + + + + + + + + + + + diff --git a/nuxt.config.ts b/nuxt.config.ts index 11a8481..b1ad521 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -2,5 +2,6 @@ export default defineNuxtConfig({ compatibilityDate: '2025-07-15', devtools: { enabled: true }, + css: ['~/assets/css/main.css'], modules: ['@nuxt/ui'] }) \ No newline at end of file diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..c7aa842 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +onlyBuiltDependencies: + - '@parcel/watcher' + - '@tailwindcss/oxide' + - esbuild + - vue-demi diff --git a/public/resources/database-icon.png b/public/resources/database-icon.png new file mode 100644 index 0000000..43126e7 Binary files /dev/null and b/public/resources/database-icon.png differ
{{ stat.label }}
{{ stat.value }}
+ {{ row.original.name }} +