Skip to content

自定义逻辑

在前面的文档章节中,我们已经有了客户信息客户经理的模型驱动页面,覆盖了大部分需求,但有一些特殊的复杂需求,模型驱动页面无法满足,因此我们需要基于模型驱动页面做一些自定义改造。

本章节将针对余下的两条个性化需求进行讲解说明:

需求

完成客户信息增删改查页面,客户信息包含字段及其要求如下:

  • 主键,自动生成
  • 客户名称,可根据该字段进行模糊搜索
  • 客户代码,长度限制 10,后台检测并提示报错信息
  • 客户经理,对应另一张【客户经理】表的主键
  • 客户性质,绑定字典
  • 客户来源,绑定字典
  • 行业排名,绑定字典
  • 行业排名依据

完成客户经理信息增删改查页面,该页面主要为客户信息提供关联数据,因此此处简化,字段如下:

  • 主键,自动生成
  • 客户经理名称

解绑

模型驱动页面章节中提到过,模型驱动页面与数据模型深度绑定,无法编辑页面与接口逻辑,因此,我们要自定义逻辑,就需要先与数据模型解除绑定

  1. 选中cust页面,在右侧菜单中点击"解绑"按钮,弹出解绑确认框,点击"确认"按钮完成解绑:

  2. 完成解绑后,在【接口页签】->【接口列表节点】下会生成该页面用到的所有通用接口,这些接口对应了自定义 CRUD章节中提到的初始模型方法,但维度更高,相当于后端的 controller 层 + service 层,即它们不仅是后端暴露给前端页面用作数据交互的广义上的接口,同时也包含接口中的调用逻辑,双击接口可以看到每个接口的初始逻辑仅为调用模型方法,但我们可以利用逻辑设计器为接口自定义更丰富的逻辑:

自定义接口逻辑

  1. 双击createTCust接口,进入逻辑设计器;

  2. 在左下方逻辑单元区域,拖动条件到中央设计器区域的逻辑调用链上;

  3. 点击刚刚拖入的if,在右侧属性面板上点击条件输入框右侧的绑定符号"{/}",在弹出窗口中配置条件表达式,选择左下方【内置方法】-> 【字符串函数】,找到length(str)函数,双击使其在上方自动填入表达式模版,删除模版中的入参str,选择左下方【局部变量】->【request】-> 【custCode】,双击使其作为新的函数参数,手动在表达式后补齐判断条件" > 10",点击右下方"确认"按钮完成表达式编辑;

    局部变量:自定义接口逻辑中可以使用的变量,变量来源包括:

    • 默认,包括请求参数request及响应参数response下的字段

    • 逻辑单元返回值临时变量:

    • 有些时候我们需要自定义一些变量来接收某些值,因此,我们也支持自定义局部变量。

    内置函数:我们为逻辑设计提供了许多内置后端函数方便快速处理某些逻辑,目前包含列表函数异常函数字符串函数

  4. 将原逻辑单元调用模型赋值拖入false分支,在true分支拖入抛出异常,点击抛出异常,在右侧属性面板中的异常内容输入框中输入字符串内容**'客户代码长度不能超过 10'**;

    这段逻辑对应的java伪代码逻辑为:

    java
    if(request.getCustCode().length() > 10) {
      throw new RuntimeException("客户代码长度不能超过10");
    } else {
      // 执行mapper方法数据入库
    }
    if(request.getCustCode().length() > 10) {
      throw new RuntimeException("客户代码长度不能超过10");
    } else {
      // 执行mapper方法数据入库
    }
  5. 点击右上角"保存"按钮进行保存;

  6. 测试效果,双击页面,点击右上角"预览"按钮,新增一条数据,其他必填数据随便输入,客户代码输入长度超过 10 的内容触发我们刚刚自定义的逻辑:

自定义页面

  1. 双击manager页面,点击"新增"按钮,新增几条数据,为后续效果呈现做准备:

  2. 现在我们需要查询所有客户经理接口,为客户信息创建时能够通过下拉选来选择客户经理做准备,由于客户经理页面现在仍为模型驱动页面,所以没有显式接口提供,我们需要的这个接口有两种方式可以创建:

    • 手动录入:大致流程为手动创建接口,然后编辑接口逻辑,使用调用模型逻辑单元,逻辑单元的逻辑方法设置为调用客户经理数据模型的queryList方法
    • 自动生成:解绑客户经理页面,如同本章开始解绑客户信息页面一样,自动会生成该页面的所有接口,其中自然包括了查询所有客户经理接口

    此处我们直接使用手动录入的方式,对本系统不熟悉的用户可自行尝试使用自动生成的方式创建接口。

    2.1. 新增接口queryAllManager

    2.2. 选中接口返回参数,在右侧属性面板中将 root 类型设置为数组

    这里返回参数 root 类型的设置对应了 KOCA 接口标准协议中返回参数的三种类型:

    • Result(对象)

      java
      class Result<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private T body;
      }
      class Result<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private T body;
      }
    • ListResult(数组)

      java
      class ListResult<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private List<T> body;
      }
      class ListResult<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private List<T> body;
      }
    • PageListResult(分页)

      java
      class ListResult<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private PageList<T> body;
      }
      
      class PageList<T> {
          private long total;
          private List<T> data;
      }
      class ListResult<T> {
          private String code;
          private String msg;
          private String detail;
          private Map<String, Object> head = new HashMap<>();
          private PageList<T> body;
      }
      
      class PageList<T> {
          private long total;
          private List<T> data;
      }

      我们定义的返回值结构其实对应的是协议中 body 的结构(在分页中,定义的是 body.data 的结构);

      因此,在逻辑设计中,很多地方对接口返回参数赋值的对象则为 response.body(非分页) 或者 reponse.body.data(分页)。

    2.3. 双击接口queryAllManager,进入逻辑设计面板,拖入调用模型,点击拖入的调用模型,在右侧属性面板模型方法选择客户经理数据模型的queryList方法,参数点击绑定按钮"{/}",在弹出窗口中选择【局部变量】->【request】作为方法入参;

    2.4. 拖入赋值,点击拖入的赋值,在右侧属性面板中,变量选择【局部变量】->【response】-> 【body】,点击绑定按钮"{/}",在弹出窗口中选择【局部变量】->【res】,即将上一步调用模型方法的结果变量res整体赋值给了 response.body,因此在这个案例中,我们可以不为接口返回参数定义具体结构,如果在实际开发中,需要对结果参数的某一些字段单独赋值,则需要自行定义结构并在逻辑设计中进行处理。

    2.5. 点击右上方的"保存"按钮进行保存,这段逻辑的java伪代码为:

    java
    // 调用模型方法
    Object res = model.quertList(request);
    // 赋值
    response.setBody(res);
    // 返回response
    return response;
    // 调用模型方法
    Object res = model.quertList(request);
    // 赋值
    response.setBody(res);
    // 返回response
    return response;
  3. 双击选中cust页面,切换到【页面逻辑页签】,在【页面逻辑节点】右侧菜单中,点击"添加页面变量"新增一个页面变量managerList

  4. 点击新增的页面变量managerList,在右侧属性面板将数据类型设置为array

  5. 在【页面逻辑节点】右侧菜单中,点击"添加页面方法"新增一个页面方法queryManager

  6. 双击新增的页面方法queryManager,进入逻辑设计面板,拖入调用接口,点击拖入的调用接口,在右侧属性面板的接口选择之前创建的接口queryAllManager

  7. 拖入赋值,点击拖入的赋值,在右侧属性面板中,变量选择之前创建的【页面变量】->【managerList】,点击绑定按钮"{/}",在弹出窗口中选择【局部变量】->【res】-> 【data】,点击右上角"保存"按钮进行保存;

    上面两步对应的javascript伪代码逻辑为:

    javascript
    const res = await http.post(queryAllManager, {});
    state.managerList = res.data;
    const res = await http.post(queryAllManager, {});
    state.managerList = res.data;
  8. 在【页面逻辑节点】-> 【事件】中,双击组件挂载后-onMounted事件方法,为本页面定义页面加载逻辑,拖入调用逻辑,点击拖入的调用逻辑,在右侧属性面板中修改逻辑,选择【页面逻辑】->【queryManager】,点击右上角"保存"按钮进行保存;

    上面对应的javascript伪代码逻辑为:

    javascript
    onMounted(() => {
      queryManager();
    });
    onMounted(() => {
      queryManager();
    });
  9. 在页面设计面板左下方,打开通用对话框,删除表单中的客户经理输入框,拖入【录入控件】-> 【下拉】,点击拖入的下拉,在右侧属性面板中,属性选项列表选择【页面变量】-> 【managerList】,设置取值字段id显示字段name,点击属性面板中的【编码页签】, v-model绑定【页面变量】->【dialogForm】->【custManager】

  10. 修改接口queryTCustPage逻辑中调用模型,将方法换为文档自定义 CURD中我们创建的新数据模型方法queryPageDetail,点击右上角"保存"按钮进行保存;

  11. 进入cust页面设计面板,选中表格中的客户经理列,在右侧属性面板中,修改字段名为我们自己创建的模型方法queryPageDetail中查询出的客户经理名称字段managerName

  12. 完成全部自定义,测试效果: