Files
bid-setup.tootaio.com/app/components/item/AddModal.vue
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

124 lines
3.1 KiB
Vue

<template>
<UModal v-model:open="open" title="新增物品" description="新增一件新的物品">
<UButton label="新增" icon="lucide:plus" />
<template #body>
<UForm
ref="itemForm"
:schema="itemSchema"
:state="itemState"
@submit="onSubmit"
class="space-y-4"
>
<UFormField label="标品名称" required name="name">
<UInput
v-model="itemState.name"
placeholder="请输入物品名称"
class="w-full"
/>
</UFormField>
<UFormField label="图片 URL">
<UInput
v-model="itemState.imageUrl"
placeholder="https://img.tootaio.com/i/2025/09/26/gxuf17.jpeg"
class="w-full"
/>
<template #hint>
<div class="text-xs text-gray-500">请粘贴您的图床图片链接</div>
</template>
</UFormField>
<UFormField label="描述">
<UTextarea
v-model="itemState.description"
placeholder="请输入物品描述(可选)"
class="w-full"
/>
</UFormField>
<UFormField label="标签">
<UInput
v-model="itemState.tags"
placeholder="Johnnie Walker,Whiskey"
class="w-full"
/>
<template #hint>
<div class="text-xs text-gray-500">用英文逗号隔开</div>
</template>
</UFormField>
</UForm>
</template>
<template #footer>
<div class="flex justify-end w-full gap-2">
<UButton
label="取消"
color="neutral"
variant="subtle"
@click="open = false"
/>
<UButton
label="创建"
color="primary"
variant="solid"
@click="itemForm.submit()"
/>
</div>
</template>
</UModal>
</template>
<script lang="ts" setup>
import type { FormSubmitEvent } from "@nuxt/ui";
import * as z from "zod";
const itemForm = ref();
const open = ref<boolean>(false);
const toast = useToast();
const { stats, isNameAvailable, addItem } = useItemsStore();
const itemSchema = z.object({
name: z
.string()
.min(1, "名称不能为空")
.refine(isNameAvailable, "该名称已被占用,请更换一个"),
imageUrl: z.string().nullable().optional(),
description: z.string().nullable().optional(),
tags: z.string().nullable().optional(),
});
type ItemSchema = z.output<typeof itemSchema>;
const itemState = reactive<ItemSchema>({
name: "",
imageUrl: null,
description: null,
tags: null,
});
const onSubmit = async (event: FormSubmitEvent<ItemSchema>) => {
const item: Item = {
id: stats.latestId.value,
name: event.data.name,
imageUrl: event.data.imageUrl,
description: event.data.description,
tags: event.data.tags?.split(",").map((tag) => tag.trim()),
createdAt: new Date(),
updatedAt: new Date(),
};
// TODO: Check is add or edit
addItem(item);
toast.add({
title: "成功",
description: `${event.data.name} 已被添加到数据库中`,
color: "success",
});
open.value = false;
};
</script>
<style></style>