理解 Enhancer 变量体系

Enhancer 平台之所以能快速地满足各类信息系统的开发,其中一个重要的原因是,它有一套完备的变量体系,方便开发者直观地使用。本文来讨论下平台的变量体系。

1. 常规业务系统增删改查中的数据流

dataflow

一个常规的业务系统,最终都会由后台做 IO 来访问或者持久化数据。在具体的关系数据库中,这种 IO 操作体现在将各种来源的数据汇集成 SQL 增删改查操作,如上图。 于是我们可以设计一套规范的数据来源和数据组织方式,让开发者按照该预定机制,直观快速地取用到各类数据,完成相关业务逻辑的开发。Enhancer 的变量体系就是这样一种方便开发者的机制。

2. Enhancer 的变量命名规则

服务端变量: 单词[.单词],如:USER_ID,SYS.PATH。

客户端变量: 数字-单词[.单词],如:1-USERNAME,12-USER_NAME,11-COMPONENTS.AMOUNT

注:以上 `[]` 表示可重复 0 次和多次的子结构。

JS 正则表达式为:

服务端变量: /^\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&params2=val2 查询参数 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_IDROLES。有时候我们需要用户其他相关信息,比如性别生日职位所属部门账号状态等等,希望他们随着用户的登录,由系统保存为可用的用户变量,方便开发时使用,则可以通过以下方式为用户添加初始变量:

  • 使用绑定用户表方式登录时

    此时,只需给该登录用户表添加需要的任何字段,系统会在用户登录成功时,将该用户记录其他字段全部添加为初始变量(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 变量的概念,对于业务的拆解设计会起到事半功倍的效果。

【附】系统预设可用变量列表

results matching ""

    No results matching ""