yida-formula · diff
git:20261018.e0d7221 to git:20261019.f4860b5
63 added, 7 removed. Audit A to A.
---
name: yida-formula
- description: 指导宜搭公式配置,包括金额计算、明细汇总、默认值、提交校验、节点筛选和报表计算。提供嵌套 IF、AND/OR、子表和复杂节点的完整示例,说明字段引用与保存方法。新增、修改或排查公式时使用,各设计器共用此入口。
+ description: 配置和排查宜搭公式,包括金额计算、明细汇总、默认值、提交校验、节点筛选和报表计算。提供完整嵌套示例;字段公式可带样例按原生计算链路试算,核对绑定与类型转换。各设计器共用此入口。
---
# 配置宜搭公式
先说明想得到什么结果,例如“单价乘数量,保留两位小数”“提交时提醒编号重复”“按上一步的金额筛选记录”。再读取已有配置,确定输入数据和结果存放位置。
- 同一种公式用法共用这里的说明。页面名称不同,也可以采用相同配置;真正需要区分的是字段引用、保存内容和执行时的数据。
+ 公式写法、嵌套、字段引用、空值和类型转换统一在这里维护。对应的业务技能提供真实字段、输入数据和结果保存位置。同样的表达式与执行方式共用规则;需要适配哪些差异,由实际输入、保存结构和执行调用决定,不按页面名称另分一套公式能力。
## 先认清要保存的内容
| 想做什么 | 要配置的内容 | 阅读说明 |
| --- | --- | --- |
| 自动填金额、日期、人员,汇总明细 | 普通字段的默认值公式 | [字段取值与完整配置](references/field-values.md) |
| 提交时检查金额、日期、重复值 | 校验公式、提示文字和阻断方式 | [校验、动作及其他表达式](references/expression-formats.md) |
| 获取数据时按上一步的字段或计算结果过滤,按公式进入分支,计算赋值 | 节点表达式和可供选择的上游字段 | [节点表达式](references/automation-formulas.md) |
| 用高级函数新增、修改、删除数据 | 业务动作及触发时机 | [表达式保存方式](references/expression-formats.md),配合 `yida-business-rule` |
| 给图表或数据集增加计算列 | 数据集表达式、数据类型和汇总方式 | [表达式保存方式](references/expression-formats.md),配合 `yida-report` |
| 在页面代码或自定义校验函数中计算 | JavaScript 表达式或回调函数 | [表达式保存方式](references/expression-formats.md),配合原页面或表单技能 |
表单中的普通字段配置也适用于流程表单中的同类字段。节点公式用于哪些设计器,以目标节点实际提供的输入为准。自定义页面上的原生组件若暴露相同公式属性,可以沿用相同方法;页面代码里的计算则按 JavaScript 处理。
+ ## 字段 Schema 中怎样保存公式
+
+ 宜搭的字段计算使用普通组件,例如 `NumberField`、`TextField`、`DateField`、`EmployeeField`,无需创建独立的“公式字段”组件。公式配置在组件的 `props` 中:
+
+ | 属性 | 应填写的内容 |
+ | --- | --- |
+ | `valueType` | `"formula"`,表示使用公式取值 |
+ | `formula` | 公式字符串 |
+ | `complexValue` | `{"complexType":"formula","formula":"同一公式字符串"}` |
+
+ 例如,数值字段的 `props` 中保存:
+
+ ```json
+ {
+ "valueType": "formula",
+ "formula": "ROUND(#{numberField_price} * #{numberField_qty}, 2)",
+ "complexValue": {
+ "complexType": "formula",
+ "formula": "ROUND(#{numberField_price} * #{numberField_qty}, 2)"
+ }
+ }
+ ```
+
+ 两处公式保持一致。使用 `create-form create/update` 时可以只提供 `formula`,CLI 会同步这三个属性。修改已有字段时保留其他属性;流水号的专用公式对象按流水号配置处理。完整创建、更新、恢复手动输入及子表示例见 [字段取值与完整配置](references/field-values.md)。校验和节点表达式按各自保存结构配置,不直接套用字段默认值的三个属性。
+
+ ## 公式语法速查
+
+ 以下规则用于原生公式原文;页面 JavaScript、数据集表达式和已编译的流程条件,按其实际输入格式处理。
+
+ | 规则 | 正确写法或说明 |
+ | --- | --- |
+ | 字段用真实 ID,并包在 `#{}` 中 | `ROUND(#{numberField_price} * #{numberField_qty}, 2)`;不要直接写裸 ID 或显示名称 |
+ | 普通子表字段使用子字段自身 ID | `SUM(#{numberField_lineAmount})`;当前行计算与整列汇总由绑定位置决定。组件子属性保留设计器提供的路径 |
+ | 使用半角括号、逗号和引号 | `IF(GT(#{numberField_total}, 100), "高", "低")` |
+ | 函数名保持原有大小写 | `ROUND`、`UserBuilder`、`DeptBuilder`;按函数清单填写 |
+ | 文本加引号,数字直接写 | `"通过"`、`100`;写进 JSON 字符串时,内部双引号写为 `\"` |
+ | 加减乘除使用 `+ - * /` | 先算的部分加括号;除法先处理零和空值,完整示例见下表 |
+ | 比较和逻辑使用函数 | `GT/GE/LT/LE/EQ/NE`、`AND/OR/NOT`;例如 `AND(GE(#{numberField_score}, 60), NE(#{textField_status}, "作废"))` |
+ | 嵌套时写全每个函数的参数 | `IF(条件, 满足时的值, 不满足时的值)`;内外层括号配对,两个返回分支都匹配目标类型 |
+ | 区分数字、文本、日期和数组 | `VALUE("12.5")` 得到数字;`TEXT` 用于格式化文本;日期对象填日期字段用 `TIMESTAMP`;成员值保留成员结构 |
+ | 避免循环依赖 | 允许“单价、数量 → 行金额 → 合计”,不要让合计反过来依赖自己;显示状态、计算和是否提交分别配置 |
+
+ ## 按用途找函数
+
+ | 要做什么 | 常用函数名 |
+ | --- | --- |
+ | 数值计算 | `SUM`、`AVERAGE`、`MAX`、`MIN`、`ROUND`、`INT`、`ABS`、`MOD`、`PRODUCT`、`SUMPRODUCT`、`SQRT`、`POWER` |
+ | 判断与校验 | `IF`、`AND`、`OR`、`NOT`、`EQ`、`NE`、`GT`、`GE`、`LT`、`LE`、`ISEMPTY`、`EXACT`、`ARRAYREPEATED` |
+ | 文本处理 | `CONCATENATE`、`LEFT`、`RIGHT`、`MID`、`LEN`、`TRIM`、`UPPER`、`LOWER`、`REPLACE`、`TEXT`、`VALUE`、`UUID`、`RMBFORMAT`、`SPLIT`、`ARRAYGET` |
+ | 日期与时间 | `TODAY`、`NOW`、`YEAR`、`MONTH`、`DAY`、`DAYS`、`DATEDELTA`、`NETWORKDAYS`、`DATE`、`TIMESTAMP`、`CASCADEDATEINTERVAL`、`TIMECOMPARE` |
+ | 人员与部门 | `USER`、`GETUSERNAME`、`LOGINUSERWORKNO`、`DEPTNAME`、`DIRECTOR`、`UserBuilder`、`DeptBuilder`、`DirectorBuilder` |
+ | 多选集合 | `UNIONSET`、`INTERSECTIONSET`、`DIFFERENCESET`、`SUBSET` |
+ | 查已有记录或执行数据动作 | `EXIST`、`COUNT`、`INSERT`、`UPDATE`、`DELETE` 等;先确认表单上下文、预处理和触发时机 |
+
+ 参数写法、返回值、完整分类名单和例子见 [公式函数速查](../../references/formula-functions.md)。查询当前组织的函数签名后,再核对目标配置实际提供的函数清单;索引中的函数不保证在每个输入位置都可用。
+
## 写配置前先处理这些易错点
按当前任务读取下表相关项,再写字段、规则或节点配置。相同用法在不同设计器中共用这些步骤。
| 正在做什么 | 先做这一步 |
| --- | --- |
| 修改已有公式 | 读取目标位置的完整配置,保留规则 ID、其他公式、提示、触发时机和无关属性;`formula inspect` 只覆盖字段配置 |
| 引用同表新字段 | 创建基础字段后复用返回的真实字段映射,再添加计算;已有字段直接读取映射,无需重新创建 |
| 获取数据时设置过滤条件 | 左边选目标表字段;右边明确选“值、字段、公式”:固定门槛用值,上游金额用字段,上游金额乘二用公式 |
| 引用子表字段 | 使用子字段自身的 ID,并明确取当前行还是整列;主表汇总和子表同行计算分别配置 |
| 保存节点公式 | 同时保留执行文本、编辑器原文和显示文字;上游节点及输出字段应真实存在,才能再次打开编辑 |
| 配置校验 | 先确认返回值含义:原生阻断公式为真时阻断;JS 自定义校验返回真时通过。提示文字与判断条件一起保存 |
| 处理空值、零、日期或成员 | 保留原始类型和结构;分别考虑空值与零、日期单位、单个成员与成员数组,避免用统一转文本或默认值替代 |
| 给日期字段自动填今天 | 使用 `TIMESTAMP(TODAY())`,把日期对象转换为字段需要的毫秒时间戳;再核对页面显示和提交值 |
| 选择函数 | 查询参数并核对目标配置提供的菜单;`EXIST` 查已有记录,`COUNT` 统计表单提交数,各按真实用途选择 |
| 本地通过或保存成功 | 分别记录检查、保存回读和实际运行结果;接口探查未覆盖的页面联动、提交校验、节点上下文及聚合保持待验证 |
+ | 试算字段公式 | 使用 `formula test APP FORM --field 目标字段ID --data-file data.json --expect JSON`;直接读取已存公式,按依赖顺序重算,并核对转换前后的值 |
+ | 公式依赖其他计算字段 | 提供最初的输入数据;试算会先计算依赖字段,再计算结果。子表数据按“表 ID → 多行对象”提供,每行使用子字段 ID |
用户已要求暂停测试时,完成配置说明和本地修改,并注明实际运行尚未验证;保留后续验收步骤即可。
## 共用步骤
1. 读取已有配置,确认真实字段 ID、输入类型、目标值类型,以及什么时候执行。修改时保留原公式和其他设置。
2. 选择函数并写公式,先用一句话说明结果。共用例子见 [常用函数](../../references/formula-functions.md)。
3. 按目标输入的格式保存。字段公式保存字符串;节点公式通常还保存编辑器内容;校验还需要提示和阻断设置。
4. 回读配置,核对字段、公式和原有属性。用户要求验证时,再用实际入口检查计算、提交或节点执行结果。
```bash
openyida get-schema APP_XXX FORM_XXX --field-map-json
openyida formula inspect APP_XXX FORM_XXX --json
openyida formula functions APP_XXX --name ROUND --json
openyida formula contracts --json
```
`inspect` 查看字段默认值公式和字段校验;完整表单校验、流程全局规则、节点和报表配置从各自的完整设计数据读取。`contracts` 列出 CLI 识别的保存方式与检查范围,不访问应用。
## 复杂配置先选一个完整示例
需要嵌套时,先选下表对应示例,保留其外层结构,再替换真实字段和业务常量。每例都说明配置位置、替换项和输入对应的预期结果;只读取需要的小节。
| 需要配置什么 | 直接读取 |
| --- | --- |
| 三档判断、多个 IF | [嵌套 IF 与完整字段变更](references/nested-examples.md#三档判断嵌套-if) |
| A 且(B 或 C)、取反 | [AND/OR/NOT 嵌套](references/nested-examples.md#多层条件andornot) |
| 数量为零时避免除零 | [非零除数与完整字段变更](references/nested-examples.md#数量为零让除数始终非零) |
| 子表同行计算后主表汇总 | [两个目标字段的完整变更](references/field-values.md#子表同行计算与主表汇总的完整变更) |
| 同时使用字段、公式、固定值过滤 | [完整取数 spec](references/node-examples.md#按编号字段嵌套公式和固定状态取数) |
| 分支命中后再分支 | [两层 route 与兜底](references/node-examples.md#嵌套分支先决定是否复核再决定级别) |
| 复杂提交校验 | [同一规则的原生公式与 JS 配置](references/nested-examples.md#同一提交规则原生阻断公式与-js-通过条件) |
## 常用写法
下面用字段默认值公式举例,字段 ID 换成读取到的真实值:
| 目的 | 公式 |
| --- | --- |
| 单价乘数量,保留两位小数 | `ROUND(#{numberField_price} * #{numberField_qty}, 2)` |
| 金额超过 100 显示“高” | `IF(GT(#{numberField_total}, 100), "高", "低")` |
| 汇总子表金额列 | `SUM(#{numberField_lineAmount})` |
| 成员字段填当前登录人 | `USER()` |
| 拼接姓名和编号 | `CONCATENATE(#{textField_name}, "-", #{textField_code})` |
- 使用半角括号、逗号和引号。函数名保持查询结果中的大小写,例如 `ROUND`、`UserBuilder`。原生公式常用 `GT/GE/LT/LE/EQ` 比较;JavaScript 和由流程条件生成的表达式使用各自的运算规则。
-
- 字段默认值引用写成 `#{字段ID}`。子表普通字段也用子字段自身的 ID;组件开放的子属性可能使用 `#{组件字段ID.属性名}`。节点和数据集引用按各自格式填写,不从显示名称猜 ID。
-
## 检查结果怎么看
```bash
openyida formula check formula.txt --contract field-value --schema schema.json --target-type NumberField --json
```
本地检查帮助找出写法、参数和部分类型问题。`formula functions` 查询函数签名;实际可选函数还取决于目标配置传入的函数清单和组织开关。
- `formula test` 调用通用表达式接口,不保存配置;它没有重现页面初始化、子表同行取值、校验预处理、节点上下文或图表聚合。交付时分别说明检查、回读和实际执行到了哪一步。详细命令见 `yida-formula-evaluate`。
+ `formula test --field` 使用平台原生字段计算接口,保留组件类型、子表行和公式依赖,并检查数值、日期及成员的部分回填转换。复杂试算、样例文件和返回值说明见 [字段绑定与样例验证](references/runtime-examples.md)。多组输入可保存成 `--cases` 文件,每组都给出期望结果。
+
+ 不带 `--field` 的 `formula test` 继续探查通用表达式接口。字段试算也需要补页面显示、组件精度和提交检查;原生校验、节点及图表计算仍从各自实际入口验收。详细检查命令见 `yida-formula-evaluate`。
本技能不依赖跨会话 memory。字段映射、原配置和变更文件保存在当前任务目录中。