自定义逻辑
在前面的文档章节中,我们已经有了客户信息
和客户经理
的模型驱动页面,覆盖了大部分需求,但有一些特殊的复杂需求,模型驱动页面无法满足,因此我们需要基于模型驱动页面做一些自定义改造。
本章节将针对余下的两条个性化需求进行讲解说明:
需求
完成客户信息增删改查页面,客户信息包含字段及其要求如下:
主键,自动生成客户名称,可根据该字段进行模糊搜索- 客户代码,长度限制 10,后台检测并提示报错信息
- 客户经理,对应另一张【客户经理】表的主键
客户性质,绑定字典客户来源,绑定字典行业排名,绑定字典行业排名依据
完成客户经理信息增删改查页面,该页面主要为客户信息提供关联数据,因此此处简化,字段如下:
主键,自动生成客户经理名称
解绑
在模型驱动页面章节中提到过,模型驱动页面与数据模型深度绑定,无法编辑页面与接口逻辑,因此,我们要自定义逻辑,就需要先与数据模型解除绑定。
选中
cust
页面,在右侧菜单中点击"解绑"按钮,弹出解绑确认框,点击"确认"按钮完成解绑:完成解绑后,在【接口页签】->【接口列表节点】下会生成该页面用到的所有通用接口,这些接口对应了自定义 CRUD章节中提到的
初始模型方法
,但维度更高,相当于后端的 controller 层 + service 层,即它们不仅是后端暴露给前端页面用作数据交互的广义上的接口,同时也包含接口中的调用逻辑,双击接口可以看到每个接口的初始逻辑仅为调用模型方法,但我们可以利用逻辑设计器为接口自定义更丰富的逻辑:
自定义接口逻辑
双击
createTCust
接口,进入逻辑设计器;在左下方逻辑单元区域,拖动条件到中央设计器区域的逻辑调用链上;
点击刚刚拖入的if,在右侧属性面板上点击条件输入框右侧的绑定符号"{/}",在弹出窗口中配置条件表达式,选择左下方【内置方法】-> 【字符串函数】,找到
length(str)
函数,双击使其在上方自动填入表达式模版,删除模版中的入参str
,选择左下方【局部变量】->【request】-> 【custCode】,双击使其作为新的函数参数,手动在表达式后补齐判断条件" > 10",点击右下方"确认"按钮完成表达式编辑;局部变量
:自定义接口逻辑中可以使用的变量,变量来源包括:- 默认,包括请求参数
request
及响应参数response
下的字段
逻辑单元返回值临时变量:
有些时候我们需要自定义一些变量来接收某些值,因此,我们也支持自定义局部变量。
内置函数
:我们为逻辑设计提供了许多内置后端函数方便快速处理某些逻辑,目前包含列表函数
、异常函数
、字符串函数
。- 默认,包括请求参数
将原逻辑单元
调用模型
和赋值
拖入false
分支,在true
分支拖入抛出异常
,点击抛出异常
,在右侧属性面板中的异常内容输入框中输入字符串内容**'客户代码长度不能超过 10'**;这段逻辑对应的
java伪代码
逻辑为:javaif(request.getCustCode().length() > 10) { throw new RuntimeException("客户代码长度不能超过10"); } else { // 执行mapper方法数据入库 }
if(request.getCustCode().length() > 10) { throw new RuntimeException("客户代码长度不能超过10"); } else { // 执行mapper方法数据入库 }
点击右上角"保存"按钮进行保存;
测试效果,双击页面,点击右上角"预览"按钮,新增一条数据,其他必填数据随便输入,
客户代码
输入长度超过 10 的内容触发我们刚刚自定义的逻辑:
自定义页面
双击
manager
页面,点击"新增"按钮,新增几条数据,为后续效果呈现做准备:现在我们需要查询所有客户经理接口,为客户信息创建时能够通过下拉选来选择客户经理做准备,由于客户经理页面现在仍为模型驱动页面,所以没有显式接口提供,我们需要的这个接口有两种方式可以创建:
- 手动录入:大致流程为手动创建接口,然后编辑接口逻辑,使用
调用模型
逻辑单元,逻辑单元的逻辑方法设置为调用客户经理数据模型的queryList
方法 - 自动生成:解绑客户经理页面,如同本章开始解绑客户信息页面一样,自动会生成该页面的所有接口,其中自然包括了查询所有客户经理接口
此处我们直接使用手动录入的方式,对本系统不熟悉的用户可自行尝试使用自动生成的方式创建接口。
2.1. 新增接口
queryAllManager
2.2. 选中接口返回参数,在右侧属性面板中将 root 类型设置为
数组
这里返回参数 root 类型的设置对应了 KOCA 接口标准协议中返回参数的三种类型:
Result(对象)
javaclass 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(数组)
javaclass 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(分页)
javaclass 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;
- 手动录入:大致流程为手动创建接口,然后编辑接口逻辑,使用
双击选中
cust
页面,切换到【页面逻辑页签】,在【页面逻辑节点】右侧菜单中,点击"添加页面变量"新增一个页面变量managerList
;点击新增的页面变量
managerList
,在右侧属性面板将数据类型
设置为array
;在【页面逻辑节点】右侧菜单中,点击"添加页面方法"新增一个页面方法
queryManager
;双击新增的页面方法
queryManager
,进入逻辑设计面板,拖入调用接口
,点击拖入的调用接口
,在右侧属性面板的接口
选择之前创建的接口queryAllManager
;拖入
赋值
,点击拖入的赋值
,在右侧属性面板中,变量
选择之前创建的【页面变量】->【managerList】,值
点击绑定按钮"{/}",在弹出窗口中选择【局部变量】->【res】-> 【data】,点击右上角"保存"按钮进行保存;上面两步对应的
javascript伪代码
逻辑为:javascriptconst res = await http.post(queryAllManager, {}); state.managerList = res.data;
const res = await http.post(queryAllManager, {}); state.managerList = res.data;
在【页面逻辑节点】-> 【事件】中,双击
组件挂载后-onMounted
事件方法,为本页面定义页面加载逻辑,拖入调用逻辑
,点击拖入的调用逻辑
,在右侧属性面板中修改逻辑
,选择【页面逻辑】->【queryManager】,点击右上角"保存"按钮进行保存;上面对应的
javascript伪代码
逻辑为:javascriptonMounted(() => { queryManager(); });
onMounted(() => { queryManager(); });
在页面设计面板左下方,打开
通用对话框
,删除表单中的客户经理
输入框,拖入【录入控件】-> 【下拉】,点击拖入的下拉
,在右侧属性面板中,属性选项列表
选择【页面变量】-> 【managerList】,设置取值字段
为id
,显示字段
为name
,点击属性面板中的【编码页签】,v-model
绑定【页面变量】->【dialogForm】->【custManager】修改接口
queryTCustPage
逻辑中调用模型
,将方法换为文档自定义 CURD中我们创建的新数据模型方法queryPageDetail
,点击右上角"保存"按钮进行保存;进入
cust
页面设计面板,选中表格中的客户经理
列,在右侧属性面板中,修改字段名
为我们自己创建的模型方法queryPageDetail
中查询出的客户经理名称字段managerName
完成全部自定义,测试效果: