# 答案卡与表单模板

插件内置两种默认模板。只使用默认值时，无需在配置中填写模板 ID；模板必须对你的企业和应用可用。默认 ID 并不授予访问权限，插件也不会替你发布模板。

| 用途 | 配置字段 | 默认模板 ID |
|---|---|---|
| 答案卡 | `answerCardTemplateId` | `675cde2f-f526-40cb-b828-f5b2b57b8b77.schema` |
| 交互表单 | `formTemplateId` | `c2a6355b-9724-4f7e-9653-d33fcb3311bb.schema` |

## 使用默认模板

1. 在钉钉开发者后台确认应用具备所用卡片创建、更新及 Stream 回调权限。
2. 答案卡设置 `replyMode: "card"`，需要正文增量显示时再设置 `streamingEnabled: true`；表单设置 `formsEnabled: true`。
3. 重新加载并启动原绑定会话，用一条新请求验证卡片显示；表单还需验证指定操作者提交、取消及继续原任务。

平台返回成功不等于每个客户端都显示正常。默认模板无法访问时，可以使用兼容的自有模板，或暂时使用文字回复。

## 指定自己的模板

在钉钉卡片平台创建或取得与你的企业权限匹配、符合下述数据结构的模板，发布后取得模板 ID。将相应字段合并到 `config.json`，不要用这个片段替换整个配置文件：

```json
{
  "replyMode": "card",
  "streamingEnabled": true,
  "answerCardTemplateId": "YOUR_ANSWER_TEMPLATE_ID.schema",
  "formsEnabled": true,
  "formTemplateId": "YOUR_FORM_TEMPLATE_ID.schema"
}
```

配置的是模板标识，不是网址。模板 ID 允许字母、数字、连字符、下划线和点，最多200字符。

**只替换 ID 不能让任意模板兼容插件。**自有模板必须保留下述变量和交互协议；颜色、排版可以调整，但不能擅自改名或改变值的类型。

### 答案卡结构

插件通过 `cardParamMap` 传入字符串字段：

| 字段 | 用途 |
|---|---|
| `content` | 正文；流式更新时替换完整正文 |
| `copy_content` | 最终可复制的正文 |
| `blockList` | JSON字符串形式的 Markdown 内容块列表 |
| `flowStatus` | 状态值：`1`为待完成，`2`为流式生成，`3`为完成 |
| `hasAction`、`stop_action` | 当前使用字符串 `false`，不要据此生成远程停止按钮 |

流式模板必须支持更新 `content`。插件先创建实例，再结束流式状态并提交最终正文；长回复可能拆成多张卡片。

### 表单结构

插件传入以下字符串字段：

- `question_id`：本次表单交互 ID；不是模板 ID。
- `question_title`、`question_desc`：标题和说明。
- `card_status`：`pending`、`submitted`或`cancelled`。
- `form_btn_text`：按钮文字。
- `selected_text`、`selected_values`：选择展示字段，初始为空字符串及 `[]`。
- `form`：JSON字符串，结构为 `{ "fields": [...] }`。字段包含 `name`、`label`、`type`、`required`，选择题另有 `options`。

模板应将填写结果放入回调的 `cardPrivateData.params.form`，键名对应字段 `name`；提交动作的 `actionIds` 应携带本次实际 `question_id`。不要把字面量 `question_id` 当成动态值。取消动作使用 `params.user_cancel`。

身份、空间、卡片 ID 等由真实钉钉回调提供。插件只接受原账号、原操作者和原交互的回调，不接受来自聊天文字或手工请求的伪造结果。

## 验证与排障

- 创建失败：检查 ID、模板发布状态、企业可用范围和应用权限。
- 卡片空白或不更新：检查变量名、字符串类型、`content`及`blockList`绑定。
- 表单能显示但不能提交：检查 Stream 回调订阅、实际 `question_id`、字段键名及操作人是否与配置一致。
- 一些字段在客户端弹窗编辑：这是模板和客户端交互方式，不保证所有字段都能在卡片内直接输入。

排查期间可将 `replyMode` 改为 `text`，关闭 `streamingEnabled` 和 `formsEnabled`。这不会影响已配置的基础聊天。结果未知的旧卡片不要自动重发；修复后使用新的明确请求验证。
