数据引擎
表
数据校验脚本
表可以定义一个 用来校验数据是否有效的脚本,该脚本在前端运行,在用户编辑完表记录之后,系统会自动调用
(ownerID,providerItemKey,compondItem,params,envViables,actionCode)=>
// 返回值 null :表示检查通过
// 返回值非null:表示检查不通过,提示原因为 result.toString()
用户定义表
Scheme表
虚拟表
字段
action
前置条件

- 可以针对 某一个字段 设置action的前置条件
- 可以 设置一个 脚本用来检查前置条件
//#RuiScriptSetting{"kind":"ES6"} (ownerID,providerItemKey,item)=> { //脚本返回值的意义 // 1 没有返回值或者return null. 表示 前置条件检查 通过 // 2 返回 bool类型 true:前置条件检查通过 false:检查不通过 ,但是原因不明确 // 3 返回 非bool类型 表示 检查不通过,原因为 返回对象.toString() }
全局action
全局action表示 不具体针对某一条记录的 action,例如 新建记录、月度结转等。默认会显示在 查询结果的 左上角 全局Aciotn需要勾选Global标志,表示 是全局Action 全局Action的OperateType 必须选择 未指定 或者 新建

操作类型为 未指定的 全局Action 用户自定义前后台操作 默认前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource,ownerID,providerItemKey,hashKey,rangeKey,actionCode,actionName,actionOperateType,envViables)=>
{
//默认的脚本,什么都不做
}
默认服务端脚本
//#RuiScriptSetting{"kind":"ES6"}
(ownerID, providerItemKey, envViables) => {
//默认的脚本,什么都不做
return true;
}
操作类型为 新建 的全局Action 表示新建一条记录 默认前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource, ownerID, providerItemKey, hashKey, rangeKey, actionCode, actionName, actionOperateType, envViables) => {
//$newItem = _getNewSingleItem(ownerID, providerItemKey,actionCode,envViables);
const $newItem = _dataSource_NewSingleItem(dataSource, ownerID, actionCode, envViables); //modify 2022.01.30 支持GetParam功能后改进
let $isShouldWhile = true;
while ($isShouldWhile) {
try {
const $result = _showAndEdit(actionName, ownerID, actionOperateType, providerItemKey, $newItem, actionCode, envViables);
if ($result) {
//$newRangeKey = _dataSource_AddItem(dataSource,_getobjectproperty($newItem,"SingleItem"),actionCode,envViables);
const $newRangeKey = _dataSource_AddItem(dataSource, $newItem, actionCode, envViables); //modify 2022.01.30 支持GetParam功能后改进
return (!(_isnullorempty($newRangeKey)));
} else {
return false;
}
}
catch (ex) {
//什么都不做,执行下个循环
_showExceptionInfo(ex);
}
}
}
默认服务端脚本
//#RuiScriptSetting{"kind":"ES6"}
(ownerID, providerItemKey, newCompondItem_Value, aclItem, envViables) => {
const $result = _compondValue_InsertToDB(newCompondItem_Value);
if ($result) {
return true;
} else {
return false;
}
}
非全局action
非全局Action 表示 针对某条具体记录的 action,例如 针对某个订单, 有 收款、取消订单、指派订单 等action。默认会显示该条记录的 右面 非选择订单 不能勾选Global标志,表示非 非全局Action
操作类型为 包含字表修改ModifyWithDetail 的非全局Action 表示修改一条记录,同时修改 其所有字表信息 默认前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource, ownerID, providerItemKey, hashKey, rangeKey, actionCode, actionName, actionOperateType, envViables) => {
const $newItem = _dataSource_GetSingleItem(dataSource, hashKey, rangeKey, actionCode, envViables);
let $isShouldWhile = true;
while ($isShouldWhile) {
try {
const $result = _showAndEdit(actionName, ownerID, actionOperateType, providerItemKey, $newItem, actionCode, envViables);
if ($result) {
//$count = _dataSource_UpdateItem(dataSource,_getobjectproperty($newItem,"SingleItem"),actionCode,envViables)
const $count = _dataSource_UpdateItem(dataSource, $newItem, actionCode, envViables);//modify 2022.01.30 支持GetParam功能后改进
return ($count > 0);
}
else {
return false;
}
}
catch (ex) {
//什么都不做,执行下个循环
_showExceptionInfo(ex);
}
}
}
默认服务端脚本
//#RuiScriptSetting{"kind":"ES6"}
(ownerID, providerItemKey, oldFieldValue, newCompondItem_Value, aclItem, envViables) => {
const $result = _compondValue_SaveToDB(newCompondItem_Value);
if ($result) {
return true;
} else {
return false;
}
}
操作类型为 不包含字表修改ModifyWithoutDetail 的非全局Action 唯一不同点:服务端多携带一个参数oldFieldValue 表示修改一条记录,但是不修改字表信息 默认前端脚本
//等同于 ModifyWithDetail 的前端脚本
默认服务端脚本
//等同于 ModifyWithDetail 的前端脚本,因为 ES6语法支持 根据参数名匹配参数,所以 可以直接使用同样的脚本
操作类型为 删除 的非全局Action 表示删除一条记录 默认前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource, ownerID, providerItemKey, hashKey, rangeKey, actionCode, actionName, actionOperateType, envViables) => {
const $result = _confirm("Do you want to delete " + " [" + rangeKey + "] ?");
if ($result) {
$count = _dataSource_DeleteItem(dataSource, actionCode, hashKey, rangeKey, envViables);
return ($count > 0);
} else {
return false;
}
}
默认服务端脚本
操作类型为 查询 的非全局Action 表示 查询 一条记录 的明细 默认前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource, ownerID, providerItemKey, hashKey, rangeKey, actionCode, actionName, actionOperateType, envViables) => {
const $newItem = _dataSource_GetSingleItem(dataSource, hashKey, rangeKey, actionCode, envViables);
_showAndEdit(actionName, ownerID, actionOperateType, providerItemKey, $newItem, actionCode, envViables);
return true;
}
默认服务端脚本
没有后端脚本
显示操作日志 显示一条记录的 日志,前提是 该表设置了 显示日志 前端脚本
//#RuiScriptSetting{"kind":"ES6"}
(dataSource, ownerID, providerItemKey, hashKey, rangeKey, actionCode, actionName, actionOperateType, envViables) => {
const $where = [new Condition("TableName", "=", providerItemKey), new Conditon("OperItemRangeKey", "=", rangeKey)];
const $listResult = _queryItemsListResult(ownerID, "PUBACTIONLOG", $where);
_showResult("操作日志", $listResult);
return true;
}
默认服务端脚本 无 服务端脚本
Action中的事务处理
默认action中的事务处理为 自动事务处理模式,即:
- 平台开启事务
- 执行 服务端脚本
- 如果 没有发生异常且返回值不是false, 则提交事务
- 否则 回滚事务
当脚本不需要 平台自动处理事务时,则 可以在 action属性中的 事务管理类型 中选择 Manual手工模式 则脚本执行方式为:
- 执行 服务端脚本
在脚本中,开发者可以自己控制事务处理,示例代码如下
//#RuiScriptSetting{"kind":"ES6"}
//其他代码
_dbBeginTrans(); //开始事务
try
{
//业务处理代码
_dbCommitTrans(); //执行成功,提交事务
}
catch(ex)
{
_dbRollbackTrans(); //执行失败,回滚事务
//其他代码
}
//其他代码
query查询
系统仅支持所有查询条件均为 add的查询,也就是说where条件中,系统不支持 or,仅仅支持and 如果需要查询条件为or的,则可以采用如下两种方式:
分成两个查询 将需要or的条件 修改为 针对一个虚拟字段的 查询条件,或者使用 in 查询
代码中查询条件的构造
//#RuiScriptSetting{"kind":"ES6"}
const $where = [];
$where.push(new Condition("字段GuidKey","=",值));
$where.push(new Condition("MyName","=","张三"));
const $listResult = _queryItemsListResult(ownerID,"TableCode",$where);
条件判断类型表
| 类型 | 别名 | 意义 |
|---|---|---|
| GreatThan | > | 大于 |
| GreatAndEqual | >= | 大于等于 |
| LessThan | < | 小于 |
| LessAndEqual | <= | 小于等于 |
| Equal | = | 等于 |
| NotQqual | != | 不等于 |
| StringLeftLike | 以某个字符串开始 | |
| StringRightLike | 以某个字符串结束 | |
| StirngBothLike | 包含某个字符串 | |
| IsNullOrEmptyValue | null或者空字符串 | |
| IsNotNULLEitherEmptyValue | 非 null同时也不是空字符串 | |
| IsNULL | null | |
| IsNotNull | 非 null | |
| In | 包含 逗号隔开的字符串 | |
| NotIn | 不包含 逗号隔开的字符串 |
trigger触发器
trigger类型
trigger 脚本
AutoEdit触发器
AutoEdit触发器可以在针对某表记录 获取之后和发送给客户端之前,进行修改操作 触发时机:
- 黄色背景框中左右过滤条件的 记录创建之后 执行表触发器
- 新建或者修改某条记录,系统获取到新记录之后,执行表触发器
触发时间点:
- before
- after
beforeAutoEdit触发器示例:before触发器的脚本没有params参数
//#RuiScriptSetting{"kind":"ES6"}
( ownerID, providerItemKey,item, dataSource, isNewCreate, envVariables)=>
{
//...
}
after AutoEdit 触发器脚本示例和说明:(一般常用afterAutoEdit触发器)
//#RuiScriptSetting{"kind":"ES6"}
//收款支付表的 触发器
( ownerID, providerItemKey,item, dataSource, isNewCreate, envVariables, paramList)=>
{
cosnt $payPlanCode = item['12dff5a75b964419a389e7c1322c1881'];// 收款计划编号
if (!(_isnullorempty($payPlanCode )))
{
const $moneyFieldCode = _fromFieldReferenceCodeToFieldCode( ownerID, "435b9a60f1fa467795efa120b891ea3e");
//如果是由 支付计划发起的,则固定 金额
const $moneyParam = paramList.find(g=>g.ParamCode == $moneyFieldCode);
const $money = [435b9a60f1fa467795efa120b891ea3e:item];
$moneyParam.MinValue = _to_str($money);
$moneyParam.MaxValue = _to_str($money);
$moneyParam.IsReadonly = true;
}
else
{
if(envVariables != null) //add 2021.06.15 当作为查询条件黄色背景框出现的时候,此处没有 环境变量
{
const $triggerCallBackFunctionName = _8939bf4ce78346d5a8d4a980fb6c4713_GetAfterAutoEditTrigger(envVariables);
if (!(_isnullorempty($triggerCallBackFunctionName)))
{
//调用这个回调函数,给业务系统执行自己触发器的机会,此时可以修改 字段的设置
const $paramList = [ownerID, providerItemKey,item, dataSource, isNewCreate, envVariables, paramList];
_callScriptFunction($triggerCallBackFunctionName,$paramList);
}
}
}
}
表单引擎
权限
权限设计采用多层次设计方案,模块中先 通过权限组,将 一组 Menu和一组 Actions 定义到一个权限组中 然后,权限组可以授权给 Role,然后通过Role间接地授权到某个 FutuID,这样 某个FutuID就获得到了 一组 Menu和Action的权限
如下图所示:

App 模块入口
用户登录到 模块之后,系统会做如下操作:
- 通过用户的有权限的 menus,根据每个Menu的归属的 App,提取出 该用户 所有有权限的 Apps,例如 老板的账号登录,有权限的 App是 餐馆管理和客户点餐。 普通客户有权限的 App是客户点餐。 已经注册的外卖骑手 有权限的 App是 骑手
- 如果是有多个 App,则显示 一个 App列表给用户选择 决定进入 哪个 App,如果 只有一个 App,则转入下一步,直接进入App
- 系统根据App中配置的 PC入口点Menu和移动入口点Menu,根据当前是PC还是手机,自动选择一个 Menu,显示这个Menu对应的Page内容
- 如果App中没有定义 入口点Menu,则显示第一个Menu的内容
- 如果 App中的入口点Menu是不存在的(该Menu被删除或者没有权限),则 按照最传统的方式,显示出所有的 菜单
jobs
定时任务。
备注: 定时任务执行的时候,平台不做任何事务性处理,这个和action的服务端脚本是有区别的,原因是 因为 jobs一般是进行批量处理,系统不好进行事务性处理 如果定时任务脚本 需要事务处理,可以参考 上面章节中 事务处理
`javascript //#RuiScriptSetting{"kind":"ES6"} (ownerID,params)=> { //... }
<center>返回值意义</center>
<table style="font-size:13px" >
<tr style="background-color:lightgrey">
<th>返回值</th><th>意义</th>
</tr>
<tr>
<td>没有返回值或者返回null</td><td>执行成功</td>
</tr>
<tr>
<td>返回整型值</td><td>0:失败 <br />1:成功 <br /> 2,成功但是携带提示信息,错误信息就是返回值</td>
</tr>
<tr>
<td>返回bool类型</td><td>true:成功<br />false:失败</td>
<tr>
<td>返回其他类型</td><td>失败。 失败原因为返回值.toString()</td>
</tr>
</table>
<b>Job中的信息输出</b>
Job中需要记录信息的时候,可以使用如下函数记录信息,该信息会被记录到 Job的执行日志中
```javascript
void _appendLog(string log)
jobs的执行结果
jobs会被调度定时执行,执行结果在系统的 定时任务执行结果表中,在管理界面可以查看
jobs的刷新
系统在启动的时候以及每到整点会进行jobs的刷新,刷新的结果也会 以任务名: refreshJobs的日志 存储在 jobs执行结果日志中,可以通过Jobs执行结果日志查看 定时刷新jobs的结果。如果可以访问服务端的话,也可以通过wildfly的console界面看到刷新结果
关于jobs的重要说明
- 因为jobs会被定时执行,所以 需要谨慎编写jobs的代码
- 因为jobs会被定时执行,所以 需要谨慎 设计 jobs的执行频率,建议执行时间放在非工作时间,例如夜间
- 不使用的 job可以 修改属性 Enable, 所有 disbaled的jobs不会被调度执行,已经被调度执行的disbaled的jobs也会被在下次刷新的时候,自动从 调度系统删除
- 如果job代码中需要进行事务处理,则需要开发者手工进行事务处理
- 定时 检查 job执行日志,发现异常情况,需要马上处理
数据流引擎
待完成
