> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 1. 数据模型

> 带有对象、字段和关系的模型文档和模板。

我们的应用需要两个自定义对象：**文档模板**（写什么）和
**文档**（生成的结果）。 让我们来定义它们。

用CLI扫描每个实体的文件 — — 它为您生成一个有效的 UUID 和
文件夹：

```bash filename="Terminal" theme={null}
yarn twenty dev:add object
```

在下方显示完成的文件。

<Note>
  每一个 `*_UNIVERSAL_IDENTIFIER' 常住寿命为
    `src/constants/universal-identifiers.ts\` 并且在使用时导入。 下面的
  代码片段省略了这些导入的简洁度 - 将它们保留在您自己的文件中。
</Note>

## 模板对象

一个模板具有一个 `name`、一个包含 `{{placeholders}}` 的 `body`，以及一个 `target`，用于指明它是为 Person 还是 Company 编写的。 `body` 是一个
`RICH_TEXT` 字段，所以二十个字段给它一个完整的文本编辑器。

```ts filename="src/objects/document-template.object.ts" theme={null}
import { defineObject, FieldType } from 'twenty-sdk/define';

export default defineObject({
  universalIdentifier: DOCUMENT_TEMPLATE_OBJECT_UNIVERSAL_IDENTIFIER,
  nameSingular: 'documentTemplate',
  namePlural: 'documentTemplates',
  labelSingular: 'Document template',
  labelPlural: 'Document templates',
  icon: 'IconFileText',
  labelIdentifierFieldMetadataUniversalIdentifier:
    TEMPLATE_NAME_FIELD_UNIVERSAL_IDENTIFIER,
  fields: [
    { universalIdentifier: TEMPLATE_NAME_FIELD_UNIVERSAL_IDENTIFIER,
      type: FieldType.TEXT, name: 'name', label: 'Name', icon: 'IconAbc' },
    { universalIdentifier: TEMPLATE_BODY_FIELD_UNIVERSAL_IDENTIFIER,
      type: FieldType.RICH_TEXT, name: 'body', label: 'Body', icon: 'IconFileText',
      description: 'Use {{placeholders}} like {{name.firstName}} or {{jobTitle}}.' },
    { universalIdentifier: TEMPLATE_TARGET_FIELD_UNIVERSAL_IDENTIFIER,
      type: FieldType.SELECT, name: 'target', label: 'Target', icon: 'IconTarget',
      defaultValue: `'PERSON'`,
      options: [
        { id: TEMPLATE_TARGET_OPTION_PERSON_UNIVERSAL_IDENTIFIER,
          value: 'PERSON', label: 'Person', color: 'blue', position: 0 },
        { id: TEMPLATE_TARGET_OPTION_COMPANY_UNIVERSAL_IDENTIFIER,
          value: 'COMPANY', label: 'Company', color: 'green', position: 1 },
      ] },
  ],
});
```

<Warning>
  `SELECT` 选项 **值** 必须是 `UPPER_CASE` (`PERSON`, 而不是`person`)，并且
  `defaultValue` 用额外引号包裹：`` `PERSON` ``。 "label" 是
  用户所看到的。
</Warning>

## 文档对象

生成的文档存储渲染的 `content` 和 `status` 。 以相同的方式定义它，并添加一个 `status` 选择字段，取值为 `DRAFT` / `GENERATED`。 完整文件：
[`document.object.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/examples/document-generator/src/objects/document.object.ts)。

## 将它们与关联到关系

每个文档都应该回到它所产生的模板。 关系是
**双向** — — 您在自己的字段文件中定义双方。

```ts filename="src/fields/document-template-relation.field.ts" theme={null}
import { defineField, FieldType, OnDeleteAction, RelationType } from 'twenty-sdk/define';

// The "many" side: each document belongs to one template.
export default defineField({
  universalIdentifier: DOCUMENT_TEMPLATE_FIELD_UNIVERSAL_IDENTIFIER,
  objectUniversalIdentifier: DOCUMENT_OBJECT_UNIVERSAL_IDENTIFIER,
  type: FieldType.RELATION,
  name: 'template',
  label: 'Template',
  relationTargetObjectMetadataUniversalIdentifier:
    DOCUMENT_TEMPLATE_OBJECT_UNIVERSAL_IDENTIFIER,
  relationTargetFieldMetadataUniversalIdentifier:
    TEMPLATE_DOCUMENTS_FIELD_UNIVERSAL_IDENTIFIER,
  universalSettings: {
    relationType: RelationType.MANY_TO_ONE,
    onDelete: OnDeleteAction.SET_NULL,
    joinColumnName: 'templateId',
  },
});
```

另一边(`template-documents-relation.field.ts`) 是一个名为`documents`的
`RelationType.ONE_TO_MANY` 字段，它指出相反的方向。
完整模式请参阅 [Relations](/l/zh/developers/extend/apps/data/relations)。

## 在 20 中查看

用 `yarn 20dev` 运行，打开 **设置 -> 数据模型**。 这两个对象都会出现，并带有你的应用标签。

<Frame caption="两个自定义对象，由文档生成器应用程序所拥有。">
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/twenty/images/docs/developers/extends/apps/documents/document-generator/01-data-model.png" alt="显示文档和文档模板的数据模型设置" />
</Frame>

创建一个模板来测试 — 名称是 *销售建议*, 设置 **Target** 为
*Person*, 并粘贴一个几个占位符的机构：

```text theme={null}
Dear {{name.firstName}} {{name.lastName}},

As {{jobTitle}} at {{company.name}}, we think you'll love our product.

Best,
The Team
```

<Frame caption="模板记录。 该机构保留其占位符直到文档生成为止。">
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/twenty/images/docs/developers/extends/apps/documents/document-generator/03-template-record.png" alt="带占位符主体的销售建议模板记录" />
</Frame>

**在这个步骤之后：** 你有 `documentTemplate` 和 `document` 对象，用
的关系链接和一个模板生成它们。 接下来，填充它的逻辑。

<Card title="下一步：生成文档 →" icon="bolt" href="/l/zh/developers/extend/apps/tutorials/document-generator/generating-document">
  写下填充模板的逻辑函数。
</Card>
