Design Form(动态表单规格设计器)
产出动态表单的规格文档(Form Spec)。支持纯文本、图片、文档(Word/PDF/Excel)输入。
> ⚠️ 本技能只产出 form-spec.md,不构建表单。构建(JSON 配置、提交平台)由 pacp-build-form 完成。本技能的终点就是规格文档落盘。
支持的输入形态
| 输入形态 | 典型说法 | 适合场景 |
|---|---|---|
| 自然语言描述 | 「帮我设计一张立案审批表,要有案件编号、案由、当事人」 | 从零开始的业务需求 |
| PDF/Word 模板直接驱动 | 「文书模板在 xxx.pdf 第30-31页,请分析产出 spec」 | 类word文书表单(法律文书、公文、通知——有固定物理模板的) |
| 图片(截图/设计稿) | (丢一张表单截图)「照这个设计帮我整一个」 | 已有界面/纸质表单的数字化 |
| 文档(Word/Excel) | (传一份 Word)「这文件里有字段定义」 | 结构化需求文档 |
> [!important] PDF/Word 模板直接驱动(文书表单的标杆输入)
> 类word文书表单(决定书/笔录/通知书等有固定排版的公文)优先用模板文件驱动,不要让 AI 从自然语言凭空组织排版——文书的权威布局来源是物理模板,抽象描述必然走样。
>
> 用户怎么给:
> text
> 文书模板在这个 PDF 里:
> D:\xxx\执法文书模板.pdf
> 调查询问通知书在第30-31页。请分析这两页的文书结构,产出规格文档。
>
> AI 怎么处理:
> 1. 用 PyMuPDF(fitz)提取指定页的文本流(用户没给文本流时自动提取;用户给了文本流就直接用)
> 2. 识别填空位(___、××、空白)→ 映射成字段
> 3. 忽略页眉页脚(页码行、附件序号标记等非正文元素)
> 4. 保留模板原文进 spec 的「### 模板」段(来源行指向 PDF + 完整文本流)
> 5. 字段清单从填空位推导,文号字段按文号规则给默认编码规则
>
> 详见下方「类word 模板流布局」章节。
职责边界
| 做 | 不做 |
|---|---|
| 从口语/图片/文档提取需求 | 构建表单 JSON |
| 产出结构化 form-spec.md | 调 save 接口 |
| 质量门校验 | 提交平台 |
| 与用户核对至定稿 | 打开表单页面 |
终点:spec 落盘到 .pacp/specs/动态渲染/{业务名}__表单.md + 明确告知用户「规格文档已生成在 动态渲染/{业务名}__表单.md,确认无误后可用 pacp-build-form 构建表单」
5.x 平台知识权威源
> spec 词汇表背后的平台组件契约、平台机制、平台陷阱等知识,权威源在 pacp-dynamic-wiki skill:
>
> - 选词时不确定某表现词汇对应哪个平台组件 → wiki 的 5x/form-component-catalog.md
> - 涉及数据处理规则(外部数据/查询接口)→ wiki 的 5x/platform-mechanisms.md §dataObjects
> - 涉及布局语义 → wiki 的 5x/platform-data-structures.md §Template JSON 布局字段
> - 涉及文书模板(${{...}})→ wiki 的 5x/platform-mechanisms.md §EDITABLE-TEXT(如有)
>
> ZCode 会根据 description 自动触发 wiki skill。本 skill 的词汇表只声明「spec 用什么词」,词汇→平台组件的映射规则详见 wiki。
重要约束:远程配置任务,不读任何源码
> 本技能的数据来源是:远程 API(按需探查)+ 本 SKILL.md + 用户提供。禁止读取任何源码——既包括本 Skill 的 lib/scripts,也包括当前项目(cwd)里的业务代码。
统一工作根目录:.pacp/
> [!important] 所有 pacp-* skill 共用 .pacp/ 作为工作根目录
> 替代原有的 BwaiClient.createWorkspace()(系统临时目录)机制。统一到项目内固定路径。
定位方式:AI 运行时的 cwd(当前工作目录)下的 .pacp/。
> [!warning] cwd 边界
> "别探查项目结构"约束依然成立——AI 只往 .pacp/ 读写工作文件,不触碰项目内其他任何文件。"用 cwd" 只是算路径,不是探查。
目录结构:
{cwd}/.pacp/
specs/ ← form-spec.md 产出位置(本 skill 写入,pacp-build-form 读取)
动态渲染/ ← 本 skill 的隔离子文件夹(与开发功能 spec 隔离)
{业务名}__表单.md ← 表单 spec(如:调查询问通知书__表单.md)
session.json ← 共享会话凭证(本 skill 探查时写入,build 复用)
active/ ← 进行中的工作区(探查结果、trace 等)
{业务名}_{时间戳}/
api-trace.jsonl
table-info.md
衔接方式:本技能把 spec 写入 .pacp/specs/动态渲染/{业务名}__表单.md,返回业务名给用户。pacp-build-form 接收业务名定位 spec(优先查 动态渲染/{业务名}__表单.md,兜底兼容旧命名 {业务名}.md)。
> [!important] 文件名命名约定:表单 spec 统一加 __表单 后缀
> 一个业务名可能对应多个表单和列表(如"调查询问通知书"有录入表单 + 列表,"执法案件"有立案表单 + 审批表单 + 列表)。
> 表单 spec 文件名统一为 {业务名}__表单.md,与列表 spec {业务名}__列表.md 区分(同目录 .pacp/specs/动态渲染/,靠后缀区分)。
> - 表单 spec:调查询问通知书__表单.md(本 skill 产出)
> - 列表 spec:调查询问通知书__列表.md(pacp-design-list 产出)
>
> 业务名可包含区分词:同业务多表单时,业务名本身带区分(如调查询问通知书_录入、调查询问通知书_审批),文件名如调查询问通知书_录入__表单.md。
> [!important] session 跨 skill 共享
> 探查需要 session 时:调 pacp-system-login 获取 → 写入 .pacp/session.json。pacp-build-form 启动时读此文件复用,过期则重新获取。session.json 是可选缓存优化,不是必需。
>
> 登录强制 chrome-devtools MCP:获取 JSESSIONID 只接受用户直接提供 或 pacp-system-login(基于 chrome-devtools MCP)。不接受其他不可靠方式。chrome-devtools MCP 不可用时,建议用户安装或直接提供 JSESSIONID。
与 pacp-stylepack 风格包的关系(不读完整包)
> [!important] 本技能不读风格包完整内容
> 延续"风格感知延后"原则。本技能只记录用户指定的风格名到 spec 元信息。
>
> - 用户说"用执法处罚-表格风格" → spec 元信息记录"风格:执法处罚-表格",到此为止
> - 词汇表的自定义组件标注(如"签名 ⚠️自定义组件")是通用标注,与风格无关
> - 风格包完整内容的加载和映射延后到 build 阶段
>
> 收益:spec 产出更快启动 + 省 token。
> [!warning] 设计阶段禁止激活 pacp-stylepack skill
> 本技能运行时,主 agent 不得调用 Skill 工具激活 pacp-stylepack。风格名只需作为字符串记录到 spec 元信息(如"风格:执法处罚-文书"),到此为止。
> - ❌ 禁止:Skill(pacp-stylepack) / 读 stylepacks/*.md / 读 pacp-stylepack SKILL.md 的风格包清单
> - ✅ 允许:把用户说的风格名原样写入 spec 元信息的「风格」行
>
> 风格包的完整加载和组件映射由 pacp-build-form 在构建阶段负责。设计阶段加载 stylepack 会多消耗 token 且无产出(design 不做组件映射)。
> [!important] 风格字段:默认无,仅用户显式指定时才填具体风格名
> spec 元信息的「风格」字段遵循「默认无」原则:
> - 用户没显式指定风格 → 风格填「无」(或留空)。AI 不得根据表单特征(如"看着像表格"、"有文书模板")自行推断并套用风格包名
> - 用户明确说「用 xxx 风格」 → 才在 spec 里填具体风格包名(如「执法处罚-表格」)
> - 泛词不算显式指定:用户说「用表格风格」「用文书风格」这类泛指词(未点名具体风格包),按未指定处理——填「无」或追问具体哪个。理由:风格包是业务语义强绑定的资产("执法处罚-表格"带执法业务语义),强匹配泛词会导致语义错配
> - 禁止自作主张:AI 看到「类excel网格」布局不能自动填「执法处罚-表格」,看到「文书模板流」不能自动填「执法处罚-文书」——风格包是业务语义强绑定的资产,必须用户主动声明
>
> 这条规则与「设计阶段禁止激活 stylepack」配套:前者管"填不填风格名",后者管"读不读风格包内容"。
探查策略(可选)
> [!important] 探查是可选项
> 只有用户没有提供表名和字段名时才探查。
| 触发条件 | 是否探查 | 是否需要 session |
|---|---|---|
| 用户给了表名 + 字段名 | ❌ 否 | ❌ 否(纯文本产出) |
| 用户给了表名,没给字段名 | ✅ 探查列 | ✅ 需要(getColumns) |
| 用户没给表名(需模糊匹配) | ✅ 探查表 | ✅ 需要(getTables) |
| 用户没给表名(明确要新建表) | ❌ 否 | ❌ 否(--no-table 模式) |
探查能力复用:本技能通过相对路径 require('../pacp-build-form/lib/bwai_client.js') 复用 BwaiClient(两 skill 同处 skills/ 目录)。需登录时调 pacp-system-login skill。
表名探查(可选)
表名探查前置——产出 spec 元信息时,如需探查,用 getTables() 轻量匹配表名/注释:
- 用户明确给出表名 → 直接用
- 用户给业务描述 → getTables 模糊匹配(唯一匹配直接用 / 多匹配列出候选让用户选 / 零匹配问用户)
- 用户未给 → 直接问
处理流程
1. 意图解析 → 2. [可选]探查表名/列 → 3. 产出 Spec 草稿 → 4. 质量门自检 → 5. 与用户核对至定稿 → 6. 落盘
阶段1 意图解析 + 产出 Spec 草稿
从用户口语 + 表注释提取,产出 Spec MD 草稿:元信息(表名/风格/数据源)+ 字段清单(字段块)+ 布局。
Spec 草稿标注不确定点——草稿里对 AI 推断的表现形式/必填/字段归属,主动标「⚠️ 推断」引导用户高效核对,减少来回。
> [!note] Spec 复用入口
> 用户说「基于 XX 的 spec 改」时,让其给 .pacp/specs/动态渲染/ 下的业务名或直接贴内容,AI 读取已有 spec 作为起点而非从零产出;全新需求则从用户口语产出。
阶段2 [可选] 探查
仅当用户没给表名/字段名时执行(见上方探查策略表)。探查结果保存到 .pacp/active/{业务名}_{时间戳}/table-info.md。
阶段3 产出 Spec 草稿
按下方「Form Spec 结构化契约」产出草稿。
阶段4 质量门自检
产出草稿后、展示给用户前,必须跑一遍质量门自检清单(见下方「质量门」)。缺项则先补全再展示。
阶段5 与用户核对至定稿
- AI 展示 Spec 草稿,用户指出修改点(草稿展示 + 自然语言迭代,不用结构化确认)
- 迭代至用户说「可以」即定稿
- 代码集编号用户当场给不出 → Spec 标「待定」,延后到 build 阶段
阶段6 落盘
定稿后落盘到 .pacp/specs/动态渲染/{业务名}__表单.md(子文件夹不存在则自动创建),返回业务名给用户。
Form Spec 结构化契约
# Form Spec:{表单名}
## 元信息 ← 必填段
- 表单标题:{必填}
- 模板名称:{必填}
- 关联表:{表名 或 标注"新建"} ← 必填
- 数据源:默认 jdbc/default
- 主键:{用已有表必填;新表默认 XH——平台统一主键,禁止写 ID}
- 风格:{无/风格包名} ← 默认无,仅用户显式指定具体风格包名时才填(见上方「风格字段:默认无」规则)
> [!important] 主键铁律:新表一律 XH
> 平台统一主键是 `XH`(VARCHAR(50)),不是 `ID`。新表 spec 主键行默认填 `XH`;用已有表时填 `getPrimaryKey()` 查到的实际主键。写错主键会导致外键关联、子表数据加载连锁失败。
## 字段清单 ← 必填段,至少1个字段
### {字段名} {含义} ← 每个字段一个小标题
- 表现形式:{词汇} ← 必填,用表现词汇表
- 代码值:{编号} ← 仅代码集字段必填,非代码集不写此行
- 必填:是/否 ← 必填
- 说明/模板:{可选}
## 布局 ← 必填段
- 范式:类excel网格 / 类word文书 ← 必填声明
- [类excel时] 逐字段布局表(见下方规则) ← 必填
- [类word时] ### 模板 段 ← 必须贴模板文本流或引用文件
- [有子表时] 子表名 + 外键字段 ← 必填
## 数据处理规则 ← 可选段,无动态行为时不写(见下方「数据处理规则段规则」)
表现词汇表(两层 + AI 兜底)
> [!important] 词汇表分层
> 第一层:标准词汇(封闭)——优先用,build 有内置映射:
> 单行文本/多行文本/下拉选择/单选/多选/日期/附件/人员/部门/富文本/数字/密码/地图经纬度/行政区划/树形选择/列表选择
>
> 第二层:自定义组件表现名(开放)——项目组开发的自定义组件(如"签名"):
> - 原样记录用户用词 + 标注「⚠️ 自定义组件」(通用标注,与风格无关)
> - build 查 pacp-stylepack 风格包找映射
>
> 兜底:都映射不到 → AI 自行决定(build 阶段,不卡住)
Form Spec 字段块规则
每个字段一个小标题 + 属性列表(不用表格,便于手工维护):
### {字段名} {含义}
- 表现形式:{词汇}
- 代码值:{代码集编号} ← 仅代码集字段
- 最大长度:{数字} ← 仅文本字段(单行文本/多行文本)
- 必填:是/否
- 说明/模板:{可选}
> [!important] 表现形式用词汇层
> 用用户能看懂的词汇:标准词(单行文本/多行文本/下拉选择/单选/多选/日期/附件/人员/部门)+ 自定义组件表现名(如「签名」)。禁写平台内部术语(CODESET/CHECKBOX 等);组件映射由 build 阶段完成。
> [!important] 文本字段必须声明最大长度(防二次编辑报错)
> 表现形式为「单行文本/多行文本」的字段,必须单列一行「最大长度」声明数值。平台元素属性 ZDCD 是必填项,缺失会导致表单渲染正常但进设计器二次编辑时报错(build 阶段有必填属性校验门,会拦截缺失 ZDCD 的提交)。
>
> - 用户给了明确长度 → 直接填
> - 用户没给 → AI 按默认规则推导并标「⚠️ 推断」:单行文本默认 100,多行文本默认 2000
> - 用户可在核对时调整
>
> markdown
> ### DSRMC 名称或姓名
> - 表现形式:单行文本
> - 最大长度:100 ⚠️ 推断
> - 必填:是
>
> [!important] 代码集字段:代码值行直接填编号
> 表现形式为「下拉选择/单选/多选」的字段,单列一行「代码值」直接填代码集编号(如 XZCF_AJLY,用户给、AI 不猜;给不出标「待定」延后 build 阶段)。表现形式不再标注「(代码集)」。非代码集的固定选项用「选项」行列出内容。
> [!important] 文号字段:spec 阶段必须定默认编码规则(禁止甩给 build/后端)
> 字段含义含"文号/编号/字号"且需系统自动生成的字段,spec 必须提供默认编码规则,用户可在此基础上调整。
> 文号的最终落库仍是后端行为(保存时调编号生成器),spec 阶段定的是规则契约(前缀/年份/流水号格式),不是实现。
>
> 文号字段专用属性(表现形式为「自动生成」时必填):
> markdown
> ### {字段名} 文号
> - 表现形式:自动生成
> - 编码规则:
> - 格式模板:`{前缀}〔{年份}〕{流水号}{后缀}`
> - 年份:当前 4 位年度(如 2026)
> - 流水号:年度内从 1 递增,跨年归零(默认不补零;如需固定位数写 `001` 形式)
> - 示例:`环调询通〔2026〕1号`
> - 生成器标识:{seqNumber/SXBH,用户直接给则填,如 1784099117607013819904;未给则留空,build 阶段查/建}
> - 必填:是
>
>
> 默认编码规则推导:用户没明确给规则时,AI 从字段语义推导默认前缀——取文书名关键词拼音首字母 + 〔{年份}〕{流水号}号(如"调查询问通知书"→环调询通),标注「⚠️ 推断」让用户核对。生成器标识行只在用户明确给出时填写,AI 不推导。
> [!important] 列表选择字段:字段块只标表现形式,回填映射放「数据处理规则」段
> 表现形式为「列表选择」的字段(点击弹窗选择数据并回填),字段块只写表现形式 + 必填 + 说明,不写回填映射/选择源/多选等配置——这些是跨字段的动态行为,统一放「## 数据处理规则」段的「列表选择」规则块里(见下方「数据处理规则段规则」)。
>
> 字段块写法:
> markdown
> ### JCXMID 监测项目ID
> - 表现形式:列表选择
> - 必填:否
> - 说明:存选中监测项目的主键,多选逗号分隔
>
>
> 一个列表选择字段通常配套一个「显示字段」(存选中项名称,单行文本)。两个字段都在字段清单里声明,回填关系在数据处理规则段描述。
Form Spec 布局段规则
布局段描述字段如何组织成最终界面。两种范式,布局规则不同:
类excel 网格表单:用结构化逐字段布局表(语义描述式),不允许散文描述。每个字段必须显式声明布局语义:
## 布局
- 范式:类excel网格
| 字段 | 布局语义 |
|------|---------|
| [全局标题] | 独占行 |
| AJBH | 半行(一行2个) |
| AJMC | 半行(一行2个) |
| LARQ | 半行(一行2个) |
| [基本信息标题] | 独占行 |
| TSNR | 独占行(跨整行) |
布局语义词汇表(封闭,build 映射为 XSGS):
| 布局语义 | 含义 | XSGS 映射 |
|---|---|---|
| 独占行 | 跨整行 | 1 |
| 半行(一行2个) | 占 1/2 | 2 |
| 三分之一行(一行3个) | 占 1/3 | 3 |
| 四分之一行(一行4个) | 占 1/4 | 4 |
> [!important] 为什么不用散文描述
> 散文描述("标题独占一行,普通字段一行2个")经常被 build 忽略,导致布局失真。结构化表格让每个字段的布局意图显式、逐字段可映射,build 照表填 XSGS 即可。
>
> 容器组件(TITLE/GROUP)也列入布局表,用 [组件名] 标注(如 [基本信息标题]、[检查记录子表]),布局语义同样适用。
类word 文书表单:文书的权威布局来源是物理模板(word/pdf),抽象描述无法承载精确排版。有模板时,布局段必须贴模板文本流作为骨架(见下方「类word 模板流布局」),不受结构化表格约束。
> [!important] 类word 模板流布局(核心机制)
> 类word 表单的布局失真是高发问题——无模板基准时 AI 只能逐字段拼接,产出必然走样。
>
> 有模板时(优先):布局段贴模板文本流 + 占位标记。构建阶段基于模板流替换 ___ → ${{...}},保证原始排版关系。
>
> 无模板时(降级):根据字段清单自行组织,产出质量打折但可用。
模板段写法(三种形态,支持引用文件):
| 形态 | 写法 | AI 处理 |
|---|---|---|
| 引用文件 + 贴文本流 | 来源行 + 模板正文 | 直接用正文(最完整,推荐) |
| 只引用文件 | 只有来源行,无正文 | AI 用工具提取文件指定页的文本流,自动标注 ___ |
| 只贴文本流 | 只有模板正文,无来源行 | 直接用正文 |
来源行格式:
> 来源:{文件路径或文件名} 第{起}页-第{止}页 # 多页
> 来源:{文件路径或文件名} 第{N}页 # 单页
> 来源:{文件路径或文件名} # 整个文件
文件提取路径(只引用文件时 AI 自动执行):
- PDF:PyMuPDF(fitz)提取文本流 → 标注填空位
- Word(.doc/.docx):mammoth / python-docx 提取段落文本
- 图片(.png/.jpg):zai-mcp-server OCR(extract_text_from_screenshot)提取文字
- 提取后自动应用忽略页眉规则
### 模板
> 来源:{文件路径或文件名} 第{页码}页
> 约定:`___` = 填空位(绑定字段),`××` = 占位文字(可填具体值)
> 规则:忽略页眉(每页重复的签名+页码行,电子表单无分页概念,签名由落款区承载)
{完整模板文本流,保留原始排版关系,可填位用 ___ 标注}
> [!warning] 模板段禁止省略
> 模板段的文本流必须完整,逐字逐行录入,不允许任何省略:
> - ❌ 禁止 ……(共12项) 省略编号项——逐项完整列出
> - ❌ 禁止 ……(固定法律文书,不可改)…… 省略固定文——法律文书全文逐字录入
> - ❌ 禁止「省略中间若干字段」——所有字段行完整保留
> - ✅ 从源文件提取时,提取多少贴多少,不做概括/缩减
占位标记三种:
| 标记 | 含义 | PDF 模板对应 | 构建映射(build 阶段) |
|---|---|---|---|
___(下划线序列) |
空白填空位,用户从零填写 | 无下划线文字的空白线 | → ${{"formKey":"字段名","value":""}} |
‹ ›(单书名号) |
预填可编辑区,提供默认值,用户可删改 | 带下划线的文字 | → ${{"formKey":"字段名","value":"默认文本"}} |
××(叉号序列) |
占位文字,可填具体值 | 无下划线的 ×× | → ${{...}},value 带默认占位 |
> [!note] ‹ › 的两种子类型(构建无差异,仅帮 AI 识别)
> - 默认值型:大段参考内容,用户在其基础上删改。如现场情况 12 项默认文字、确认位填写指引
> - 占位词型:短词提示"填什么",用户替换为具体值。如 ‹姓名›、‹编号›
忽略页眉:物理模板每页顶部重复的签名+页码行(如「签名: 年 月 日 第_页 共页」),一律不写入模板段。理由:电子表单无分页概念,签名由落款区承载。
Form Spec 数据处理规则段规则
> [!important] 数据处理规则段:承载动态行为(可选段)
> 表单的字段清单 + 布局描述静态结构;动态行为(字段间计算、联动、初始值带入、列表选择回填)统一放「## 数据处理规则」段。
>
> 该段是可选段——无动态行为的简单表单(纯录入表单)不写此段。
>
> 承载原则:业务规则归 spec,实现映射归 build。spec 描述"要实现什么业务规则",build 映射成 events 脚本/dataObjects 配置等实现。这与"表现形式→SELECT_ELEMENT"是同一分层哲学。
段结构契约
## 数据处理规则
### 计算:{语义规则名}
- 目标字段:{字段名}
- 公式:{自然语言或半结构化公式,如 ZF = YW + SX + YY}
- 依赖字段:{字段名列表}
- 触发:{依赖字段任一变化时重算}
- 可编辑:{否(只读,推荐)/ 是}
### 联动:{语义规则名}
- 触发字段:{字段名}
- 触发条件:{可选,如 值变化 / 值='立案'}
- 目标字段:{字段名}
- 行为:{清空 / 赋值 / 联动查询 / ...开放,枚举仅引导不限制}
- 行为参数:{行为为赋值时填,如 默认值'类型一默认备注'}
- 说明:{可选,自然语言补充}
### 初始值:{语义规则名}
- 目标字段:{字段名列表,可多个}
- 来源类型:{枚举值,见下方来源类型表}
- 来源描述:{自然语言补充,可选}
- 带入参数:{字段名,主键带入}
- 联动带入:{可选,根据带入参数查询后回填的其他字段}
### 外部数据对象:{语义名}
- 目标表单:{表单名}(design 阶段填表单名;build 增量修改时补 templateId)
- OBJECT_NAME:{英文键名} ← 可 AI 推断
- 中文名:{OBJECT_NAME_CN} ← 可 AI 推断
- 数据来源:【硬门槛,二选一必填】
- [ ] 已有查询接口,QUERYXH = ____________
- [ ] 无现成接口,需先基于数据源表 ____________ 建查询配置
- 运行参数(PARAMS):无 / ____________ ← 可 AI 推断
- ⭐ 取值方式:【硬门槛,必填】
- [ ] 默认值回填:取首条记录字段 ___ 填入表单字段 ___
- [ ] 脚本取用:在 onDataLoaded 里读取 dataObjects.{OBJECT_NAME}(说明:___)
- [ ] 配套选择器:字段需改为 DYNAMIC_DATA_SELECT —— ⚠️ 选此项说明真实需求是“字段可选”,单独配 dataObjects 达不到目的,应改用「列表选择」规则或显式声明字段组件改动
- 操作类型:【全量覆盖语义下必填,build 阶段填】
- 新增第 N 条 / 修改第 N 条(原 OBJECT_NAME=___)/ 删除第 N 条(OBJECT_NAME=___)
- 影响字段:{field 列表} ← 可 AI 推断
### 列表选择:{语义规则名}
- 目标字段:{字段名,存选中行主键}
- 显示字段:{字段名,存选中行名称}
- 选择源:{列表 spec 文件名 / ⚠️待定 / 具体ID}
- 多选:是/否
- 回填映射:
- {表单字段} ← 选中行.{列表字段}
- {表单字段} ← 选中行.{列表字段}
- 筛选条件:{可选,弹窗时固定的查询条件,自然语言描述}
### 字段控制:{语义规则名}
- 触发字段:{字段名}
- 触发条件:{JS 条件表达式,如 `value === '其他'`}
- 目标字段:{被控制的字段名}
- 行为:{显示 / 隐藏 / 必填 / 非必填}
- 说明:{可选,自然语言补充}
> [!note] 外部数据对象规则块的双阶段用途
> 本规则块在 design 阶段(新建表单)填写;build 阶段对已有表单的增量修改也用此结构(增量回写)。build 阶段涉及 dataObjects 修改时,还需走 build-form 的「🔴 外部数据对象修改门禁」四步流程。
规则命名约定
- 小标题格式:
### {类型}:{语义规则名} - 语义规则名是用户起的业务语义名(如「总分自动汇总」「类型切换清空子类」),非字段名
- 目标字段在规则块内单行声明(
- 目标字段:ZF) - 一条规则块对应一条独立规则,不合并
各类规则的设计要点
计算:公式自描述,不单列「类型」字段(求和/求积等从公式本身能看出)。可编辑默认推荐「否」(自动计算字段设只读,防止用户手动覆盖)。
联动:行为字段保持开放,枚举(清空/赋值/联动查询)仅引导不限制。用户可填枚举外的自然语言(如"收窄B字段选项范围"),build 按语义映射。行为参数是条件必填(行为=赋值时必填,清空时不需要),不单独进质量门,留给用户核对阶段。
字段控制:行为为封闭枚举(显示/隐藏/必填/非必填),不允许自然语言扩展。设计时需明确:
- 触发条件用 value 指代触发字段当前值(如 value === '其他'),build 阶段替换为 model.value.XXX
- 隐藏行为默认联动设为非必填(平台运行时自动处理),spec 中无需额外声明
- 多条规则触发字段相同 → build 合并为同一个 $watch;触发字段不同 → 各自独立监听
> [!important] 联动规则 vs 列表选择规则的职责边界
> 「弹窗选中后回填字段」与「字段变化触发赋值」在语义上有重叠,需明确分工避免重复配置:
> - 选中后回填(包括赋值和清空)统一由列表选择规则的回填映射承载——列表选择规则已声明选中后哪些字段被写入
> - 联动规则只用于非弹窗触发的字段间行为——如「A字段手输变化→清空B字段」「A字段=特定值→给C字段赋默认值」
>
> 即:同一个"选供应商后回填名称电话"的需求,只写一条列表选择规则(回填映射列全),不要再补一条"供应商变化→赋值名称"的联动规则。但如果需求是"供应商被清空时也要清空名称电话",这个清空语义可以补一条联动规则(因为清空不是选中动作)。
初始值:来源类型见下方枚举表。质量门只校验「来源类型有值」,不强校验枚举范围。用户可填枚举外的自然语言。
列表选择:选择源三种情况见下方引用语法表。回填映射的目标字段(FORM_COLUMN)必须在字段清单中存在(formModel 的 key 是业务表字段名,写入了才会落库)。
来源类型枚举(初始值规则专用)
| 来源类型 | 含义 | 对应 build 实现 |
|---|---|---|
| 外部带入 | URL参数/上游页面跳转带入 | URL解析 / dataObjects.PARAMS |
| 查询接口 | 后端查询接口预加载 | 涉及此类来源统一用「外部数据对象」规则块描述(见上方段结构契约),不再借住在初始值规则 |
| 当前用户 | 登录用户信息(userName/userOrg等) | globalVars |
| 默认值 | 静态默认值 | 字段块「说明」行已承载,一般不单列规则 |
> 质量门只校验「来源类型有值即可」,不强校验枚举范围。用户可填枚举外的自然语言描述(如「上一个流程节点带过来的」),build 阶段按语义映射。
选择源引用语法(列表选择规则专用)
> [!important] 引用键统一用文件名,与列表→表单方向对称
> 表单的「列表选择」规则用列表 spec 文件名引用选择器列表(如 监测项目选择__列表),不用业务名。这与列表 spec 的「关联表单」字段用表单 spec 文件名引用(如 调查询问通知书__表单)方向对称。统一用文件名的原因:同业务可能有多选择器列表(如 供应商选择_主__列表 / 供应商选择_停用__列表),业务名会歧义,文件名唯一精确。
| 情况 | 写法 | build 处理 |
|---|---|---|
| A. 选择器列表 spec 已存在 | 选择源:监测项目选择__列表(文件名) |
按文件名查 .pacp/specs/动态渲染/{文件名}.md 的构建记录取 XH |
| B. 选择器列表 spec 未建 | 选择源:⚠️待定(需先设计选择器列表 spec) |
停止,提示用户先设计选择器列表 |
| C. 用户直接给具体ID | 选择源:a1b2c3d4-...(dynamicId) |
直接用 |
跨 spec 引用一致性(软提醒)
> [!note] 列表选择规则引用列表 spec 时
> 当列表选择规则的「选择源」填的是文件名(情况A),design-form 质量门不做跨文件硬校验(保持单文件自检原则)。仅在展示 spec 草稿时附一句提醒:
> 「请确认列表 spec『{文件名}』已设计且列表用途=选择器」
>
> 真正的硬校验在 build 阶段——build 本就要查 {文件名}.md 取 XH,顺带校验列表用途字段是否为「选择器」。
质量门:Spec 完整性自检清单
> [!important] 质量门是 AI 自检(结构完整),用户核对是业务对齐(内容正确)。两者都要:
> 质量门通过 → 展示给用户核对 → 用户说「可以」→ 落盘。
> 质量门不通过 → 不展示,先补全。
产出 spec 草稿后、落盘前,必须跑一遍自检清单:
□ 元信息段:表名已确认(用户给 / 探查确认 / 标注新建)
□ 元信息段:主键已确认(用已有表时填实际主键;新表默认 XH)
□ 字段清单:每个字段四要素齐全——字段名 + 含义 + 表现形式(词汇) + 必填
□ 代码集字段:LYZ 编号已填(用户给)或标注"待定"(延后到 build 阶段)
□ 文号字段(表现形式=自动生成):编码规则已给出默认值(格式模板 + 流水号规则),不允许标"待定"甩给 build
□ 文本字段(表现形式=单行文本/多行文本):最大长度已声明(用户给或 AI 推断单行100/多行2000),缺失会被 build 校验门拦截
□ 布局段:范式已明确(类excel网格 / 类word文书)
□ [类word时]:模板流已提供(贴文本流 / 引用文件)
□ [有子表时]:子表名 + 外键字段
□ [有计算规则时]:每个计算规则——目标字段 + 公式 + 依赖字段 齐全
□ [有联动规则时]:每个联动规则——触发字段 + 目标字段 + 行为 齐全
□ [有字段控制规则时]:每个字段控制规则——触发字段 + 触发条件 + 目标字段 + 行为 齐全,且行为为显示/隐藏/必填/非必填之一
□ [有初始值规则时]:每个初始值规则——目标字段 + 来源类型 有值(来源类型不强校验枚举)
□ [有外部数据对象规则时]:每个外部数据对象规则——数据来源有值(QUERYXH 或数据源表二选一)
□ [有外部数据对象规则时]:每个外部数据对象规则——取值方式有值(默认值回填 / 脚本取用 / 配套选择器 三选一;选“配套选择器”时提示需求跨边界)
□ [有列表选择规则时]:选择源有值(列表 spec 文件名/⚠️待定/具体ID 三选一)
□ [有列表选择规则时]:回填映射的目标字段在字段清单中存在
缺项处理:不落盘,逐项追问用户。代码集编号当场给不出 → 允许标「待定」延后(唯一软项,其余硬性)。
> [!note] PXH 列检查不在本技能职责内
> PXH(子表排序号)属于平台实现细节。spec 里子表只标注子表名+外键,PXH 是否缺失由 build 在探查列时处理。
API 速查(探查时按需使用)
> 以下仅探查时使用,通过 require('../pacp-build-form/lib/bwai_client.js') 引入。
const { BwaiClient } = require('../pacp-build-form/lib/bwai_client');
const client = new BwaiClient(BASE_URL, SESSION_ID);
// 探查表名
const tables = await client.getTables(); // [{ TABLE_NAME, TABLE_COMMENT }]
// 探查列
const columns = await client.getColumns('表名'); // [{ COLUMN_NAME, COLUMN_COMMENT, DATA_TYPE }]
// 代码集核验(可选)
const codeClassList = await client.getCommonCodeClassList({ pageSize: 10000 });
图片与文档输入
当用户传入图片或文档(Word/PDF/Excel)路径时,按 references/doc-and-image-input.md 规范提取表单结构信息,产出 spec(非构建配置)。
> [!important] 与原 pacp-build-form 的差异
> 原 doc-and-image-input.md 产出的是 elements 配置(走 form_creator 构建)。本技能迁移后,产出的是 form-spec.md(规格文档),不走构建。图片/文档解析的最终产物是 spec 的字段清单,而非 elements 数组。