# @foundrykit/advanced-forms-plugin 中文文档

规范地址：https://npmcn.com/package/%40foundrykit/advanced-forms-plugin/

版本：1\.16\.2
npm 元数据更新时间：2026-11-09T09:38:57.408Z
中文译文更新时间：2026-11-15T10:33:35.305Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40foundrykit/advanced-forms-plugin
原文对照：https://npmcn.com/package/%40foundrykit/advanced-forms-plugin/?lang=original
项目主页：https://github.com/umi-labs/advanced-forms-plugin#readme
源码仓库：https://github.com/umi-labs/advanced-forms-plugin

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：991 kB，511 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：^18\.20\.2 \|\| \>=20\.9\.0
- 运行依赖：1 个
- peer 依赖：zod ^3\.23\.0 \|\| ^4，react ^19，payload ^3\.84\.1，react-hook-form ^7，@radix-ui/react-popover ^1\.1\.0，@payloadcms/richtext-lexical ^3\.0\.0
- 首次发布：2026-05-28T11:44:04.639Z
- 最新版本发布：2026-11-09T09:38:57.085Z
- 近 30 天下载量：2437（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：33（近 12 个月 33 个）

## 中文简介

有效载荷 CMS 3 的多步查询表插件

## 安装

```sh
npm install @foundrykit/advanced-forms-plugin
```

也可以使用：`pnpm add @foundrykit/advanced-forms-plugin`、`yarn add @foundrykit/advanced-forms-plugin`、`bun add @foundrykit/advanced-forms-plugin`

## README

# @ foundrykit/ 高级形式- 插件

多步骤窗体插件 [有效载荷CMS 3](https://payloadcms.com/)。在您的管理面板上添加一个窗体构建器,其中包含11个内置的字段类型,可配置的提交动作,以及用于前端的即时反应组件.

## 特征

-   **多步骤形式** ——将字段组织成有可选图标和进度指标的已命名步骤
-   **reCAPTCHA v3 (英语)** · 每种形式的可选、无形的垃圾邮件保护
-   **12个外地类型** ——文本,电子邮件,电话,文本区域,复选框,收音机组,复选框组,选取,编号,日期,文件上传,地址(并带有后码查询)
-   **提交行动** ——发送电子邮件,显示确认消息,或提交后重定向(每个表单多动作,按顺序执行)
-   **两集** —— 说 `forms` 财务报告和审定财务报表 `form-submissions` 自动添加到您的有效载荷配置
-   **(原始内容存档于2013-10-12) (英语). REST API** ——通过有效载荷自定义终点获取窗体数据并提交表格
-   **前端组件** —— 说 `<EnquiryForm>` 以内置步骤导航和验证来反应客户端组件
-   **完全定制** ——禁用、替换或添加字段块类型;重命名收藏 satters

* * *

## 安装

```sh
pnpm add @foundrykit/advanced-forms-plugin
```

**同伴依赖关系** (如尚未安装)

```sh
pnpm add payload react react-hook-form @radix-ui/react-popover
```

* * *

## 快开始

```ts
// payload.config.ts
import { formPlugin } from '@foundrykit/advanced-forms-plugin'
import { buildConfig } from 'payload'

export default buildConfig({
  // Configure your email adapter here — the plugin uses payload.sendEmail
  // for the `sendEmail` submission action.
  // email: nodemailerAdapter({ ... }) or resendAdapter({ ... }), etc.
  plugins: [formPlugin({})],
  // ...rest of your config
})
```

这个 `sendEmail` 提交动作使用有效载荷内置 `payload.sendEmail`,哪个 常驻裁军谈判会议代表 [电子邮件适配器](https://payloadcms.com/docs/email/overview) 你们 在有效载荷配置上配置 。 不需要插件级电子邮件处理器 .

* * *

## 插件选项

```ts
formPlugin(options: FormPluginConfig)
```

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `disabled` | `boolean` | `false` | 注册收藏但跳过添加端点 |
| `baseUrl` | `string` | `''` | 在构建时将基础 URL 准备形成 API URL(例如. `https://example.com`(中文(简体) ) |
| `mediaCollection` | `string` | `'media'` | 显示您收藏的媒体, 用于步骤图标上传 |
| `collections.forms` | `string` | `'forms'` | 窗体收藏的标签 |
| `collections.submissions` | `string` | `'form-submissions'` | 提交文件收集的屏障 |
| `labels.forms` | `string` | `'Form'` | 表单的 Singula 管理标签 |
| `labels.submissions` | `string` | `'Form Submission'` | 提交文件的 Singula 管理标签 |
| `fields` | `FieldsConfig` | 全部内置 | 控制窗体构建器中可用的字段块类型——见 [自定义字段块](https://npmcn.com/package/%40foundrykit/advanced-forms-plugin/#readme-customising-field-blocks) |

* * *

## 垃圾邮件保护(ReCAPTCHA v3)

传出 a `captcha` 配置和每个表单的提交端点都需要验证 {\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}是CAPTCHA v3 代币 别管它了,或者把钥匙放出去,什么也没有 更改: 没有装入脚本, 不需要符号 .

```ts
formPlugin({
  captcha: {
    siteKey: process.env.RECAPTCHA_SITE_KEY,
    secretKey: process.env.RECAPTCHA_SECRET_KEY,
    minScore: 0.5,        // optional, default 0.5
    action: 'form_submit' // optional, default 'form_submit'
  },
})
```

没有别的东西可以窃听. `GET /api/form-data/:slug` 广告 **站点密钥** (按设计公开)浏览器, `EnquiryForm` 薄荷每服一剂, 财务报告和审定财务报表 `POST /api/form-submit/:formSlug` 在表单平之前验证一下 装入。 这个 **密钥永不离开服务器** - 综合测试 声称表格答复中未提及.

**得分,不是挑战.** v3 是隐形的: 它返回 0.0- 1. 0 而您选择 截断。 调色板 `minScore` 从reCAPTCHA控制台 一旦你能看到真实 交通;太高无声地拒绝真正的人.

**故意没打开.** 如果Google无法访问, 或秘密是 错误, 允许提交, 原因会被记录为错误 。 封锁 将会丢弃真实的询问 时间长度的断电或 错位,比垃圾邮件还要贵 失踪或 拒绝的代号仍然很困难 `403` 仅限 _基础设施_ 失败是 原谅我 注意日志 `[forms] captcha could not be verified`。 。 。 .

将站点密钥与每个为表格服务的域进行注册,包括 `localhost` 或每个当地提交文件都无法核实.

* * *

## 收款

### 表单( E)`forms`(中文(简体) )

存储构成定义. 可公开读取;创建/更新/删除需要认证.

每个表格文档有:

-   **标题** — 显示名称
-   **弹片** ——API中使用的独特标识符(例如. `contact-form`(中文(简体) )
-   **步骤** ——一个或多个步骤,每个步骤都有标题,可选图标,以及字段块列表
-   **额外内容** ——表上或表下可选的丰富文本
-   **行动** - 在成功提交后执行的一项或多项行动

### 提交资料`form-submissions`(中文(简体) )

每个划界案一份。 存储 :

-   **标题** ——谁寄出:答案取名 `name`, (中文(简体) ), `full-name` 或者说 `first-name` + 键 `last-name`,或者电子邮件,或者日期。 用作页面标题.
-   **表单** ——与父母形式的关系
-   **提交日期** — ISO 时间戳
-   **数据** ——提交字段值的密钥/值对
-   **元数据** —— 说 `userAgent`, (中文(简体) ), `ip`, (中文(简体) ), `referrer` 从请求中捕获

在管理员中,划界案的答案在表格本身的问题下显示,按步骤分组, 选项值显示为标签和电话、计数器和地址答案. **编辑** 在Answers卡上将文本解答变为输入,选择解答变为下拉,所以 工作人员可以在重发前修补错误的电子邮件;更改保存时保留. 电话柜台 和地址答案不能在那里编辑。 表格、日期和a **细节** 纸牌( 页面) 来源,IP,浏览器和提交上下文)是只读的.

站点可以以相同的卡片样式显示自己的提交字段 `SubmissionPanel` 从 `@foundrykit/advanced-forms-plugin/rsc`作为田园 `admin.components.Field`数字 :

```tsx
import { SubmissionPanel } from '@foundrykit/advanced-forms-plugin/rsc'

export const NotesField = ({ data }) => (
  <SubmissionPanel
    heading="Notes"
    id="notes"
    groups={[{ items: [{ label: 'Follow-up', value: data?.followUp ?? '' }] }]}
  />
)
```

**升级到 Postgres 的提交视图 :** 页:1 `title` 列是新建的,所以添加一个 移徙(`ALTER TABLE "form_submissions" ADD COLUMN "title" varchar;`重新生成导入 地图。 旧的呈文读取标题直到下次保存为止.

* * *

## 字段类型

| 块状弹片 | 说明 |
| --- | --- |
| `text` | 单行文本输入( 支持) `half` 宽度) |
| `email` | 电子邮件地址输入 |
| `phone` | 电话号码输入 |
| `textarea` | 多行文本( 可配置) `rows`(中文(简体) ) |
| `checkbox` | 单个布尔复选框 |
| `radioGroup` | 从列表中选择单一选项( :`row` 或者说 `grid` (布局) |
| `checkboxGroup` | 从列表中选择多个选项( E)`row` 或者说 `grid` (布局) |
| `select` | 下拉选择 |
| `number` | 可选数字输入 `min`, (中文(简体) ), `max`, (中文(简体) ), `step` |
| `date` | 可选取日期者 `min`编号 :`max` |
| `file` | 文件上传到有效载荷收藏( 可配置) `accept`, (中文(简体) ), `maxSizeMB`(中文(简体) ) |
| `address` | 英国邮政编码查询地址( 可配置) `defaultCountry`, (中文(简体) ), `showLine2`, (中文(简体) ), `lookupLabel`(中文(简体) ) |

所有字段块共享这些基属性: `name`, (中文(简体) ), `label`, (中文(简体) ), `required`, (中文(简体) ), `tooltip`。 。 。 .

### 旅行日期(可选入)

"你想什么时候旅行?":一个日历面板,游客在那里挑选 **一个月** (单位:一年) 月按钮)或 **确切的日期** (日历,通过 `react-day-picker`) (中文(简体) ). 这是我们自己的 面板而不是本地选择和日期输入,所以网站可以标出它: `enquiry-field__calendar*` 课程。 它不在默认的集中, 所以添加到插件中不会 更改任何现有网站的计划。 登记,然后在邮递表中添加一个迁移:

```ts
import { formPlugin, TravelDateBlock } from '@foundrykit/advanced-forms-plugin'

formPlugin({ fields: { travelDate: { block: TravelDateBlock } } })
```

答案为 `2027-08` 或者说 `2027-08-14` ,并在提交页面上显示为 "2027年8月"或"2027年8月14日". `parseTravelDate(value)` 给它覆盖的第一天和最后一天 (单位:千美元)`from`编号 :`to`,准确日期的同一天)和那个标签,用于映射一个客户关系管理系统.

要问“你灵活吗?” 只要不灵活就需要约会,就加上一个是 / 无字段和 给予旅行日期可见度规则: **规则匹配时需要此字段**,灵活 等于 `no`。 。 。 .

### 地址字段

存储一个复合值 - `{ line1, line2, city, county, postcode, country }` —— 说 在呈文中连载到JSON,同样的方式 `phone` 存储 `{ country, number, e164 }`。 。 。 .

检查由 [邮政编码.io](https://postcodes.io/):免费,没有 API 密钥, 没有人每通电话开账单,所以球场可以不看任何公开形式 一个配额。 它只解决其城镇、县和国家的邮政编码问题——它确实如此 不返回一个房地列表,所以街道线总是被打入. 手动条目是 从未被屏蔽,使字段能够用于非英国地址和何时 寻取相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.

A 类 **所需经费** 地址需要街道行和邮政编码:单是邮政编码 无法交付, 和搜索永远无法提供街道。 重用浏览 与导出助手的表格外 :

```ts
import { lookupPostcode } from '@foundrykit/advanced-forms-plugin/client'

const result = await lookupPostcode('SW1A 1AA')
// { status: 'ok', address: { postcode, city, county, country } }
// | { status: 'notFound' } | { status: 'error' }
```

* * *

## 提交行动

每个窗体配置一个或多个动作。 他们按出现顺序执行.

| 块 | 说明 |
| --- | --- |
| `sendEmail` | 通过电子邮件发送邮件 `payload.sendEmail` (使用您的有效载荷) [电子邮件适配器](https://payloadcms.com/docs/email/overview)) (中文(简体) ). 主题支持 `{{fieldName}}` 内插. |
| `confirmationMessage` | 返回 API 响应中的 Lexical 丰富文本消息,用于显示前端 . |
| `redirect` | 回返a `redirectUrl` 在API响应中。 前端组件处理导航. |

* * *

## (原始内容存档于2013-10-12) (英语). REST API

两个端点都登记在有效载荷 API 根上(`/api` (默认情况下).

### `GET /api/form-data/:slug`

以弹片取出窗体文档.

**回应:** 全文 `FormDocument` 贾森.

### `POST /api/form-submit/:formSlug`

提交窗体的字段数据.

**请求机构 :**

```json
{
  "data": { "name": "Alice", "email": "alice@example.com" },
  "metadata": { "referrer": "https://example.com/about" }
}
```

**成功反应`200`:**

```json
{
  "success": true,
  "actions": {
    "confirmationMessage": { /* Lexical rich-text node */ },
    "redirectUrl": "/thank-you"
  }
}
```

**校验出错的答复( E)`422`:**

```json
{
  "success": false,
  "errors": [{ "field": "email", "message": "Email is required" }]
}
```

* * *

## 前端用途

### 服务器组件——获取窗体数据

从 `@foundrykit/advanced-forms-plugin/rsc`数字 :

```tsx
import { fetchForm } from '@foundrykit/advanced-forms-plugin/rsc'

export default async function ContactPage() {
  const form = await fetchForm({ slug: 'contact-form' })
  return <ContactForm form={form} />
}
```

`fetchForm` 选项:

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `slug` | `string` | 所需经费 | 要获取的窗体 sattle |
| `baseUrl` | `string` | `''` | 覆盖 API 基础 URL |
| `formsSlug` | `string` | `'forms'` | 覆盖 URL 路径中使用的表单收藏 sattle |

### 客户部分——提供表格

从 `@foundrykit/advanced-forms-plugin/client`数字 :

```tsx
'use client'

import { EnquiryForm } from '@foundrykit/advanced-forms-plugin/client'
import type { FormDocument } from '@foundrykit/advanced-forms-plugin'

export function ContactForm({ form }: { form: FormDocument }) {
  return (
    <EnquiryForm
      form={form}
      onSuccess={(result) => console.log('submitted', result)}
      onError={(err) => console.error(err)}
    />
  )
}
```

`EnquiryForm` 道具 :

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `form` | `FormDocument` | 所需经费 | 表单数据由 `fetchForm` |
| `apiBase` | `string` | `''` | 提交端点的基础 URL |
| `className` | `string` | —— 说 | 适用于根元素的 CSS 类 |
| `onSuccess` | `(result: SubmitResult) => void` | —— 说 | 在成功提交后调用 |
| `onError` | `(error: SubmitError) => void` | —— 说 | 当服务器返回验证错误时调用 |
| `additionalContent` | `ReactNode` | —— 说 | 表格上或下的额外内容(尊重 `additionalContent.position` 设置) |
| `resolver` | `Resolver<Record<string, unknown>>` | —— 说 | 可选反应-hook-form 解析器(例如. `zodResolver(schema)`) (中文(简体) ). 与每个外地管理员的规则合并. |

### 验证

每个字段都会暴露一个管理员 **验证** 组 : `requiredMessage`, (中文(简体) ), `minLength` 编号 : `maxLength` 编号 : `pattern` 编号 : `patternMessage` (用于文本形状) 字段)和 `min` 编号 : `max` 编号 : `minMessage` 编号 : `maxMessage` (用于数字字段) 和多场比赛总数。 这些规则通过 `buildFieldRules` 帮助者,也从 `/client` 用于: 自定义字段组件.

对于更丰富的跨域逻辑,通过形式级解析器. 插件确实如此 **没有** 捆绑 `zod` 或者说 `@hookform/resolvers` 安装在您的应用程序中:

```sh
pnpm add zod @hookform/resolvers
```

```tsx
'use client'

import { EnquiryForm } from '@foundrykit/advanced-forms-plugin/client'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'

const schema = z
  .object({
    travelKnown: z.enum(['yes', 'no']).optional(),
    travelPlans: z.string().optional(),
  })
  .passthrough()
  .superRefine((data, ctx) => {
    if (data.travelKnown === 'no' && !data.travelPlans) {
      ctx.addIssue({
        path: ['travelPlans'],
        code: 'custom',
        message: 'Tell us a bit about what you’re looking for',
      })
    }
  })

export function ContactForm({ form }) {
  return <EnquiryForm form={form} resolver={zodResolver(schema)} />
}
```

每个外地管理员的规则和解决者一起运行——任一来源都可以标出 无效的字段,并逐个进行验证(`goNext`)尊重两者.

### Hook — 自定义格式 UI

如果您需要完全控制窗体 UI, 请使用 `useEnquiryForm` 直接 :

```tsx
'use client'

import { useEnquiryForm } from '@foundrykit/advanced-forms-plugin/client'

export function MyCustomForm({ form }) {
  const { currentStep, totalSteps, stepData, form: rhf, goNext, goBack, submit, isSubmitting } =
    useEnquiryForm({ form, apiBase: '' })

  // render whatever you like
}
```

* * *

## 自定义字段块

这个 `fields` 选项:

```ts
formPlugin({
  fields: {
    // disable a built-in type
    file: false,

    // replace a built-in type with your own block
    text: { block: myCustomTextBlock },

    // add a new type
    budgetRange: { block: BudgetRangeBlock },
  },
})
```

内置弹道: `text`, (中文(简体) ), `email`, (中文(简体) ), `phone`, (中文(简体) ), `textarea`, (中文(简体) ), `checkbox`, (中文(简体) ), `radioGroup`, (中文(简体) ), `checkboxGroup`, (中文(简体) ), `select`, (中文(简体) ), `number`, (中文(简体) ), `date`, (中文(简体) ), `file`, (中文(简体) ), `address`。 。 。 .

* * *

## 结构概览

```
src/
├── index.ts                  # Plugin entry — merges collections and endpoints into Payload config
├── types.ts                  # All shared TypeScript types (field blocks, FormDocument, plugin config)
├── collections/
│   ├── Forms.ts              # createFormsCollection factory
│   └── Submissions.ts        # createSubmissionsCollection factory
├── blocks/
│   ├── fields/               # One file per built-in field block type
│   └── submissionActions/    # SendEmail, ConfirmationMessage, Redirect blocks
├── endpoints/
│   ├── fetchFormHandler.ts   # GET /api/form-data/:slug
│   └── submitFormHandler.ts  # POST /api/form-submit/:formSlug — validates, stores, fires actions
├── components/
│   └── EnquiryForm/          # React client component and useEnquiryForm hook
├── utilities/
│   ├── fetchEnquiryForm.ts   # fetchForm — RSC utility wrapping the fetch endpoint
│   ├── buildFormURL.ts       # URL builder for the form-data endpoint
│   └── sanitizeSubmission.ts # Sanitises raw form data before storage
└── exports/
    ├── client.ts             # @foundrykit/advanced-forms-plugin/client exports
    └── rsc.ts                # @foundrykit/advanced-forms-plugin/rsc exports
```

插件遵循标准的有效载荷插件模式 : `formPlugin(options)` 返回接收并返回有效载荷的函数 `Config` 对象。 集合和端点的添加使用分布式语法来避免覆盖已存在的配置.

* * *

## 发展

```sh
pnpm dev        # Start the dev app at http://localhost:3000
pnpm test       # Run unit + integration + e2e tests
pnpm build      # Compile to dist/
```

复制 `dev/.env.example` 改为 `dev/.env` 设置 `DATABASE_URL` 财务报告和审定财务报表 `PAYLOAD_SECRET` 运行前 `dev`。 。 。 .

## 释放

运行 `pnpm release` 打开 `prod`。它撞倒了版本,更新了更改日志并推出一个 `v*` 标签. 标签触发器 `.github/workflows/publish.yml`,通过信任的方式发布到 npm 发布,所以没有npm令牌在当地或GitHub存储.

## 常见问题

### @foundrykit/advanced-forms-plugin 是什么？

有效载荷 CMS 3 的多步查询表插件

### 如何安装 @foundrykit/advanced-forms-plugin？

在项目目录运行 npm install @foundrykit/advanced-forms-plugin，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^19）、payload（^3\.84\.1）、react-hook-form（^7）、@radix-ui/react-popover（^1\.1\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @foundrykit/advanced-forms-plugin 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @foundrykit/advanced-forms-plugin 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @foundrykit/advanced-forms-plugin 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js ^18\.20\.2 \|\| \>=20\.9\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @foundrykit/advanced-forms-plugin 可以商用吗？

@foundrykit/advanced-forms-plugin 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @foundrykit/advanced-forms-plugin 的下载量有多少？

根据 npm 官方下载统计，@foundrykit/advanced-forms-plugin 在 2026/10/16 – 2026/11/14 这 30 天内被下载 2,437 次，日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @foundrykit/advanced-forms-plugin 还在维护吗？

最新版本 1\.16\.2 发布于 2026/11/09（6 天前）；至今共发布 33 个版本，其中过去 12 个月发布了 33 个；首次发布于 2026/05/28。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

