Guide for creating new document modules in the Zform ERP system. Use when the user requests to add a new document type, create a new business module, or add a new form/schema to the system.
This skill guides the creation of new document modules (e.g., 付款单, 收款登记) in the Zform ERP system.
When creating a new document module, follow these 4 steps:
Task Progress:
- [ ] Step 1: Add Prisma model to schema.prisma
- [ ] Step 2: Create frontend schema file
- [ ] Step 3: Register schema in setup.ts
- [ ] Step 4: Add menu in seed.ts and run migration
File: server/prisma/schema.prisma
enum YourDocStatus {
DRAFT
SUBMITTED
APPROVED
CANCELLED
}
model YourDocument {
id String @id @default(cuid())
// Basic info
code String @unique
status YourDocStatus @default(DRAFT)
// Business fields...
// Timestamps
createdBy String? @map("created_by")
createdAt DateTime @default(now()) @map("created_at")
updatedBy String? @map("updated_by")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
// Relations
items YourDocumentItem[] @relation("YourDocumentItems")
@@index([code])
@@index([status])
@@map("your_documents")
}
model YourDocumentItem {
id String @id @default(cuid())
yourDocumentId String @map("your_document_id")
yourDocument YourDocument @relation("YourDocumentItems", fields: [yourDocumentId], references: [id], onDelete: Cascade)
// Detail fields...
@@index([yourDocumentId])
@@map("your_document_items")
}
Important naming conventions:
@map("snake_case") for database column names@@map("snake_case_table_name") for table namesFile: src/schemas/your-document-schemas.ts
import type { DocumentSchema, ChangeRule } from "@/core/types"
export const yourDocumentSchema: DocumentSchema = {
typeId: "your_document", // Must match Prisma model table name (singular)
typeName: "你的单据名称",
masterFields: [
// === 基本信息 ===
{
id: "code",
label: "编号",
type: "text",
readOnly: true,
required: true,
group: "基本信息",
},
{
id: "status",
label: "状态",
type: "select",
options: [
{ label: "草稿", value: "DRAFT" },
{ label: "待审核", value: "SUBMITTED" },
{ label: "已审核", value: "APPROVED" },
{ label: "已取消", value: "CANCELLED" },
],
defaultValue: "DRAFT",
required: true,
group: "基本信息",
},
// Add more fields organized by groups...
],
detailTables: [
{
id: "items",
label: "明细",
editable: true,
fields: [
// Detail fields...
],
},
],
}
export const yourDocumentChangeRule: ChangeRule = {
typeId: "your_document",
watchFields: ["master.status"],
evaluate: (oldDoc, newDoc, downstreamDocs) => {
const impacts = []
// Add change impact logic...
return impacts
},
}
File: src/schemas/setup.ts
import {
yourDocumentSchema,
yourDocumentChangeRule,
} from "./your-document-schemas"
registry.registerSchema(yourDocumentSchema)
registry.registerChangeRule(yourDocumentChangeRule)
const yourDocumentActionConfig: DocumentListActionConfig = {
typeId: "your_document",
rowActions: [
{ id: "open", label: "打开" },
{ id: "copy-id", label: "复制ID" },
{
id: "delete",
label: "删除",
danger: true,
modes: ["document"],
visible: (row) => row._status === "draft",
permission: "your_document:delete",
},
],
toolbarActions: [
{ id: "create", label: "新建", icon: "Plus", variant: "outline", permission: "your_document:create" },
],
}
const yourDocumentFormActions: DocumentFormActionConfig = {
typeId: "your_document",
actions: [
{ id: "save", label: "保存", icon: "Save", variant: "outline", allowedStatuses: ["draft"], order: 1 },
{ id: "submit", label: "提交", icon: "Send", allowedStatuses: ["draft"], permission: "your_document:submit", order: 2 },
// Add more actions...
],
}
registry.registerActionConfig(yourDocumentActionConfig)
registry.registerFormActionConfig(yourDocumentFormActions)
File: server/prisma/seed.ts
financeEntryMenu):const yourDocumentMenu = await prisma.sysMenu.create({
data: {
title: '你的单据名称',
icon: 'FileText',
path: '/type-list/your_document',
parentId: financeEntryMenu.id, // Change to appropriate parent
orderNum: 3,
menuType: 'menu',
status: 'visible',
},
});
const yourDocumentBtnIds = await createDocPermButtons(yourDocumentMenu.id, 'your_document', [
...basicDocActions,
{ perm: 'close', title: '关闭' },
// Add more permissions as needed
]);
allBtnIds array:...yourDocumentBtnIds,
allMenuIds, managerMenuIds, userMenuIds):yourDocumentMenu.id,
userBtnIds:...yourDocumentBtnIds.slice(0, 3),
After completing all file modifications:
cd server
npx prisma generate
npx prisma migrate dev --name add_your_document
npx ts-node prisma/seed.ts
| Parent Menu | Variable Name | Typical Documents |
|---|---|---|
| 业务入口 | businessEntryMenu | 销售合同, 采购计划, 采购合同 |
| 财务入口 | financeEntryMenu | 付款申请, 付款单, 收款登记 |
| 单证入口 | documentEntryMenu | 出运计划, 出运单证 |
| 资料入口 | dataEntryMenu | 产品管理, 客户管理, 供应商管理 |
| 质检入口 | qualityEntryMenu | 验货单, 让步接收单 |
| 仓库入口 | warehouseEntryMenu | 库存查询, 入库管理, 出库管理 |
| Type | Usage |
|---|---|
text | Short text input |
textarea | Multi-line text |
number | Numeric input |
date | Date picker |
select | Dropdown with options |
checkbox | Boolean toggle |
id: Field identifier (matches Prisma field name)label: Display label (Chinese)type: Field typerequired: Is field mandatoryreadOnly: Is field editablegroup: Group name for form organizationspan: Column span (default 2, use 4 for full width)options: For select fieldsdefaultValue: Default value for new documents