表达式
应用场景
在搭建系统的过程,你可能会遇到以下的场景:
计算属性: 一个实体的属性是由另外的一个或多个值计算而来,比如户籍所在省份由身份证的省份码计算而来;又如用户的年龄是当前时间减去出生日期得到的。
验证或校验规则: 很多情况下对用户的输入的校验是基于通用的格式校验的,比如手机号格式,邮箱格式等。但有些情况下,校验规则可能比较复杂,比如用户输入的新密码和确认的新密码相同且不能等于旧密码,这个就很难用一个格式验证去实现,需要我们设置校验规则。
数据转换: 有些情况下,我们需要对实体信息进行转换映射,如计算人员得分时,我们需要将考核项的某些字段转换到得分项上。
条件判断: 条件判断出现的场景很多,比如权限控制,某个用户是否有某个操作权限,某个订单是否满足某个条件等;又比如计算水费时,根据不同的楼层条件产生不同的计算方式等。
表达式的场景不仅局限于上述的几种,了解平台的表达式使用方式,可以极大的提升配置的深度和效率。
常用术语
表达式类型
- 赋值表达式:将一个值赋给一个变量,如
a = 10
- 判断表达式:返回条件判断的结果,如
if a > 0
- 筛选表达式:用于范围(如权限)限制,无法添加中间变量和复杂算术计算
- 显示规则表达式:用户按判断条件显示不同样式(颜色、字体、背景颜色、图标等)
配置相关
- 变量名:表达式的步骤名,作为后续中间变量名使用,最后步骤的变量名为
最终值
,且不可更改。 - 是否为决策计算:是否切换为分支决策计算的模式
例
简单模式下,c=a+b
,在决策模式下,可以配置 如果xx条件成立则 c=a+b,否则 c=a-b
。
- 空值处理:当变量值为空时,如何处理。
说明
以最终值=c+1,c为空时为例
不处理
: 继续计算,不特殊处理,则结果为 null1
中断计算
: 判断为 null时,不继续后续操作,此时最终值为 undefined
默认值
: 若变量值为空,则使用默认值,假设设置了默认值为 1,则最终值为 1+1=2
- 是否浮点数: 当检测到表达式的返回值是
数字类型
时,需要确认是否为浮点数
,以辅助程序处理。
函数相关
- 链式运算:
链式运算
是平台表达式的一个隐含概念,它从一个值出发,经过一系列的计算,返回一个最终值。
例子
以计算商品总价为例:总价为:(商品单价*数量)+运费-优惠券金额,链式运算可以表示为:
总价 = 商品单价 * 数量 + 运费 - 优惠券金额
先计算商品单价 * 数量,再加上运费,最后减去优惠券金额,就像一条链条一样,如下图所示。
- 取值类型:
常量
、变量
、序列号
、过程变量
说明
常量:指在表达式中固定不变的值,如 10、"hello"、true 等。
变量:指在运行时才能够确定的值,如商品的单价、商品的数量。
序列号:指公共域中配置的序列号规则。
过程变量:当表达式添加步骤时,表示前序步骤计算的结果。
- 参数:表示函数的输入值,可以是常量、变量、序列号、过程变量。如
a + b
,其中b
就是加这个函数的参数。 - 配置:辅助函数计算的配置项,比如
当前日期 加上 30 日
,那么30
是函数日期加
的参数,日
就是配置,表示计算的单位。
分步计算
当我们在计算一些复杂的表达式时,可以将其分成多个步骤,每个步骤可以包含多个表达式。
后序步骤可以依赖前序步骤的计算结果。
我们用这个例子来说明: 我们希望通过身份证号码计算用户的年龄,就可以使用分步骤的方式。
点击 添加
,向前添加一个步骤:
第一步:通过用户的身份证号码获取出生年份。
第二步:用当前日期的年份减去出生年份,得到用户的年龄。
算子(函数)概览
以下列举了平台目前支持的常用算子(函数):
文本(字符串)函数
函数名称 | 说明 | 参数 | 配置项 | 返回值类型 | 示例 |
---|---|---|---|---|---|
长度 | 返回文本的长度 | 数字 | 瑞信软件.长度 => 4 | ||
截取 | 从文本中截取指定长度的字符 | 开始位置、截取长度 | 字符串 | 瑞信软件.截取(0, 2) =>瑞信 | |
拼接 | 将多个文本拼接成一个文本 | 需要拼接的文本 | 文本 | 瑞信软件.拼接("公司") => 瑞信软件公司 | |
转日期 | 将日期文本按照配置的格式转成日期类型 | 字符格式 | 日期 | 20201212.转日期("yyyyMMdd") => 日期类型2020-12-12 | |
转拼音 | 文本转拼音 | 字符串 | 瑞信软件.拼音 => =ruixin | ||
子串起始位置 | 返回子串在文本中的起始位置 如果没有找到子串,返回 -1 | 文本子串 | 数字 | 瑞信软件.子串起始位置("信") => 1 | |
转小写 | 将文本转成小写 | 字符串 | RUixin.转小写 => ruixin | ||
转大写 | 将文本转成大写 | 字符串 | RUixin.转小写 => RUIXIN | ||
去除空格 | 去除文本中的空格 | 字符串 | 瑞信 .转小写 => 瑞信 | ||
替换字符 | 将文本中的指定字符替换成另外字符 | 源字符 、目标字符 | 字符串 | 瑞信软件.替换字符("瑞", "R") => R信软件 | |
分割字符 | 将文本按照指定字符分割成集合 | 集合 | ruixin.分割字符("i") => [ru,x,n] | ||
转整数 | 将文本转成整数 | 数字 | '10'.转整数 => 10 | ||
转小数 | 将文本转成小数 | 数字 | '10.01'.转小数 => 10.01 |
文本比较函数
比较函数的返回值都为
是否类型(布尔值)
。
函数名称 | 说明 | 示例 |
---|---|---|
等于 | 判断两个文本 是否相等 | 瑞信软件.等于("瑞信软件") => 是 |
不等于 | 判断两个文本 是否不相等 | 瑞信软件.不等于("瑞信") => 是 |
匹配正则 | 判断文本是否 匹配正则表达式 | 瑞信软件.匹配正则("^瑞信.*$") => 是 |
不匹配正则 | 判断文本是否 不匹配正则表达式 | 瑞信软件.不匹配正则("^瑞信.*$") => 否 |
包含 | 判断文本 是否包含子串 | 瑞信软件.包含("瑞") => 是 |
不包含 | 判断文本 是否不包含子串 | 瑞信软件.不包含("瑞") => 否 |
以..开头 | 判断文本是否 以指定字符开头 | 瑞信软件.以"瑞"开头 => 是 |
以..结尾 | 判断文本是否 以指定字符结尾 | |
为空 | 判断文本 是否为空 | "".为空 => 是 |
不为空 | 判断文本 是否不为空 | "10".不为空 => 是 |
数字函数
函数名称 | 说明 | 参数 | 配置项 | 返回值类型 | 示例 |
---|---|---|---|---|---|
加 | 两个数相加 | 加数 | 数字 | 1加1 => 2 | |
减 | 两个数相减 | 减数 | 数字 | 1减1 => 0 | |
乘 | 两个数相乘 | 乘数 | 数字 | 1乘1 => 1 | |
除 | 两个数相除 | 除数 | 数字 | 4除2 => 2 | |
取余 | 两个数取余 | 除数 | 数字 | 4取余3 => 1 | |
转字符串 | 将数字转成字符串 | 字符串 | 10.转字符串 => 10 | ||
变更精度 | 数字的精度 | 精度 | 数字 | 10.234.变更精度(2) => 10.23 |
数字比较函数
比较函数的返回值都为
是否类型(布尔值)
。
函数名称 | 说明 | 示例 |
---|---|---|
等于 | 判断两个数字是否相等 | 10.等于(10) => 是 |
不等于 | 判断两个数字是否不相等 | 10.不等于(11) => 是 |
大于 | 判断一个数字是否大于另一个数字 | 10.大于(9) => 是 |
大于等于 | 判断一个数字是否大于等于另一个数字 | 10.大于等于(10) => 是 |
小于 | 判断一个数字是否小于另一个数字 | 10.小于(11) => 是 |
小于等于 | 判断一个数字是否小于等于另一个数字 | 10.小于等于(10) => 是 |
为空 | 判断数字是否为空 | 0.为空 => 是 |
不为空 | 判断数字是否不为空 | 10.不为空 => 是 |
日期函数
函数名称 | 说明 | 参数 | 配置项 | 返回值类型 | 示例 |
---|---|---|---|---|---|
转字符串 | 将日期转成字符串 | 日期格式 | 字符串 | 日期类型2020-12-12.转字符串("yyyy-MM-dd") => 2020-12-12 | |
日期加 | 日期加上指定时间 | 数量、单位 | 日期 | 日期类型2020-12-12.日期加(1, "天") => 日期类型2020-12-13 | |
日期减 | 日期减去指定时间 | 数量、单位 | 日期 | 日期类型2020-12-12.日期减(1, "天") => 日期类型2020-12-11 | |
日期差 | 两个日期的差值 | 另外一个日期 | 单位 | 数字 | 日期类型2020-12-12减去日期类型2020-12-11 => 1 |
支持的日期格式的标识符:
标识 | 示例 | 描述 |
---|---|---|
YY | 18 | 年,两位数 |
YYYY | 2018 | 年,四位数 |
M | 1-12 | 月,从 1 开始 |
MM | 01-12 | 月,两位数 |
MMM | Jan-Dec | 月,英文缩写名 |
MMMM | January-December | 月,英文全名 |
D | 1-31 | 日,从 1 开始 |
DD | 01-31 | 日,两位数 |
d | 0-6 | 一周中的一天,星期天是 0 |
dd | Su-Sa | 星期几,英文缩写名 |
ddd | Sun-Sat | 星期几,英文全名 |
dddd | Sunday-Saturday | 星期几,英文全名 |
H | 0-23 | 小时 |
HH | 0-23 | 小时,24 小时制 |
h | 1-12 | 小时,12 小时制 |
hh | 01-12 | 小时,12 小时制,两位数 |
m | 0-59 | 分钟 |
mm | 00-59 | 分钟,两位数 |
s | 0-59 | 秒 |
ss | 00-59 | 秒,两位数 |
S | 0-9 | 毫秒 |
SS | 00-99 | 毫秒,两位数 |
SSS | 000-999 | 毫秒,三位数 |
日期比较函数
比较函数的返回值都为
是否类型(布尔值)
。
函数名称 | 说明 | 示例 |
---|---|---|
等于 | 判断两个日期是否相等 | 日期类型2020-12-12.等于(日期类型2020-12-12) => 是 |
不等于 | 判断两个日期是否不相等 | 日期类型2020-12-12.不等于(日期类型2020-12-11) => 是 |
晚于 | 判断一个日期是否晚于另一个日期 | 日期类型2020-12-12.晚于(日期类型2020-12-11) => 是 |
晚于等于 | 判断一个日期是否晚于等于另一个日期 | 日期类型2020-12-12.晚于等于(日期类型2020-12-12) => 是 |
早于 | 判断一个日期是否早于另一个日期 | 日期类型2020-12-12.早于(日期类型2020-12-13) => 是 |
早于等于 | 判断一个日期是否早于等于另一个日期 | 日期类型2020-12-12.早于等于(日期类型2020-12-12) => 是 |
为空 | 判断日期是否为空 | 空日期.为空 => 是 |
不为空 | 判断日期是否不为空 | 日期类型2020-12-12.不为空 => 是 |
字典函数
假设有如下性别字典: label
表示展示值,value
表示编码存储值。
[
{label:"男",value:1},
{label:"女",value:2}
]
函数名称 | 说明 | 返回值类型 | 示例 |
---|---|---|---|
获取标签 | 获取字典标签 | 字符串 | 性别字典.男.获取标签 => 男 |
获取编码 | 获取字典编码 | 字符串 | 性别字典.男.获取值 => 1 |
字典比较函数 字典比较主要是字典项的标签文本或编码文本同其他文本的比较,可以参考文本的比较函数。
集合函数
我们以以下集合为例说明集合的常用函数:
集合 1:
姓名 | 性别 | 成绩 | 年龄 |
---|---|---|---|
张三 | 男 | 90 | 20 |
李四 | 男 | 80 | 21 |
王五 | 女 | 70 | 22 |
集合 2:
姓名 | 性别 | 成绩 | 年龄 |
---|---|---|---|
陈六 | 女 | 60 | 18 |
王五 | 女 | 70 | 22 |
函数名称 | 说明 | 参数 | 配置项 | 返回值类型 | 示例 |
---|---|---|---|---|---|
直接计数 | 直接计数 | 数字 | 集合1.直接计数 => 3 | ||
条件计数 | 按条件计数 | 过滤条件(表达式) | 数字 | 集合1.条件计数(性别="男") => 2 | |
平均值 | 求平均值 | 过滤条件(表达式,可选) 、 选择属性 | 数字 | 集合1.平均值(条件无, 成绩) => 80 | |
求和 | 求和 | 过滤条件(表达式,可选) 、 选择属性 | 数字 | 集合1.求和(条件无, 成绩) => 240 | |
最大值 | 求最大值 | 判断属性 、 选择属性 | 数字 | 集合1.最大值(年龄, 成绩) => 70 意思是年龄最大的学生的成绩是 70 | |
最小值 | 求最小值 | 判断属性 、 选择属性 | 数字 | 集合1.最小值(年龄, 成绩) => 90 意思是年龄最小的学生的成绩是 90 | |
获取首项 | 返回集合的第一项 | 对象 | 集合1.获取首项 => 学生张三 | ||
获取末项 | 返回集合的最后一项 | 对象 | 集合1.获取末项 => 学生王五 | ||
求交集 | 两个集合重叠的部分 | 集合 | 集合1.连接(集合2) => [学生王五] | ||
求并集 | 两个集合合并 | 集合2 | 集合 | 集合1.求并集(集合2) => [学生张三,学生李四, 学生王五, 学生陈六] | |
求差集 | 第一个集合中不在第二个集合中的部分 | 集合2 | 集合 | 集合1.求差集(集合2) => [学生张三,学生李四] |
集合比较函数
比较函数的返回值都为
是否类型(布尔值)
。
函数名称 | 说明 | 被比较值 类型 | 配置 | 示例 |
---|---|---|---|---|
为空 | 判断集合是否为空 | 无 | 集合1.为空 => 否 | |
不为空 | 判断集合是否不为空 | 无 | 集合1.不为空 => 是 | |
都满足条件 | 判断集合中所有项 是否都满足条件 | 无 | 条件表达式 | 集合1.都满足条件(成绩>80) => 否 |
有任一满足条件 | 判断集合中是否 存在满足条件的项 | 无 | 条件表达式 | 集合1.有任一满足条件(成绩>80) => 是 |
有交集 | 判断两个集合是否有交集 | 集合 | 集合1.有交集(集合2) => 是 | |
无交集 | 判断两个集合是否无交集 | 集合 | 集合1.无交集(集合2) => 否 | |
属于子集 | 判断集合是否属于另一个集合 | 集合 | 集合1.属于子集(集合2) => 否 | |
不属于子集 | 判断集合是否不属于另一个集合 | 集合 | 集合1.不属于子集(集合2) => 是 | |
等于集合 | 判断两个集合是否相等 (集合中每一项都相等) | 集合 | 集合1.等于集合(集合2) => 否 | |
不等于集合 | 判断两个集合是否不相等 (集合中不是每一项都相等) | 集合 | 集合1.不等于集合(集合2) => 是 | |
包含 | 判断集合是否包含指定项 | 无 | 对像 | 集合1.包含(学生王五) => 是 |
不包含 | 判断集合是否不包含指定项 | 无 | 对像 | 集合1.不包含(学生陈六) => 是 |
对像函数
目前平台主要实现对像类型的比较函数:
函数名称 | 说明 | 被比较值 类型 | 配置 | 示例 |
---|---|---|---|---|
等于 | 判断两个对像是否相等 | 对像 | 学生张三.等于(学生王五) => 否 | |
不等于 | 判断两个对像是否不相等 | 对像 | 学生张三.不等于(学生王五) => 是 | |
属于 | 判断对像是否属于指定集合 | 对像 | 集合 | 学生张三.属于(学生集合) => 是 |
不属于 | 判断对像是否不属于指定集合 | 对像 | 集合 | 学生张三.不属于(学生集合) => 否 |
为空 | 判断对像是否为空 | 对像 | 空对像.为空 => 是 | |
不为空 | 判断对像是否不为空 | 对像 | 学生张三.不为空 => 是 |
表达式类型
赋值表达式
赋值表达式用于给变量赋值,如实体的属性为计算属性的,给流程变量赋值等。
举例1: 在配置实体的计算属性时,学生的全名: 姓 拼接
名
举例2: 我们还可以综合使用 决策计算
和 分步计算
来根据客户的身份证号码计算客户的性别:
身份证的第 17 位表示性别,其中单数位男性,双数为女性。
第一步: 我们先计算出身份证第 17 除以 2 的余数。
第二步: 根据余数,采用 决策计算
来判断客户的性别,如果余数为 0,则性别为女(双数),否则为男(单数)。
条件表达式
在很多时候,我们的计算不是简单的赋值运算,而是需要根据条件来进行不同的计算。条件表达式用于根据条件来进行不同的计算。
在平台上有很多用到条件表达式的地方,比如 计算属性
、流程变量赋值
等赋值计算时的决策计算;显示规则
等。
例子: 我们以 显示规则
为例,我们希望当性别为 男性
时,字体颜色为蓝色,当性别为 女性
时,字体颜色为红色。
下图是条件表达式的具体配置:
同级条件和子级条件
很多时候我们是用的判断条件是复杂,含有嵌套的.
比如:学生的性别为男 并且
(学生年龄大于 18 或者
学生预算大于 10000),我们将这个学生标记为红色
(意味着可能是电子产品的潜在消费者),否则不做特殊标记。
我们可以点击 +
号来增加 同级条件
或者 子级条件
。
子级条件类似于数学运算的小括号(),会先计算小括号里面的结果,再计算外层。
我们按照需要添加条件如下,我们还可以根据需要切换逻辑操作符: 且
还是 或
。且表示条件都成立的时候才会成立,或表示只要有一个条件成立就成立。
筛选表达式
筛选表达式常用于从当前实体出发,根据配置的条件,筛选出符合条件的实体/结构体。比如在 查询条件
例子: 我们在查询操作中,希望设置查询规则:只查询工程名称不为空的工程。
下图是筛选表达式的具体配置:
本质上筛选表达式也是条件表达式的一种,但是筛选表达式只能跟当前实体/结构体(目标)出发,而不能自由选择。