理解 Enhancer 变量体系
Enhancer 平台之所以能快速地满足各类信息系统的开发,其中一个重要的原因是,它有一套完备的变量体系,方便开发者直观地使用。本文来讨论下平台的变量体系。
1. 常规业务系统增删改查中的数据流
一个常规的业务系统,最终都会由后台做 IO 来访问或者持久化数据。在具体的关系数据库中,这种 IO 操作体现在将各种来源的数据汇集成 SQL 增删改查操作,如上图。 于是我们可以设计一套规范的数据来源和数据组织方式,让开发者按照该预定机制,直观快速地取用到各类数据,完成相关业务逻辑的开发。Enhancer 的变量体系就是这样一种方便开发者的机制。
2. Enhancer 的变量命名规则
服务端变量: 单词[.单词],如:USER_ID,SYS.PATH。
客户端变量: 数字-单词[.单词],如:1-USERNAME,12-USER_NAME,11-COMPONENTS.AMOUNT
注 1:以上 `[]` 表示可重复 0 次和多次的子结构。
注 2:【单词】只能包含字母、下划线、数字,不能包含中划线 - !
正则表达式为:
服务端变量: /^\w+(.\w+)*$/
客户端变量: /^\d+-\w+(.\w+)*$/
推荐在书写时全部采用大写。
3. Enhancer 的变量分类
3.1 服务端变量
服务端变量指变量值的存放和使用只能在服务端的数据变量。又分为:
【系统变量】
指从启动到运行由自身产生,表现系统状态的一些变量,比如 PATH
(启动路径), CURR_TIME
(当前系统时间),CURR_DATE
(当前系统日期),CURR_MONTH
(当前月份),LAST_YEAR
(去年),NEXT_MONTH
(下个月)等。
命名规则 单词[.单词]
【用户变量】
指从用户登录到退出,属于该用户的数据变量,如 USER_ID
(用户 ID),USER_NAME
(用户名), ROLES
(角色), GENDER
(性别), DEPARTMENT
(所属部门) 等。
命名规则 单词[.单词]
3.2 客户端变量
客户端变量指客户端产生的数据变量,有以下几类
【窗口变量】以窗口被编号开头命名,窗口编号一定大于 10
通过用户的操作产生的表现当前窗口各种状态的数据变量,不同窗口包含的组件类型(查询器,表单,树...)不同,其组织变量的方式也不同,比如在查询组件窗口中用户选择了某数据行,此时该窗口可能有这些变量:11-STU_NO
(11 号窗口当前选中行的学号列值), 11-SELECTED_ROWS_COUNT
(11 号窗口选中的行数),再比如在树组件中用户选择某个节点:12-LAST_SELECTED_NODE_VALUE
(12 号窗口当前选中节点的值),- 12-LAST_CHECKED_LEVEL
(当前选中节2.
点的层级) 等等。
命名规则 窗口编号-单词[.单词]
【系统初始变量】以 0 开头命名
由服务器端注入到前端的可用变量,如 0-CURR_YEAR
(当前系统年份如:2018), 0-CURR_DATE
(当前系统日期如:16),0-CURR_MONTH
(当前系统月份如:8)。
命名规则 0-单词[.单词]
【用户初始变量】以 1 开头命名
由服务器端注入给前端使用的关于当前用户的变量,如1-USER_ID
(当前用户 ID),1-USER_NAME
(当前用户名),1-ROLES
(当前用户的全部角色)。
命名规则 1-单词[.单词]
【用户行为变量】以 2 开头命名
系统记录用户操作行为的数据变量,如下表:
变量名 | 例 | 含义 |
---|---|---|
2-LAST_CLICKED_BTN_ID | ButtonClick1 | 上一次点击的按钮 ID 编号 |
2-CURR_PAGE_ID | 159 | 当前页面编号 |
2-PREV_PAGE_ID | 155 | 上次浏览的页面编号 |
2-LAST_EVENT_ID | 159-w12-ButtonClick1 | 上一次点击按钮ID |
2-LAST_EVENT_SRC_ID | 159-w12 | 上一次触发事件所属窗口 ID |
2-LAST_EVENT_SRC_NO | 12 | 上一次触发事件所属窗口编号 |
2-LAST_PROCEDURE_RESULT | {success: true, data: {...}, messge: "执行成功"} | 上一次提交后台过程返回的结果 |
命名规则 2-单词[.单词]
【当前页面 url 查询参数变量】以 3 开头名命
如3-PARAM1
表示 url?param1=val1¶ms2=val2#102 查询参数 param1 的值 'val1'。
命名规则 3-单词[.单词]
【上一页面内的窗口变量】以 8 开头命名
如8-12_STU_NO
表示上一页面 12 号窗口的学生编号。
命名规则 8-窗口编号_单词[.单词]
【当前页面由外部传递的数据】以 9 开头命名
如9-ARTICLE_ID
表示从外部传递给当前页面的文章 ID 号。使用脚本 Enhancer.openPage(页面编号, 数据) 可以在打开页面时传递数据。例如:Enhancer.openPage(123, {article_id, '9187324'})。那么此时 变量@9-ARTICLE_ID@的值是 9187324。
命名规则 9-单词[.单词]
4 变量的用法
4.1 用在 SQL 中 (使用变量引用符号: @变量@
)
- 在查询语句中
SELECT * FROM TAB_A a, TAB_B b
WHERE a.id = b.id AND a.code = @12-CODE@ AND b.user_id = @USER_ID@
- 在非查询语句中(事件触发执行后台 SQL)
UPDATE accounting_document
SET accounting_date = @14-ACCOUNTING_DATE@,
attachment_num = @14-ATTACHMENT_NUM@
WHERE id = @11-ID@;
- 用作 SQL 中的表名或字段名,需使用$变量$强化转义规则,防止注入攻击
SELECT * FROM $12-TABLE_YEAR$
WHERE field1 = @15-VARNAME@ AND $12-FIELD_NAME$ = @12-USER_INPUT@
4.2 用在组件数据绑定中
最常见的是给表单的某个输入域绑定其他窗口变量。
4.3 用在条件表达式中
在配置事件动作执行条件时(双击流程图中的动作线),可书写变量以精确控制动作是否执行,如:
@11-GENDER@ = '男' AND @11-CHECKED@ = true
4.4 用在前端脚本中
如在事件设置中配置执行-事件触发时脚本
来控制后续动作是否继续执行:
var gender = @11-gender@;
var cnt = @12-selected_rows_count@
if (cnt > 5 || gender == '女') {
alert('仅限女,且数量不超过 5 个')
return false
}
4.5 用在后台过程执行中【选修】
如在事件设置中配置 执行-服务器过程
--> JavaScript 过程
var sql = `UPDATE student SET name = ?, birthday = ?, birth_place = ?, gender = ?, phone = ?,
nation = ?, entry_year = ?, ssn = ?, family_address = ?, political_status = ?, school_year_length = ?
WHERE student_no = ?`;
// 直接 @变量@ 从页面取用本次过程执行需要的数据。
var params = [@12-NAME@, @12-BIRTHDAY@, @12-BIRTH_PLACE@, @12-GENDER@, @12-PHONE@, @12-NATION@,
@12-ENTRY_YEAR@, @12-SSN@, @12-FAMILY_ADDRESS@, @12-POLITICAL_STATUS@, @12-SCHOOL_YEAR_LENGTH@,
@12-STUDENT_NO@];
// Enhancer 是全局对象,直接使用。
var databaseService = Enhancer.getDatabaseService();
databaseService.execute(sql, params, function(err, result) {
if (err) {
console.log(err);
// 不论结果执行成功失败,需要调用 done 方法表示本次过程结束。
// done 方法的第一个参数传递系统级 err,第二个参数传递常规结
// 果对象(包含 success 和 message 字段)。
done(null, {
success: false,
message: '操作失败操作失败。' + err.message
});
return;
}
done(null, {
success: true,
message: '修改成功!'
});
});
5 给用户注入其他初始变量
在默认情况下,系统表示用户状态的可用变量只有 USER_NAME
, USER_ID
和 ROLES
。有时候我们需要用户其他相关信息,比如性别
,生日
,职位
,所属部门
,账号状态
等等,希望他们随着用户的登录,由系统保存为可用的用户变量,方便开发时使用,则可以通过以下方式为用户添加初始变量:
使用绑定用户表方式登录时
此时,只需给该登录用户表添加需要的任何字段,系统会在用户登录成功时,将该用户记录其他字段全部添加为初始变量(PASSW0RD 除外),开发时可随意引用。例如用户表有字段名叫
department
, 那么在服务端使用@department@
或者在客户端使用@1-DEPARTMENT@
便可引用到该变量值。此外,还可以在【登录校验后函数】中查询当前用户相关的其他数据,然后调用 user.setVariables 方法,给当前用户赋予其他初始变量。也可以根据用户表的相关状态字段控制登录,如:
function (enhancer, user, done) { // ... if (user.getVariable('STATUS') !== 1) { done(null, '您的账号已被禁用,请联系管理员。'); return } // ... }
使用自定义校验登录过程时 在自定义过程校验完毕之后,可以调用
user.setVariables
方法来给该用户设置初始变量,如:function (enhancer, user, done) { // 完成 用户校验之后,可能再次异步请求获得了一些 用户的数据 // 设置用户初始变量 user.setVariables({ field1: value1, field2: value2 ... }); done(null, true); }
之后便可以在服务端或者客户端使用变量 @FIELD1@, @1-FILED1@, @FIELD2@, @1-FILED2@ ...
【说明】在线上开发调试阶段,由于没有一个真实的系统启动过程和用户登录过程,所以相关变量需要手工在预览界面顶部工具栏进行【变量设置】。开发者可以任意调整其值,来做不同场景的测试。项目发布之后,这些变量会按照预定机制赋予真实值。
正确把握了 Enhancer 变量的概念,对于业务的拆解设计会起到事半功倍的效果。