设计手册
遇到问题了吗?不用担心,答案都在这。
全站搜索

Javascript 工作发动机

所有表单都可以触发 Ragic 的服务器端 JavaScript 工作流程发动机来运行复杂的业务逻辑,如计算成本和发布库存余额。基本上,任何 Ragic 现有功能无法覆盖的复杂业务逻辑都可以透过服务器端程序来实现。

程序发动机基于标准的 Nashorn Java 程序发动机,它包含在 Java 平台中。Nashorn 支持 ECMAScript 5.1,所以最好避免使用 ECMAScript 6 句法。

JavaScript 工作流程的功能

Ragic 的电子表格设计接口可以处理大部分数据管理工作,如创建、编辑和查询记录。然而,手动数据维护可能会变得有点耗时和繁琐。这时,Ragic 订户会开始考虑如何自动化这些过程。

在 Ragic 内部,有一个非常强大的程序发动机,可以编写在服务器端运行的 JavaScript,用来检索电子表格上的数据,进行修改,甚至可以一次点击创建多个纪录。典型的使用场景包括更新库存,根据另一笔纪录创建新纪录(例如从报价创建销售订单,从Sales lead创建联络人),或者用数据库数据做数据检查。

有五种主要方式来运行您的 JavaScript 工作流程:

  1. 动作单击钮
  2. Post-workflow
  3. Pre-workflow
  4. Daily Workflow
  5. Approval Workflow

还有一个 Global Workflow,您可以在其中放置多个工作流程程序共享的常用 JavaScript 函数定义。

动作单击钮

这是运行 JavaScript 工作流程最常见和最清晰的方式,通常是我们的首选推入荐。您可以在工作表的sheet scope中编写程序,并分配动作单击钮来运行程序,当订户点击将显示在右下方“动作”面板中的单击钮时。

要加上 sheet scope 程序,只需右键点击一个工作表,然后选择JavaScript Workflow

并从顶部下拉菜单中选择sheet scope

然后,您可以转到表单页面面设计中,加上一个类型为JS Workflow动作单击钮,并引用您编写的 JavaScript 函数。

请注意,您可以使用 {id} 作为函数调用的参数来传递当前记录的纪录 ID,例如:

setStatus({id})

当然,我们会在接下来的章节中介绍如何编写这些函数。

Post-workflow

Post-workflows 在记录保存后立即运行。通过 Post-workflow,可以方便地自动化您希望对刚保存的纪录进行的变更,而这些变更是公式无法完成的。或者,您可以对其他相关工作表的纪录进行修改,例如更新库存余额。

要加上 Post-workflow,只需右键点击一个工作表,然后选择JavaScript Workflow

然后从顶部下拉菜单中选择Post-workflow

一个典型的 Post-workflow 如下所示:

var recordId = param.getNewNodeId(key_field_id_of_form);

var query = db.getAPIQuery(path_to_form);

var record = query.getAPIEntry(id);

// 对检索到的纪录进行所需操作

请参阅我们的 API 参阅 和本文档的其他部分,了解您可以做的事情。

还请注意,如果您在列表页面面上修改数据,Post-workflow 将不会运行。

Pre-workflow

Pre-workflows 在记录保存之前运行,因此可以用作检查的一种方式,以检查输入的数据是否符合数据库中的数据。通常,大多数检查可以通过我们的前端正则表达式检查,或自由文本字段的唯一核取方块来完成。但对于更复杂的后端检查,有时需要 Pre-workflow。

要加上 Pre-workflow,只需右键点击一个工作表,然后选择JavaScript Workflow

然后从顶部下拉菜单中选择Pre-workflow

这里有一个简单的例子:

假设我们有一个列表,

我们希望确保保存的价格不是负数。

/**

* 主键码字段: 1000004

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* ID : 1000001

* 价格 : 1000002

* 名称 : 1000003

* 是否可用 : 1000005

*/

function log(str) {

// 设置状态为 'INVALID' 或 'ERROR' 以撤销保存。

response.setStatus('INVALID');

response.setMessage(str);

}

function ifThePriceIsNegative() {

// 获取要保存的价格。

var newPrice = param.getNewValue(1000002);

// 将 newPrice 字符串转换为整数。

if(parseInt(newPrice) < 0) {

return true;

}

}

// 如果价格为负数,则不保存。

if(ifThePriceIsNegative()) {

log('价格为负数!!');

}

现在尝试保存负数价格,我们会得到

值得注意的是,在 Ragic 中编写 Pre-workflow 时,不能使用 entry.getFieldValue(因为 Ragic 还没有保存)。请尝试使用 param 来获取旧值和新值。

Daily Workflow

Daily Workflows 每天运行一次。这对于需要每天更新结果的修改非常有用,例如根据当前日期更新公式结果。

要加上 Daily Workflow,只需右键点击一个标签,然后选择Global Javascript Workflow

然后从顶部下拉菜单中选择Daily Workflow

默认情况下,Daily Workflow 在 UTC 19:00 运行。您可以在公司设置中更改运行时间和时区:

1. 前往帐户设置

2. 点击公司设置

3. 选择公司当地时区Daily Workflow 运行时间并保存。

如果您的公司设置中没有公司当地时区Daily Workflow 运行时间,请联络我们来为您更新。

Approval Workflow

Approval Workflows 在签核创建、签核、拒绝、撤销或完成后立即运行。

要加上 Post-workflow,只需右键点击一个工作表,然后选择JavaScript Workflow

然后从顶部下拉菜单中选择Approval Workflow

您可以透过以下方法获取记录 ID:

var recordId = approvalParam.getEntryRootNodeId();

approvalParam 是签核工作流程范围内的预定义变量。

您可以透过以下方法获取签核操作:

var action = approvalParam.getApprovalAction();

在获取上述数据后,您可以根据需求进行自订:

var query = db.getAPIQuery(path_to_form);

var entry = query.getAPIEntry(recordId);

if (action === 'CANCEL') {

entry.setFieldValue(STATUS_FIELD, "签核已撤销!");

}else if (action === 'FINISH') {

entry.setFieldValue(STATUS_FIELD, "签核已完成!");

}else if (action === 'CREATE') {

entry.setFieldValue(STATUS_FIELD, "签核已创建!");

}else if (action === 'REJECT') {

entry.setFieldValue(STATUS_FIELD, "签核已拒绝!");

}else {

entry.setFieldValue(STATUS_FIELD, "签核已批准!");

}

entry.save();

Global Workflow

Global Workflow 是您可以编写的 JavaScript 工作流程模块,其他工作流程函数可以引用它。它不会自己运行,但可以在上面列出的任何类型的工作流程中引用。这是一个很好的地方来放置可能需要在多个工作表中重复的程序。

要加上 Global Workflow,只需右键点击一个标签,然后选择Global Javascript Workflow

获取一笔数据

有两种不同的方式来获取订户正在查看的当前记录(适用于动作单击钮)或订户刚保存的纪录(适用于 Pre-workflow 和 Post-workflow)。

动作单击钮

表单页面面动作单击钮透过分配动作单击钮来调用您在 sheet scope 中定义的函数。当您定义动作单击钮调用的函数时,您可以传递参数 {id},即点击动作单击钮所在记录的 ID,来在工作流程中使用。

您可以在 动作单击钮工作流程 中看到范例。

Pre-workflow

您可以透过以下方法获取记录 ID:

var recordId = param.getNewNodeId(key_field_id_of_form);

param 是一个预定义变量,您可以在 Pre-workflow 和 Post-workflow 中使用它。

在获取记录 ID 之后,这是获取记录(entry)的方式:

var query = db.getAPIQuery(path_to_form);

var entry = query.getAPIEntry(id);

Post-workflow

对于 Post-workflow,您可以使用与 Pre-workflow 相同的方法。但是,还有一种方便的方法来检索刚刚保存的纪录:

var entry=param.getUpdatedEntry();

如果表单页面面上有字掩码字段,默认情况下您将获得掩码值。您可以透过以下方式获取未掩码的值:

var query = db.getAPIQuery(path_to_form);

query.setUpdateMode();

query.setIgnoreAllMasks(true); // 撤销所有掩码字段的掩码。

var entry = query.getAPIEntry(id);

您可以使用 query.addIgnoreMaskDomain(fieldId_of_the_masked_field) 而不是 query.setIgnoreAllMasks(true) 来仅撤销特定字段的掩码。

有关如何在以下部分中更新纪录的更多介绍,请参阅 更新纪录

查询数据

如果您想透过过滤条件获取多笔纪录:

var query = db.getAPIQuery("/workflow-demo/1");

query.addFilter(1000002, '=', 'Green');

query.addFilter(1000008, '=', '2017');

var results = query.getAPIResultList();

for (var i = 0; i < results.length; i++) {

var entry = results[i];

// ...

}

您可以使用 addFilter(fieldId, operator, value) 来加上过滤条件,并使用 getAPIResultList() 来获取记录列表。

以下是您可以使用的操作符列表:

操作符名称 操作符值
等于 =
正则表达式 regex
大于或等于
小于或等于 <=
大于
小于 <</td>
包含 like

请注意,当您透过日期或日期时间进行过滤时,它们需要以下列格式表示:yyyy/MM/ddyyyy/MM/dd HH:mm:ss

您还可以透过调用 setFullTextSearch(String queryTerm) 来使用全文搜索作为查询过滤条件,而不是 addFilter()。

更新纪录

范例链接

让我们从一个简单的范例开始,检索当前记录作为物件,使用单击钮更新其值,然后将其保存回数据库。以下是范例表单的外观:

我们希望设计一些单击钮,通过点击单击钮运行简单的服务器端 JavaScript 工作流程来更改我们的状态字段值。以下是单击钮后面的程序代码:

/**

* AP_Name:wfdemo

* 主键码字段: 1000013

* 名称 ID

* - - - - - - - - - - - --------

* No. : 1000011

* 状态 : 1000012

*/

function setStatus(recordId, status) {

var STATUS_FIELD = 1000012; // 状态字段的字段ID

var query = db.getAPIQuery("/workflow-demo/2"); // 获取工作表的查询物件

var entry = query.getAPIEntry(recordId); // 获取当前记录的物件

// 设置当前记录的状态值

if (status) {

entry.setFieldValue(STATUS_FIELD, status);

}

else { // 用于切换

var newStatus = entry.getFieldValue(STATUS_FIELD) == 'On' ? 'Off' : 'On'; // 获取字段的当前值

entry.setFieldValue(STATUS_FIELD, newStatus);

}

// 保存记录到数据库

entry.save();

}

在编写 JavaScript 工作流程时,变量 db 是预定义的,您可以在任何地方参阅它。通常,我们会调用方法 getAPIQuery(pathName) 来获取工作表的查询物件。

然后,您可以透过在工作表物件上使用 getAPIEntry(recordId) 检索记录,并使用 setFieldValue(fieldId,value) 设置字段的值,或者使用 getFieldValue(fieldId) 检索记录中的值。

请注意,当加上日期值时,它必须是以下列格式之一:

yyyy/MM/dd

yyyy/MM/dd HH:mm:ss

HH:mm:ss

如果您正在从多选字段检索值,其中可能有多个值,请使用 getFieldValues(fieldId) 以数组形式检索所有值。您还可以调用 setFieldValue(fieldId,value,true) 并在末尾加上一个 true 参数来指定您正在“加上”一个选项到当前的值列表,而不是覆盖现有值。请注意,这些操作仅适用于多选字段。

如果您想拷贝一个多选字段值并覆盖到另一个多选字段,您不能仅仅使用 getFieldValues(fieldId)setFieldValue(fieldId,value,true)。这里有一段程序代码供您参阅:


var multipleSelectionFieldValue = entry.getFieldValues(1013251); // 1013251 是一个多选字段

var targetMultipleSelectionField = "";

for (var i = 0; i < multipleSelectionFieldValue.length; i++) {

if (i == 0) {

targetMultipleSelectionField = targetMultipleSelectionField + multipleSelectionFieldValue[i];

}

else {

targetMultipleSelectionField = targetMultipleSelectionField + "|" + multipleSelectionFieldValue[i];

}

}

entry.setFieldValue(1013252, targetMultipleSelectionField, false); // 1013251 是另一个多选字段

请注意,您需要检索每个选项,并使用垂直条字符(|)格式化这些选项,就像您在从 Excel 或 CSV 文档导入现有数据时所做的一样。

如果您要将值设置为文档上载字段,您可以使用 setFieldFile(int fieldId, String fileName, String fileContent) 来创建一个具有您提供的 fileName 和 fileContent 的文档。Ragic 将会保存此文档到指定字段,这样文档就可以在订户界面上下载。

完成后,只需在记录物件上调用 save() 将其保存回数据库。

创建记录

创建记录与更新纪录非常相似。不同的是,您需要调用 query.insertAPIEntry() 来创建新纪录。与 getAPIEntry() 一样,它也会回传一个纪录物件,您可以使用 setFieldValue 来加上字段值。调用 record.save() 之后,记录将被创建。

这是一个简单的范例,修改了记录更新范例来创建新纪录:

/**

* AP_Name:wfdemo

* 主键码字段: 1000013

* 名称 ID

* - - - - - - - - - - - --------

* No. : 1000011

* 状态 : 1000012

*/

function setStatus(recordId, status) {

var STATUS_FIELD = 1000012; // 状态字段的字段ID

var query = db.getAPIQuery("/workflow-demo/2"); // 获取工作表的查询物件

var entry = query.insertAPIEntry(); // 创建新纪录物件

// 创建新纪录到数据库

entry.save();

}

子表格

范例链接

如果您在工作表中有子表格,您也可以使用我们的 API 来检索数据或进行编辑,像以下范例。表单看起来像这样:

这个工作流程将遍历子表格中的每一行,找到本年度的总金额(根据子表格中的日期字段)、金额最多的一年总额,并确定哪一年具有最高总额。这被设计为一个 Post-workflow,因此这三个只读字段将在记录保存后由工作流程填写。

/**

* AP_Name:wfdemo

* 主键码字段: 1000006

* 日期子表格主键码: 1000007

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* No. : 1000001

* 名称 : 1000002

* 日期 : 1000003

* 金额 : 1000004

* 本年度总额 : 1000010

* 最高年度总额 : 1000009

* 最高总额年份 : 1000008

*/

var KEY_FIELD = 1000006;

var AMOUNT_SUBTABLE_ID = 1000007;

var DATE_FIELD = 1000003;

var AMOUNT_FIELD = 1000004;

var MAX_YEAR_FIELD = 1000008;

var MAX_TOTAL_FIELD = 1000009;

var THIS_YEAR_TOTAL_FIELD = 1000010;

var query = db.getAPIQuery("/workflow-demo/1");

var entry = query.getAPIEntry(param.getNewNodeId(KEY_FIELD));

var subtableSize = entry.getSubtableSize(AMOUNT_SUBTABLE_ID);

var yearTotal = {}

for (var i = 0; i < subtableSize; i++) {

var year = parseInt(entry.getSubtableFieldValue(AMOUNT_SUBTABLE_ID, i, DATE_FIELD).substr(0, 4));

var amount = parseInt(entry.getSubtableFieldValue(AMOUNT_SUBTABLE_ID, i, AMOUNT_FIELD));

if (year in yearTotal) {

yearTotal[year] += amount;

} else {

yearTotal[year] = amount;

}

}

var maxYear;

for (var year in yearTotal) {

if (!maxYear || yearTotal[maxYear] < yearTotal[year]) {

maxYear = year;

}

}

entry.setFieldValue(MAX_YEAR_FIELD, maxYear);

entry.setFieldValue(MAX_TOTAL_FIELD, yearTotal[maxYear]);

entry.setFieldValue(THIS_YEAR_TOTAL_FIELD, yearTotal[new Date().getFullYear()]);

entry.save();

基本想法是使用 getSubtableSize(subtableId) 获取记录的子表格行数,并使用 getSubtableFieldValue(subtableId,subtableRowIndex,subtableFieldId) 检索它们的值。当您开始编辑工作流程程序时,应该能在自动生成的注释中找到子表格 ID 和字段 ID 信息。

您还可以使用 setSubtableFieldValue(subtableFieldId,subtableRootNodeId,value) 将值设置到子表格字段。subtableRootNodeId 用于指定您所指的子表格行。要查找现有子表格行的 subtableRootNodeId,您可以使用以下调用 getSubtableRootNodeId(subtableId,subtableRowIndex),它将回传包含 subtableRootNodeId 的整数。

如果需要向子表格加上一行,可以使用负数 subtableRootNodeId 例如 -100,这样所有设置到相同负数 subtableRootNodeId 的值将应用到同一新子表格行,而设置到不同负数 subtableRootNodeId 例如 -101 的值将创建具有这不同值集的另一行。

Pre-workflow 和 Post-workflow

如果您希望在 Pre-workflow 和 Post-workflow 中获取值,请参阅以下范例:

var list = param.getSubtableEntry(AMOUNT_SUBTABLE_ID);

var arr = list.toArray();

response.setStatus('WARN');

for (var i = 0; i < arr.length; i++) {

response.setMessage('日期: '+arr[i].getNewValue(DATE_FIELD)+', 金额: '+arr[i].getNewValue(AMOUNT_FIELD)+'\r\n');

}

拷贝记录

范例链接:从这里拷贝拷贝到这里

拷贝记录是我们遇到的最常见的工作流程程序之一。我们编写了一个非常简单的函数来简化这类操作。假设我们希望查看这个工作表中的一笔纪录:

透过点击单击钮,在这个工作表中生成一笔纪录:

以下是这个动作单击钮的程序代码:

/**

* AP_Name:wfdemo

* 主键码字段: 1000022

* S1 子表格主键码: 1000023

* T1 子表格主键码: 1000029

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* A : 1000014

* C : 1000015

* B : 1000016

* D : 1000017

* S1 : 1000018

* S2 : 1000019

* S3 : 1000020

* S4 : 1000021

* T1 : 1000024

* T2 : 1000025

* T3 : 1000026

*/

function copyEntry(nodeId) {

db.entryCopier(JSON.stringify({

THIS_PATH:"/workflow-demo/3",

THIS_NODEID:nodeId,

NEW_PATH:"/workflow-demo/4",

COPY:{

1000030:1000014, // A

1000031:1000015, // C

1000032:1000018, // S1

1000033:1000020 // S3

}

}),response);

}

在这里,您可以看到我们可以透过一个简单的函数调用 entryCopier 来完成拷贝操作。entryCopier 接受一个 JSON 字符串作为其参数。只需输入源工作表、目标工作表、我们正在拷贝的纪录,以及最重要的是,哪些字段应映射到哪些字段。完成映射后,您可以非常轻松地创建动作单击钮来从一个工作表拷贝记录到另一个工作表。

让我们看另一个范例。

这里,我们希望将 Lin 从 "CopyFrom" 拷贝到 "CopyTo",并将状态设置为 new。此外,我们还希望记录创建日期(请忽略本范例中的 $DATE 字段的使用)。

/**

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* From-ID : 1000001

* From-Name : 1000002

* To-ID : 1000004

* To-Name : 1000005

* 状态 : 1000007

* 登记日期 : 1000008

*/

function copyEntry(nodeId) {

db.entryCopier(JSON.stringify({

THIS_PATH:"/entrycopier/1",

THIS_NODEID:nodeId,

NEW_PATH:"/entrycopier/2",

COPY:{

// 目标字段 : 源字段

1000004:1000001,

1000005:1000002,

}

}),response);

// 获取刚才拷贝的纪录的 rootNodeId

var newEntryRootNodeId = response.getRootNodeId();

// 我们需要创建一个 ApiQuery 来查询 '/entrycopier/2'

var toApiQuery = db.getAPIQuery('/entrycopier/2');

// 获取刚才拷贝的纪录

var newEntry = toApiQuery.getAPIEntry(newEntryRootNodeId);

newEntry.setFieldValue(1000007, "New");

var current = new Date();

newEntry.setFieldValue(1000008, current.getFullYear()+'/' + (current.getMonth()+1) + '/' + current.getDate());

newEntry.save();

}

接下来,设置动作单击钮并保存。

然后,只需点击动作单击钮即可显示结果。

检查订户权限

您可以根据将要运行程序的订户所在的群组进行一些条件处理。一个订户可以在多个用户组组中,所以通常我们可以透过调用 user.isInGroup(groupName) 来判断订户是否在该用户组组中。以下是一个典型的使用范例,这段编程为 Pre-workflow,但 user 物件和 isInGroup 调用可以在所有类型的工作流程中使用,除了 Daily Workflow,它是由系统触发的。

if(!user.isInGroup('SYSAdmin')){// 检查订户是否为 SYSAdmin

response.setStatus('INVALID');// 如果不是,则不保存记录

response.setMessage('您没有权限进行此操作。');// 并显示一笔信息

}

发送电邮通知

有时候您可能希望根据一组条件发送电邮通知,或者您希望真正自订您的通知信息内容。您可以为此编写服务器端 JavaScript 工作流程。这是发送电邮的程序代码,非常简单:


// 省略...先检索记录物件

var name=entry.getFieldValue(1001426);

var email=entry.getFieldValue(1001428);

var title=entry.getFieldValue(1001386);

mailer.compose(

email, // 收件人

null, // 副本

'support@example.com', // 回覆地址

'Acme, Inc.', // 显示的发件人

title,

'嗨 '+name+',

我们已收到您的销售订单,'+

'并将很快处理您的订单。

'+

'您可以在 https://www.ragic.com/example/1 查看您的订单详情。

'+

'谢谢。


最好的祝福,

Sophia, 销售经理

Acme, Inc.'

);

// mailer.attach(myURL); // 您可以使用 .attach 来附加来自 URL 的内容

mailer.send();

请注意,如果您希望将电邮发送给多个收件人,只需用逗号分隔每个电邮地址。

对于附件,您可以使用 mailer.attach(myURL); 来附加 Ragic 上的纪录,使用记录的 URL。例如,这是 Ragic 上的纪录 URL(始终忽略哈希后的 URL):

https://www.ragic.com/wfdemo/workflow-demo/2/9

这是其 HTML 友好列印版 URL:

https://www.ragic.com/wfdemo/workflow-demo/2/9.xhtml

这是其 Excel 版本 URL:

https://www.ragic.com/wfdemo/workflow-demo/2/9.xlsx

您还可以使用邮件归并 URL,例如,cid 是邮件归并的 ID,当尝试下载邮件归并文档时,您可以在 URL 中获取 cid:

https://www.ragic.com/wfdemo/workflow-demo/2/9.custom?rn=9&cid=1

我们对您可以发送的电邮数量有限制。因此请合理发送!如果您对电邮发送配额有任何疑问,请发送电邮至 support@ragic.com

创建和撤销签核

您可以透过在工作表中加上 Post-workflow 程序来启动或撤销记录的签核。

首先,在设计模式中设置签核步骤。

现在,在 Post-workflow 中设置签核详细信息

function autoStartApprover() {

var signers = [];

signers.push({

'stepIndex':'0',

'approver':'kingjo@ragic.com',

'stepName':'START'

});

signers.push({

'stepIndex':'1',

'approver':'HR0000@hr.hr',

'stepName':'HR'

});

approval.create(JSON.stringify(signers));

}

autoStartApprover();

结果

{

'stepIndex':'0',

'approver':'kingjo@ragic.com',

'stepName':'START'

}

是您应提供的参数格式。

stepIndex :

用于指明签核的步骤,从零开始。

approver :

用于指明谁可以签核此步骤。

stepName :

用于设置签核步骤名称。

如果参数格式有误或您提供的签核人不符合设计模式中设置的规则,签核将不会创建。

在这个范例中,如果您给第二步提供参数如下:

{

'stepIndex':'1',

'approver':'kingjo@ragic.com',

'stepName':'HR'

}

那么它将失败,因为 kingjo@ragic.com 不在 HR 群组中。

我们还提供了三种特殊格式,用于根据您的公司树动态决定签核人员。您可以参阅此链接了解更多信息。

$DS :

签核人将设置为订户的直属主管。

$SS :

签核人将设置为订户主管的主管。

$DSL :

签核人将设置为前一个签核人的主管。

参数格式如下:

{

'stepIndex':'1',

'approver':'$DSL',

'stepName':''

}

当使用这些特殊格式时,您不需要提供非空的 stepName。

注意:如果特殊格式中的订户不符合您在设计模式中设置的规则,该签核将不会创建。

发送手机应用通知

除了电邮通知,您还可以发送手机应用通知。如果订户在其移动设备上安装了 iOS 应用或 Android 应用,则会向其发送通知。电邮引用的是您在 Ragic 帐户中登记的订户电邮地址。例如:

mailer.sendAppNotification("mike@example.com","测试手机通知");

如果您希望订户在点击此通知时被重定向到指定记录,您应提供要重定向到的表单路径(例如:/forms/1)和记录 ID。调用应如下所示:

mailer.sendAppNotification("mike@example.com","测试手机通知","/forms/1",12);

签核和其他记录信息

您可以首先对从 db.getAPIQuery 获取的查询物件发出以下命令,以包括完整的纪录信息:

query.setIfIncludeInfo(true);

然后您可以透过以下方式获取记录的签核信息:

entry.getFieldValue('_approve_status');// 获取当前签核状态

entry.getFieldValue('_approve_next');// 获取下一个应签核此记录的人

entry.getFieldValue('_create_date');// 获取记录的创建日期

entry.getFieldValue('_create_user');// 获取记录的创建订户电邮

签核状态将显示 F 表示已签核,REJ 表示拒绝,P 表示处理中。

显示信息

您可以像这样显示一个弹出信息。请注意,信息仅在响应状态为 "WARN" 时显示。默认情况下,响应物件中的信息将不会显示,因为通常对最终订户没有帮助。

response.setStatus('WARN');

response.setMessage(message);

调页

在本节中,我们将展示如何使用 setLimitSize 和 setLimitFrom。在这个范例中,我们总共有 20 个数据,每次取 6 个并显示信息。

/**

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* ID : 1000009

* 金额 : 1000010

*/

function limitFromExample() {

var apiQuery = db.getAPIQuery('/entrycopier/3');

// 记住偏移量

var fromNumber = 0;

apiQuery.setLimitFrom(fromNumber);

// 每次取 6 个

apiQuery.setLimitSize(6);

var resultList = apiQuery.getAPIResultList();

while(resultList.length > 0) {

var msg = '';

for(var i = 0;i < resultList.length; i++) {

var entry = resultList[i];

msg += entry.getFieldValue(1000009);

if(i != resultList.length -1) msg += ',';

}

response.setMessage(msg);

// 更新偏移量

fromNumber += resultList.length;

// 更新 apiQuery

apiQuery = db.getAPIQuery('/entrycopier/3');

apiQuery.setLimitSize(6);

apiQuery.setLimitFrom(fromNumber);

resultList = apiQuery.getAPIResultList();

}

response.setStatus('WARN');

}

数据

结果

发送 HTTP 请求

您可以向 URL 发送 HTTP GET/POST/DELETE/PUT 请求并获取回传结果:

util.getURL(String urlstring)

util.postURL(String urlstring,String postBody)

util.deleteURL(String urlstring)

util.putURL(String urlstring,String putBody)

变量 util 是预定义的。

如果您需要忽略当前 HTTP 请求的 SSL 证书检查,可以在发送请求前加上以下程序代码:

util.ignoreSSL()

此外,您可以调用 util.setHeader(String name,String value) 设置 HTTP 首部。util.removeHeader(String name) 用于移除首部。

API 参阅

此处列出的预定义系统全域变量可以直接访问,无需定义。

db.getAPIQuery

方法描述
getAPIResult()遍历查询时获取第一笔纪录
getAPIResultList()获取查询的纪录数组
getAPIEntry(int rootNodeId)通过节点 ID 获取记录
getKeyFieldId()检索此查询所在工作表的主键码字段 ID。
getFieldIdByName(String fieldName)根据指定名称获取字段 ID。如果有多个相同名称的字段,将回传第一个独立的字段 ID。
insertAPIEntry()向查询中插入新纪录,该方法回传新纪录
addFilter(int fieldId, String operand, String value)单击指定条件过滤数据
setIfIgnoreFixedFilter(boolean ifIgnoreFixedFilter)设置是否忽略目标工作表的固定过滤条件
setOrder(int orderField, int orderDir)单击指定字段 ID 和排序方向对查询数据进行排序,参数orderDir 设置为 1 表示升序排序,设置为 2 表示降序排序,设置为 3 表示次要升序排序,设置为 4 表示次要降序排序。
deleteEntry(int nodeId)通过节点 ID 删除数据
deleteEntryToRecycleBin(int nodeId)通过节点 ID 将数据删除到回收站
setLimitSize(int limitSize)默认情况下,ScriptAPIQuery 每次查询回传 1000 笔纪录,您可以使用 setLimitSize 更改每次查询回传的纪录数量。然而,我们不建议每次查询回传过多的纪录,因为这可能会占用过多内存并影响性能。我们建议使用下一个方法 setLimitFrom 进行调页。
setLimitFrom(int limitFrom)此方法用于遍历 ScriptAPIQuery 的所有记录。设置 limitFrom 将告诉 ScriptAPIQuery 从偏移量开始回传记录,以便您遍历 ScriptAPIQuery 的所有记录,因为 ScriptAPIQuery 默认每次查询回传 1000 笔纪录。您应该检查回传的纪录数量是否等于回传列表的大小,以确定是否存在下一页面。
setGetUserNameAsSelectUserValue(boolean b)设置为 false 时,查询将检索订户的电邮作为选择订户字段的值,而不是用户名称。

以下是您可以使用的操作符列表:

方法描述
getFieldValue(int fieldId)透过字段 ID 获取字段值。不包括子表格字段。
getFieldIdByName(String fieldName)透过指定名称获取字段 ID。如果有多个相同名称的字段,将回传第一个字段值。
getKeyFieldId()检索此工作表的主键码字段 ID。
getFieldValueByName(String fieldName)透过字段名称获取字段值。不包括子表格字段。如果有多个相同名称的字段,将回传第一个字段值。
getFieldValues(int fieldId)将多选字段中的所有字段值作为数组获取。不包括子表格字段。
getRootNodeId()获取数据的根节点 ID
getRootfieldId()获取数据的根字段 ID
getSubtableSize(int subtableRootfieldId)透过子表格的根字段 ID 获取子表格的大小。
getSubtableRootNodeId(int subtableRootfieldId, int rowNumber)透过子表格的根字段 ID 和子表格中的行号获取根节点 ID。
getJSON()获取整个纪录的 JSON 表示。
setFieldValue(int fieldId, String value)为指定字段设置值。对于子表格字段,您需要使用 setSubtableFieldValue()。
setFieldValue(int fieldId, String value, boolean appendValue)为多选字段设置值,参数 appendValue 必须为 true。对于子表格字段,您需要使用 setSubtableFieldValue()。
setFieldFile(int fieldId, String fileName, String fileContent)仅适用于文档上载或图形字段。将创建一个具有您提供的 fileName 和 fileContent 的文档上载并保存到指定字段。对于子表格字段,您需要使用 setSubtableFieldFile()。
setSubtableFieldValue(int fieldId, int subtableRootNodeId,String value)为子表格字段设置值,您可以透过方法 getSubtableRootNodeId 获取参数 subtableRootNodeId
setSubtableFieldValue(int fieldId, int subtableRootNodeId, String value, boolean appendValue)为多选子表格字段设置值,参数 appendValue 必须为 true
deleteSubtableRowByRowNumber(int subtableRootfieldId, int rowNumber)透过根字段 ID 和子表格中的行号删除子表格行。
deleteSubtableRowAll(int subtableRootfieldId)删除指定子表格中的所有行
deleteSubtableRow(int subtableRootfieldId, int subtableRootNodeId)透过根字段 ID 和子表格的根节点 ID 删除子表格行
loadAllLinkAndLoad()加载数据中链接和加载分配的所有加载字段的值。
recalculateAllFormulas()重新计算数据中包含公式的所有字段。
recalculateFormula(int fieldId)重新计算指定字段的公式。


注意:如果两个或多个字段共享相同的 fieldId,请改用 recalculateFormula(int fieldId, String cellName)。

recalculateFormula(int fieldId, String cellName)使用 cellName 参数确定字段的单元格位置(如 A1,C2,H21 等),重新计算指定字段的公式。此方法适用于具有相同 fieldId 的多个字段。
loadAllDefaultValues(ScriptUser user)加载设置了默认值的所有字段的值,参数 user 是预定义的。
loadDefaultValue(int fieldId, ScriptUser user)加载指定字段的默认值,参数 user 是预定义的。
lock()加锁数据
unlock()解锁数据
save()保存数据
setCreateHistory(boolean createHistory)设置数据是否需要创建历史记录
isCreateHistory()数据是否设置为创建历史记录
setIfExecuteWorkflow(boolean executeWorkflow)设置数据是否需要运行工作流程(Pre-workflow 和 Post-workflow)
setIgnoreEmptyCheck(boolean ignoreEmptyCheck)设置是否忽略不为空的字段检查
setRecalParentFormula(boolean recalParentFormula)如果此工作表是由另一工作表的子表格创建的,或者被另一工作表引用,这意味着此工作表具有父工作表,则可以调用此方法设置是否需要重新计算父工作表。
setIfDoLnls(boolean)如果该工作表链接到此工作表(源工作表),则将触发另一工作表上的同步。您应该始终在源工作表中加上此方法以触发另一工作表上的同步。

response

方法描述
getStatus()获取响应的状态。可为 SUCCESS、WARN、CONFIRM、INVALID、ERROR
setStatus(String status)设置响应的状态。可为 SUCCESS、WARN、CONFIRM、INVALID、ERROR
setMessage(String plainMessage)设置程序运行时显示的信息。此功能可多次调用,所有设置的信息将同时显示。
numOfMessages()回传已设置的信息数量。
setOpenURL(String url)仅限于已安装的工作表范围。保存编辑后将用户重定向到指定的 URL。
setOpenURLInNewTab(boolean b)设置是否在新标签页面中打开 URL。默认为 true。

user

方法描述
getEmail()获取订户的电邮地址
getUserName()获取订户的全名
isInGroup(String groupName)回传订户是否在具有 groupName 的用户组组中

mailer

方法描述
compose(String to,String cc,String from,String fromPersonal,String subject,String content)编写一封要发送的电邮信息。to 和 cc 参数可以包含多个电邮地址,只需用逗号分隔。
send()发送刚编写的信息。
sendAsync()异步发送刚编写的信息。请注意,sendAsync 每次程序运行仅能调用一次。
attach(String url)将文档附加到信息。URL 应为完整的 https:// 开头的 URL。
setSendRaw(boolean b)设置内容是否不转换为 HTML。如果内容已经是 HTML,请将其设置为 true。
sendAppNotification(String email,String message)如果订户安装了 Ragic iOS 应用或 Android 应用,向该订户发送移动应用通知。
sendAppNotification(String email,String message,String pathToForm,int nodeId)如果订户安装了 Ragic iOS 应用或 Android 应用,向该订户发送移动应用通知。订户在点击此通知时将被重定向到指定的纪录。 "pathToForm" 应为 "/forms/1" 格式,不包含帐户名,包含标签文件夹和工作表索引。

util

方法描述
getURL(String urlstring)以 GET 方法调用 URL
postURL(String urlstring,String postBody)以 POST 方法调用 URL。
deleteURL(String urlstring)以 DELETE 方法调用 URL。
putURL(String urlstring,String putBody)以 PUT 方法调用 URL。
setHeader(String name,String value)设置 HTTP 首部,将在后续的 URL 调用中使用。
ignoreSSL()忽略当前 HTTP 请求的 SSL 证书检查
removeHeader(String name)移除后续 URL 调用中使用的 HTTP 首部。
logWorkflowError(String text)在工作流程日志中记录字符串字日志信息,您可以在数据库维护页面面中找到它。

account

方法描述
getUserName(String email)根据电邮地址获取订户的全名。
getUserEmail(String userName)根据用户名称获取电邮地址。
reset()程序运行完毕后,清除所有与帐户相关的高速缓存并重新加载页面面。
getTimeZoneOffset()获取此帐户的时区时差,以毫秒为单元。
getTimeZoneOffsetInHours()获取此帐户的时区时差,以小时为单元。

param

这是订户在请求保存到数据库之前提交的订户请求物件。特别适用于编写 Pre-workflow 程序时。

方法描述
getUpdatedEntry()仅适用于 Post-workflow。回传刚创建或更新的纪录。
getNewNodeId(int fieldId)回传指定字段的新值写入后的节点 ID(整数)。
getOldNodeId(int fieldId)回传指定字段的新值写入前的节点 ID(整数)。
getNewValue(int fieldId)回传指定字段的新值写入后的值。
getOldValue(int fieldId)回传指定字段的新值写入前的值。
getNewValues(int fieldId)类似于 getNewValue,但可以同时访问多个值,这在处理多选字段时非常有用。
getOldValues(int fieldId)类似于 getOldValue,但可以同时访问多个值,这在处理多选字段时非常有用。
getSubtableEntry(int fieldId)回传一个参数列表,可以操作子表格中的每笔纪录。
isCreateNew()回传数据是否新创建。

approval

方法描述
create(String[] wfSigner)

仅适用于 Post-workflow。

wfSigner 是一个包含特定 JSON 格式物件的数组。

{

'stepIndex' : 签核的步骤 - 从 0 开始,

'approver' : 签核人的电邮

'stepName' : 签核人的姓名或职称

}

范例 "单步骤签核人":

wfSigner push({

'stepIndex':'1',

'approver':'kingjo@ragic.com',

'stepName':'Jo'

})

请注意,wfSigner 应满足您在设计模式中设置的签核。

例如,如果在设计模式中的第二步仅有 "HR00@gmail.com" 一个候选人,您应提供一个包含 approver: HR00@gmail.com 和 stepIndex : 1 的 JSON。

cancel()仅适用于 Post-workflow。撤销数据中的签核。

approvalParam

方法描述
getEntryRootNodeId()获取数据的根节点 ID
getApprovalAction()获取签核的操作。可为 CREATE、APPROVE、FINISH、CANCEL、REJECT

动作单击钮

动作单击钮是运行 JavaScript Workflow 最常见且最简洁的方式,通常是我们的首选建议。您可以在表单中编写程序,并分配一个动作单击钮,当订户点击显示在右下角“动作”面板中的单击钮时,运行这段程序。

要加上动作单击钮程序,只需右键点击一个表单,然后选择JavaScript Workflow

并从顶部下拉菜单中选择Installed Sheet Scope

然后进入您的表单设计页面面,加上一个动作单击钮,类型为JS Workflow,并引用您编写的 JavaScript 函数。

请注意,您可以透过在函数调用的参数中使用 {id} 传递当前记录的纪录 ID,例如:

setStatus({id})

当然,我们将在后续部分中详细介绍如何编写这些函数。

Post-workflow

Post-workflows 在记录保存后立即运行。使用 Post-workflow,自动化您想要对刚保存的纪录进行的更改(无法使用公式完成的更改)非常方便。或者,您可以修改其他相关表单上的纪录,例如更新库存余额。

要加上 Post-workflow,只需右键点击一个表单,然后选择JavaScript Workflow

并从顶部下拉菜单中选择Post-workflow

一个典型的 Post-workflow 可能看起来像这样:

var recordId = param.getNewNodeId(key_field_id_of_form);

var query = db.getAPIQuery(path_to_form);

var record = query.getAPIEntry(id);

// 对检索到的纪录进行操作

请参阅我们的API 参阅和本文档的其他部分以了解可以运行的操作列表。

还请注意,如果您在列表页面面上修改数据,则不会运行 Post-workflow。

Pre-workflow

Pre-workflows 在记录保存之前运行,因此可以用作检查工具,将输入数据与数据库中的数据进行比对。一般来说,大多数检查可以使用前端正则表达式检查或自由文本字段的唯一复选框来完成。但对于更复杂的后端检查,有时需要使用 Pre-workflow。

要加上 Pre-workflow,只需右键点击一个表单,然后选择JavaScript Workflow

并从顶部下拉菜单中选择Pre-workflow

以下是一个简单范例:

假设我们有一个列表,

我们希望确保保存的价格不为负数。

/**

* 主键码字段: 1000004

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* ID : 1000001

* 价格 : 1000002

* 名称 : 1000003

* 是否可用 : 1000005

*/

function log(str) {

// 设置状态为 'INVALID' 或 'ERROR' 以撤销保存。

response.setStatus('INVALID');

response.setMessage(str);

}

function ifThePriceIsNegative() {

// 获取要保存的价格。

var newPrice = param.getNewValue(1000002);

// 将 newPrice 字符串转换为整数。

if(parseInt(newPrice) < 0) {

return true;

}

}

// 如果价格为负数,则不保存。

if(ifThePriceIsNegative()) {

log('价格为负数!!');

}

现在尝试保存负数价格,我们会得到

值得注意的是,在 Ragic 中编写 Pre-workflow 时,不能使用 entry.getFieldValue(因为 Ragic 还没有保存)。请尝试使用 param 来获取旧值和新值。

Daily Workflow

Daily Workflows 每天运行一次。这对于需要每天更新结果的修改非常有用,例如根据当前日期更新公式结果。

要加上 Daily Workflow,只需右键点击一个标签,然后选择Global Javascript Workflow

然后从顶部下拉菜单中选择Daily Workflow

默认情况下,Daily Workflow 在 UTC 19:00 运行。您可以在公司设置中更改运行时间和时区:

1. 前往帐户设置

2. 点击公司设置

3. 选择公司当地时区Daily Workflow 运行时间并保存。

如果您的公司设置中没有公司当地时区Daily Workflow 运行时间,请联络我们来为您更新。

Approval Workflow

Approval Workflows 在签核创建、签核、拒绝、撤销或完成后立即运行。

要加上 Post-workflow,只需右键点击一个表单,然后选择JavaScript Workflow

然后从顶部下拉菜单中选择Approval Workflow

您可以透过以下方式获取记录 ID:

var recordId = approvalParam.getEntryRootNodeId();

approvalParam 是签核工作流程范围内的预定义变量。


您可以透过以下方式获取签核动作:

var action = approvalParam.getApprovalAction();

获取上述数据后,您可以单击照以下方式自订需求:

var query = db.getAPIQuery(path_to_form);

var entry = query.getAPIEntry(recordId);

if (action === 'CANCEL') {

entry.setFieldValue(STATUS_FIELD, "签核已撤销!");

}else if (action === 'FINISH') {

entry.setFieldValue(STATUS_FIELD, "签核已完成!");

}else if (action === 'CREATE') {

entry.setFieldValue(STATUS_FIELD, "签核已创建!");

}else if (action === 'REJECT') {

entry.setFieldValue(STATUS_FIELD, "签核被拒绝!");

}else {

entry.setFieldValue(STATUS_FIELD, "签核已通过!");

}

entry.save();

Global Workflow

Global Workflow 是您可以编写 JavaScript Workflow 模块的地方,其他工作流程函数可以引用它。它不会自行运行,但可以在上述的任何类型的工作流程中引用。这是一个放置您可能需要在多个表单中重复使用的程序的好地方。

要加上 Global Workflow,只需右键点击一个标签,然后选择Global Javascript Workflow

获取记录

有两种不同的方法来获取订户正在查看的当前记录(适用于动作单击钮)或订户刚刚保存的纪录(适用于 Pre-workflow 和 Post-workflow)。

动作单击钮

表单页面面的动作单击钮透过分配动作单击钮来调用您在已安装表单范围内定义的函数。当您定义动作单击钮调用的函数时,您可以传递参数 {id},这是点击动作单击钮所在记录的 ID,将其作为工作流程中的参数。

您可以在动作单击钮工作流程中查看范例。

Pre-workflow

您可以透过以下方式获取记录 ID:

var recordId = param.getNewNodeId(key_field_id_of_form);

param 是预定义变量,您可以在 Pre-workflow 和 Post-workflow 中使用它。


获取记录 ID 后,这是获取记录(数据)的方式:

var query = db.getAPIQuery(path_to_form);

var entry = query.getAPIEntry(id);

Post-workflow

对于 Post-workflow,您可以使用上述方法,就像在 Pre-workflow 中一样。但也有一种方便的方法来检索刚刚保存的纪录:

var entry=param.getUpdatedEntry();

如果表单页面面上有屏蔽字段,默认情况下,您将获取屏蔽值。您可以透过以下方式获取未屏蔽值:

var query = db.getAPIQuery(path_to_form);

query.setUpdateMode();

query.setIgnoreAllMasks(true); // 撤销所有屏蔽字段的屏蔽。

var entry = query.getAPIEntry(id);

您可以使用 query.addIgnoreMaskDomain(fieldId_of_the_masked_field) 代替 query.setIgnoreAllMasks(true) 来撤销特定字段的屏蔽。

在后续部分中有更多关于如何更新纪录的介绍。

如果您想过滤多笔纪录,请参阅关于过滤的部分。

查询数据

如果您想透过过滤条件获取多笔纪录:

var query = db.getAPIQuery("/workflow-demo/1");

query.addFilter(1000002, '=', 'Green');

query.addFilter(1000008, '=', '2017');

var results = query.getAPIResultList();

for (var i = 0; i < results.length; i++) {

var entry = results[i];

// ...

}

您可以使用 addFilter(fieldId, operator, value) 来加上过滤条件,并使用 getAPIResultList() 来获取记录列表。

以下是您可以使用的操作符列表:

操作符名称 操作符值
等于 =
正则表达式 regex
大于或等于
小于或等于 <=
大于
小于 <</td>
包含 like

请注意,当您透过日期或日期时间进行过滤时,它们需要以下列格式表示:yyyy/MM/ddyyyy/MM/dd HH:mm:ss

您还可以透过调用 setFullTextSearch(String queryTerm) 来使用全文搜索作为查询过滤条件,而不是 addFilter()。

更新纪录

范例链接

让我们从一个简单的范例开始,检索当前记录作为物件,使用单击钮更新其值,然后将其保存回数据库。以下是范例表单的外观:

我们希望设计一些单击钮,通过点击单击钮运行简单的服务器端 JavaScript Workflow 来更改我们的状态字段值。以下是单击钮后面的程序代码:

/**

* AP_Name:wfdemo

* 主键码字段: 1000013

* 名称 ID

* - - - - - - - - - - - --------

* No. : 1000011

* 状态 : 1000012

*/

function setStatus(recordId, status) {

var STATUS_FIELD = 1000012; // 状态字段的字段ID

var query = db.getAPIQuery("/workflow-demo/2"); // 获取工作表的查询物件

var entry = query.getAPIEntry(recordId); // 获取当前记录的物件

// 设置当前记录的状态值

if (status) {

entry.setFieldValue(STATUS_FIELD, status);

}

else { // 用于切换

var newStatus = entry.getFieldValue(STATUS_FIELD) == 'On' ? 'Off' : 'On'; // 获取字段的当前值

entry.setFieldValue(STATUS_FIELD, newStatus);

}

// 保存记录到数据库

entry.save();

}

在编写 JavaScript Workflow 时,变量 db 是预定义的,您可以在任何地方参阅它。通常,我们会调用方法 getAPIQuery(pathName) 来获取工作表的查询物件。

然后,您可以透过 getAPIEntry(recordId) 获取工作表物件中的纪录,并调用 setFieldValue(fieldId,value) 为字段设置值,或调用 getFieldValue(fieldId) 从记录中检索值。

请注意,在加上日期值时,必须以下列格式之一:

yyyy/MM/dd

yyyy/MM/dd HH:mm:ss

HH:mm:ss

如果您从多选字段中检索值,这些字段可能有多个值,请使用 getFieldValues(fieldId) 以数组形式检索所有值。您还可以在末尾加上额外的 true 参数来调用 setFieldValue(fieldId,value,true),以指定您正在“加上”选项到当前值列表中,而不是覆盖现有值。请注意,这些操作仅适用于多选字段。

如果您想拷贝多选字段的值并覆盖另一个多选字段中的值,您不能仅仅使用 getFieldValues(fieldId)setFieldValue(fieldId,value,true)。以下是您可以参阅的程序代码:


var multipleSelectionFieldValue = entry.getFieldValues(1013251); // 1013251 是多选字段

var targetMultipleSelectionField = "";

for (var i = 0; i < multipleSelectionFieldValue.length; i++) {

if (i == 0) {

targetMultipleSelectionField = targetMultipleSelectionField + multipleSelectionFieldValue[i];

}

else {

targetMultipleSelectionField = targetMultipleSelectionField + "|" + multipleSelectionFieldValue[i];

}

}

entry.setFieldValue(1013252, targetMultipleSelectionField, false); // 1013251 是另一个多选字段

请注意,您需要检索每个选项,并将这些选项格式化为一个垂直条(|),就像从 Excel 或 CSV 文档中导入现有数据一样。

如果您设置值到文档上载字段,可以使用 setFieldFile(int fieldId, String fileName, String fileContent) 来创建一个具有 fileName 和 fileContent 的文档上载。Ragic 然后将此文档保存到该字段,以便在订户界面上下载。

完成后,只需调用 save() 方法保存记录到数据库。

创建记录

创建记录与更新纪录非常相似。与调用 query.getAPIEntry() 相比,调用 query.insertAPIEntry()。与 getAPIEntry() 一样,它也将回传一个纪录,您可以使用 setFieldValue 加上字段值。调用 record.save() 后将创建记录。

对记录更新范例进行简单修改,如下所示将创建一个新纪录:

/**

* AP_Name:wfdemo

* 主键码字段: 1000013

* 名称 ID

* - - - - - - - - - - - --------

* No. : 1000011

* 状态 : 1000012

*/

function setStatus(recordId, status) {

var STATUS_FIELD = 1000012; // 状态字段的字段 ID

var query = db.getAPIQuery("/workflow-demo/2"); // 获取工作表的查询物件

var entry = query.insertAPIEntry(); // 创建一个新纪录物件

// 将新纪录保存到数据库

entry.save();

}

子表格

范例链接

如果工作表中有子表格,您也可以使用 API 从中检索数据或进行编辑,如以下范例所示。表单看起来像这样:

该工作流程将遍历子表格中的每一行,找出今年的总金额(根据子表格中的日期字段),总金额最多的年份,以及确定哪一年总金额最高。这是一个 Post-workflow,当记录保存后,这三个只读字段将由工作流程填写。

/**

* AP_Name:wfdemo

* 主键码字段: 1000006

* 日期子表格主键码: 1000007

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* No. : 1000001

* 名称 : 1000002

* 日期 : 1000003

* 金额 : 1000004

* 今年总金额 : 1000010

* 年度最大总金额 : 1000009

* 年度最大总金额年份 : 1000008

*/

var KEY_FIELD = 1000006;

var AMOUNT_SUBTABLE_ID = 1000007;

var DATE_FIELD = 1000003;

var AMOUNT_FIELD = 1000004;

var MAX_YEAR_FIELD = 1000008;

var MAX_TOTAL_FIELD = 1000009;

var THIS_YEAR_TOTAL_FIELD = 1000010;

var query = db.getAPIQuery("/workflow-demo/1");

var entry = query.getAPIEntry(param.getNewNodeId(KEY_FIELD));

var subtableSize = entry.getSubtableSize(AMOUNT_SUBTABLE_ID);

var yearTotal = {};

for (var i = 0; i < subtableSize; i++) {

var year = parseInt(entry.getSubtableFieldValue(AMOUNT_SUBTABLE_ID, i, DATE_FIELD).substr(0, 4));

var amount = parseInt(entry.getSubtableFieldValue(AMOUNT_SUBTABLE_ID, i, AMOUNT_FIELD));

if (year in yearTotal) {

yearTotal[year] += amount;

} else {

yearTotal[year] = amount;

}

}

var maxYear;

for (var year in yearTotal) {

if (!maxYear || yearTotal[maxYear] < yearTotal[year]) {

maxYear = year;

}

}

entry.setFieldValue(MAX_YEAR_FIELD, maxYear);

entry.setFieldValue(MAX_TOTAL_FIELD, yearTotal[maxYear]);

entry.setFieldValue(THIS_YEAR_TOTAL_FIELD, yearTotal[new Date().getFullYear()]);

entry.save();

基本思路是使用 getSubtableSize(subtableId) 获取记录的行数,并使用 getSubtableFieldValue(subtableId,subtableRowIndex,subtableFieldId) 检索其值。您应该能够在开始编辑工作流程程序时,在自动生成的注释中找到子表格 ID 和字段 ID 信息。

您还可以使用 setSubtableFieldValue(subtableFieldId,subtableRootNodeId,value) 为子表格设置值。子表格的 subtableRootNodeId 用于指定您指的是哪一行子表格。要找到现有子表格行的 subtableRootNodeId,您可以使用以下调用 getSubtableRootNodeId(subtableId,subtableRowIndex),它将回传一个包含子表格根节点 ID 的整数。

如果您需要向子表格加上一行,可以使用负数的 subtableRootNodeId,例如 -100,这样,设置为相同负数 subtableRootNodeId 的所有值将应用到同一行子表格中,而设置为不同负数 subtableRootNodeId 的值,如 -101,将在子表格中创建一个不同的行。

Pre-workflow 和 Post-workflow

如果您想在 Pre-workflow 和 Post-workflow 中获取值,请参阅以下范例:

var list = param.getSubtableEntry(AMOUNT_SUBTABLE_ID);

var arr = list.toArray();

response.setStatus('WARN');

for (var i = 0; i < arr.length; i++) {

response.setMessage('日期 : '+arr[i].getNewValue(DATE_FIELD)+', 金额 : '+arr[i].getNewValue(AMOUNT_FIELD)+'\r\n');

}

拷贝记录

范例链接:拷贝自拷贝到

拷贝记录是我们经常遇到的最常见的工作流程之一。我们编写了一个非常简单的函数来简化此类操作。假设我们希望看到此表单上的一个纪录:

点击单击钮,生成此表单上的一个纪录:

这是此动作单击钮的程序代码:

/**

* AP_Name:wfdemo

* 主键码字段: 1000022

* S1 子表格主键码: 1000023

* T1 子表格主键码: 1000029

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* A : 1000014

* C : 1000015

* B : 1000016

* D : 1000017

* S1 : 1000018

* S2 : 1000019

* S3 : 1000020

* S4 : 1000021

* T1 : 1000024

* T2 : 1000025

* T3 : 1000026

*/

function copyEntry(nodeId) {

db.entryCopier(JSON.stringify({

THIS_PATH:"/workflow-demo/3",

THIS_NODEID:nodeId,

NEW_PATH:"/workflow-demo/4",

COPY:{

1000030:1000014, // A

1000031:1000015, // C

1000032:1000018, // S1

1000033:1000020 // S3

}

}),response);

}

如您所见,我们可以透过一个简单的函数调用 entryCopier 来完成拷贝操作。entryCopier 接受一个 JSON 字符串作为参数。只需写下源工作表、目标工作表、我们正在拷贝的纪录,以及最重要的,哪些字段应映射到哪些字段。完成映射后,您可以非常轻松地创建动作单击钮来将记录从一个表单拷贝到另一个表单。

让我们看另一个范例。

在这里,我们希望将 "Lin" 从 "CopyFrom" 拷贝到 "CopyTo" 并将状态设置为新建。此外,我们还希望记录创建日期(请忽略本范例中 $DATE 字段的使用)。

/**

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* From-ID : 1000001

* From-Name : 1000002

* To-ID : 1000004

* To-Name : 1000005

* 状态 : 1000007

* 登记日期 : 1000008

*/

function copyEntry(nodeId) {

db.entryCopier(JSON.stringify({

THIS_PATH:"/entrycopier/1",

THIS_NODEID:nodeId,

NEW_PATH:"/entrycopier/2",

COPY:{

// to : from

1000004:1000001,

1000005:1000002,

}

}),response);

// 获取拷贝之前的数据的 rootNodeId。

var newEntryRootNodeId = response.getRootNodeId();

// 我们需要创建一个 ApiQuery 来搜索 '/entrycopier/2'

var toApiQuery = db.getAPIQuery('/entrycopier/2');

// 获取拷贝之前的数据

var newEntry = toApiQuery.getAPIEntry(newEntryRootNodeId);

newEntry.setFieldValue(1000007, "New");

var current = new Date();

newEntry.setFieldValue(1000008, current.getFullYear()+'/' + (current.getMonth()+1) + '/' + current.getDate());

newEntry.save();

}

接下来,设置动作单击钮并保存。

然后,只需点击动作单击钮即可显示结果。

检查订户访问权限

您可以根据将要运行程序的订户所属的群组进行一些条件处理。订户可以属于多个用户组组,因此通常我们可以调用 user.isInGroup(groupName) 来确定订户是否在此用户组组中。以下是一个典型的使用范例,以下程序代码设计为 Pre-workflow,但 user 物件和 isInGroup 调用可在除 Daily Workflow 之外的所有类型工作流程中使用,因为 Daily Workflow 是由系统触发的。

if(!user.isInGroup('SYSAdmin')){// 检查订户是否为 SYSAdmin

response.setStatus('INVALID');// 如果不是,则不保存记录

response.setMessage('您没有运行此操作的访问权限。');// 并显示一笔信息

}

发送电邮通知

有时候,您可能需要根据一组条件发送电邮通知,或者您希望真正自订通知信息内容。您可以编写服务器端 JavaScript Workflow 来实现此目的。这是您将用来发送电邮的程序,非常简单:


// 省略...首先检索记录物件

var name=entry.getFieldValue(1001426);

var email=entry.getFieldValue(1001428);

var title=entry.getFieldValue(1001386);

mailer.compose(

email, // 收件人

null, // 副本

'support@example.com', // 回覆地址

'Acme, Inc.', // 显示的发件人

title,

'您好 '+name+',

我们已收到您的销售订单,'+

'并将很快处理您的订单。

'+

'您可以在 https://www.ragic.com/example/1 查看您的订单详情。

'+

'谢谢。


此致

销售经理 Sophia

Acme, Inc.'

);

// mailer.attach(myURL); // 您可以使用 .attach 从 URL 附加内容

mailer.send();

请注意,如果您想向多个收件人发送电邮,只需用逗号分隔每个电邮地址。

对于附件,您可以使用 mailer.attach(myURL); 透过使用记录的 URL 附加 Ragic 上的纪录。例如,这是 Ragic 上的一个纪录 URL(始终忽略哈希后的 URL):

https://www.ragic.com/wfdemo/workflow-demo/2/9

这是其 HTML 友好列印版本的 URL:

https://www.ragic.com/wfdemo/workflow-demo/2/9.xhtml

这是其 Excel 版本的 URL:

https://www.ragic.com/wfdemo/workflow-demo/2/9.xlsx

您还可以使用归并 URL,例如,cid 是归并文档的 id,您可以在尝试下载归并文档时在 URL 中找到 cid:

https://www.ragic.com/wfdemo/workflow-demo/2/9.custom?rn=9&cid=1

我们确实对您可以发送的电邮数量施加了一些限制。所以请合理地发送!如果您对电邮发送配额有任何疑问,请发送电邮至 support@ragic.com

创建和撤销签核

您可以透过在表单中加上 Post-workflow 程序来启动或撤销记录的签核。

首先,我们在设计模式中设置签核步骤。

现在在 Post-workflow 中设置签核详情

function autoStartApprover() {

var signers = [];

signers.push({

'stepIndex':'0',

'approver':'kingjo@ragic.com',

'stepName':'START'

});

signers.push({

'stepIndex':'1',

'approver':'HR0000@hr.hr',

'stepName':'HR'

});

approval.create(JSON.stringify(signers));

}

autoStartApprover();

结果

{

'stepIndex':'0',

'approver':'kingjo@ragic.com',

'stepName':'START'

}

是您应提供的参数格式。

stepIndex

用于知道设置的是哪一步签核,从零开始。

approver

用于知道谁可以签署这一步签核。

stepName

用于设置签核步骤名称。

如果参数格式有误或提供的签核人不符合设计模式中设置的规则,签核将无法创建。

在这个范例中,如果您提供如下参数的第二步:

{

'stepIndex':'1',

'approver':'kingjo@ragic.com',

'stepName':'HR'

}

这种情况下会失败,因为 kingjo@ragic.com 不在 HR 群组中。

我们还提供 3 种特殊格式,用于根据您的公司树动态决定签核人。

您可以查看这里以获取更多信息。

$DS

签核人将设置为订户的直属主管。

$SS

签核人将设置为订户的主管的主管。

$DSL

签核人将设置为上一个签核人的主管。

参数格式如下

{

'stepIndex':'1',

'approver':'$DSL',

'stepName':''

}

使用这些特殊格式时,您不必提供非空的 stepName。

注意:如果特殊格式中的订户不符合设计模式中设置的规则,该签核人将无法创建。

发送移动应用通知

除了电邮通知,您还可以发送移动应用通知。如果订户在其移动设备上安装了 iOS 应用或 Android 应用,将向其发送通知。电邮是指订户在您的 Ragic 帐户中登记的电邮地址。例如:

mailer.sendAppNotification("mike@example.com","测试移动通知");

如果您希望订户在点击此通知时被重定向到指定记录,应提供要重定向到的表单路径(例如:/forms/1)和记录 ID。调用应如下所示:

mailer.sendAppNotification("mike@example.com","测试移动通知","/forms/1",12);

记录上的签核人和其他信息

您可以首先向从 db.getAPIQuery 获取的查询物件发出以下命令,以包含完整的纪录信息:

query.setIfIncludeInfo(true);

然后您可以透过以下方式获取记录的签核信息:

entry.getFieldValue('_approve_status');// 获取当前签核状态

entry.getFieldValue('_approve_next');// 获取下一个应签署此记录的人

entry.getFieldValue('_create_date');// 获取记录的创建日期

entry.getFieldValue('_create_user');// 获取记录的创建订户电邮

签核状态将为 F 代表已签核,REJ 代表拒绝,P 代表处理中。

显示信息

您可以像这样在弹出窗口中显示信息。请注意,仅当响应状态为“WARN”时,信息才会显示。默认情况下,响应物件内的信息不会显示,因为通常对最终订户没有帮助。

response.setStatus('WARN');

response.setMessage(message);

调页

本节中,我们将展示如何使用 setLimitSize 和 setLimitFrom。范例中,我们总共有 20 数据录,每次取 6 笔显示信息。

/**

* 字段名称 字段 ID

* - - - - - - - - - - - --------

* ID : 1000009

* 金额 : 1000010

*/

function limitFromExample() {

var apiQuery = db.getAPIQuery('/entrycopier/3');

// 记住偏移量

var fromNumber = 0;

apiQuery.setLimitFrom(fromNumber);

// 每次取 6 笔

apiQuery.setLimitSize(6);

var resultList = apiQuery.getAPIResultList();

while(resultList.length > 0) {

var msg = '';

for(var i = 0;i < resultList.length; i++) {

var entry = resultList[i];

msg += entry.getFieldValue(1000009);

if(i != resultList.length -1) msg += ',';

}

response.setMessage(msg);

// 更新偏移量

fromNumber += resultList.length;

// 更新 apiQuery

apiQuery = db.getAPIQuery('/entrycopier/3');

apiQuery.setLimitSize(6);

apiQuery.setLimitFrom(fromNumber);

resultList = apiQuery.getAPIResultList();

}

response.setStatus('WARN');

}

数据

结果

发送 HTTP 请求

您可以向 URL 发送 HTTP GET/POST/DELETE/PUT 请求并获取回传结果:

util.getURL(String urlstring)

util.postURL(String urlstring,String postBody)

util.deleteURL(String urlstring)

util.putURL(String urlstring,String putBody)

变量 util 是预定义的。

如果您需要为当前的 HTTP 请求忽略 SSL 证书检查,可以在发送请求之前加上以下程序代码:

util.ignoreSSL()

此外,您可以调用 util.setHeader(String name,String value) 设置 HTTP 首部。util.removeHeader(String name) 移除首部。

API 参阅

这里列出了可以直接访问的预定义系统全域变量。

db.getAPIQuery

方法描述
getAPIResult()遍历查询时获取第一笔纪录
getAPIResultList()获取查询的纪录数组
getAPIEntry(int rootNodeId)透过节点 ID 获取记录
getKeyFieldId()检索此查询所在工作表的主键码字段 ID。
getFieldIdByName(String fieldName)透过指定名称获取字段 ID。如果有多个相同名称的字段,将回传第一个独立字段 ID。
insertAPIEntry()向查询中插入新纪录,方法回传新纪录
addFilter(int fieldId, String operand, String value)透过指定条件过滤记录
setIfIgnoreFixedFilter(boolean ifIgnoreFixedFilter)设置是否忽略目标工作表的固定过滤条件
setOrder(int orderField, int orderDir)透过指定字段 ID 和排序方向对查询结果进行排序,参数 orderDir 设置为 1 则升序排序,设置为 2 则降序排序,设置为 3 则二级升序排序,设置为 4 则二级降序排序。
deleteEntry(int nodeId)透过节点 ID 删除记录
deleteEntryToRecycleBin(int nodeId)透过节点 ID 删除记录到回收站
setLimitSize(int limitSize)默认情况下,ScriptAPIQuery 每次查询回传 1000 笔纪录,您可以使用 setLimitSize 更改每次查询回传的纪录数量。但是,我们不建议每次查询回传太多记录,因为这可能会占用过多内存并对性能生成不良影响。我们建议使用下一个方法 setLimitFrom 进行调页。
setLimitFrom(int limitFrom)此方法用于通过所有记录进行调页。设置 limitFrom 将告诉 ScriptAPIQuery 从偏移量开始回传记录,以便您可以通过所有记录调页,因为默认情况下,ScriptAPIQuery 每次查询回传 1000 笔纪录。如果回传的纪录数量等于回传列表的大小,则应检查下一页面。
setGetUserNameAsSelectUserValue(boolean b)设置为 false 时,查询将检索选择订户字段的订户电邮,而不是用户名称。

这是您可以使用的操作符列表:

操作符名称 操作符值
等于 =
正则表达式 regex
大于或等于
小于或等于 <=
大于
小于 <</td>
包含 like

请注意,当您透过日期或日期时间进行过滤时,它们需要以下列格式表示:yyyy/MM/ddyyyy/MM/dd HH:mm:ss

您还可以透过调用 setFullTextSearch(String queryTerm) 来使用全文搜索作为查询过滤条件,而不是 addFilter()。

db.getAPIQuery 记录

方法描述
getFieldValue(int fieldId)透过字段 ID 获取字段值。不包括子表格字段。
getFieldIdByName(String fieldName)透过指定名称获取字段 ID。如果有多个相同名称的字段,将回传第一个独立字段 ID。
getKeyFieldId()检索此工作表的主键码字段 ID。
getFieldValueByName(String fieldName)透过字段名称获取字段值。不包括子表格字段。如果有多个相同名称的字段,将回传第一个字段值。
getFieldValues(int fieldId)以数组形式获取多选字段的所有字段值。不包括子表格字段。
getRootNodeId()获取记录的根节点 ID
getRootfieldId()获取记录的根字段 ID
getSubtableSize(int subtableRootfieldId)透过子表格根字段 ID 获取子表格的大小。
getSubtableRootNodeId(int subtableRootfieldId, int rowNumber)透过子表格根字段 ID 和子表格中的行号获取子表格的根节点 ID。
getJSON()获取整个纪录的 JSON 表示。
setFieldValue(int fieldId, String value)为指定字段设置值。对于子表格字段,需要使用 setSubtableFieldValue();
setFieldValue(int fieldId, String value, boolean appendValue)为多选字段设置值,参数 appendValue 需要为 true。对于子表格字段,需要使用 setSubtableFieldValue();
setFieldFile(int fieldId, String fileName, String fileContent)仅适用于文档上载或图形字段。将创建一个包含您提供的 fileName 和 fileContent 的文档上载并保存到指定字段。对于子表格字段,需要使用 setSubtableFieldFile();
setSubtableFieldValue(int fieldId, int subtableRootNodeId,String value)为子表格字段设置值,您可以透过方法 getSubtableRootNodeId 获取参数 subtableRootNodeId
setSubtableFieldValue(int fieldId, int subtableRootNodeId, String value, boolean appendValue)为多选字段设置值,参数 appendValue 需要为 true
deleteSubtableRowByRowNumber(int subtableRootfieldId, int rowNumber)透过子表格根字段 ID 和子表格中的行号删除子表格行。
deleteSubtableRowAll(int subtableRootfieldId)删除指定子表格中的每一行
deleteSubtableRow(int subtableRootfieldId, int subtableRootNodeId)透过子表格根字段 ID 和子表格根节点 ID 删除子表格行。
loadAllLinkAndLoad()加载数据中链接和加载分配的所有已加载字段的值。
recalculateAllFormulas()重新计算数据中包含公式的所有字段。
recalculateFormula(int fieldId)重新计算指定字段的公式。
注意:如果两个或多个字段共享相同的 fieldId,请使用 recalculateFormula(int fieldId, String cellName) 代替。
recalculateFormula(int fieldId, String cellName)透过 cellName 参数确定字段的单元格位置(例如 A1、C2、H21 等)重新计算指定字段的公式。此方法适用于具有两个或多个相同 fieldId 的工作表。
loadAllDefaultValues(ScriptUser user)加载设置了默认值的所有字段的值,参数 user 是预定义的。
loadDefaultValue(int fieldId, ScriptUser user)加载指定字段的默认值,参数 user 是预定义的。
lock()加锁数据
unlock()解锁数据
save()保存数据
setCreateHistory(boolean createHistory)设置数据是否需要创建历史记录
isCreateHistory()数据是否设置为创建历史记录
setIfExecuteWorkflow(boolean executeWorkflow)设置数据是否需要运行工作流程(Pre-workflow 和 Post-workflow)
setIgnoreEmptyCheck(boolean ignoreEmptyCheck)设置是否忽略不为空的字段检查
setRecalParentFormula(boolean recalParentFormula)如果此工作表是由另一个工作表的子表格创建的,或者是被另一个工作表引用的,这意味着此工作表有父工作表,则您可以调用此方法设置是否要重新计算父工作表。
setIfDoLnls(boolean)如果该表单链接到此表单,则将触发已同步的值同步到其他表单。您应始终在源表单中加上此方法以触发同步到其他表单。

response

方法描述
getStatus()获取响应的状态。可为 SUCCESS、WARN、CONFIRM、INVALID、ERROR
setStatus(String status)设置响应的状态。可为 SUCCESS、WARN、CONFIRM、INVALID、ERROR
setMessage(String plainMessage)设置运行程序后显示的信息。此功能可以多次调用,所有设置的信息将同时显示。
numOfMessages()回传已设置的信息数量。
setOpenURL(String url)仅限已安装表单范围。保存编辑后将订户重定向到指定的 URL。
setOpenURLInNewTab(boolean b)设置在打开 URL 时是否在新标签页面中打开。默认为 true。

user

方法描述
getEmail()获取订户的电邮地址
getUserName()获取订户的全名
isInGroup(String groupName)回传订户是否在名称为 groupName 的用户组组中

mailer

方法描述
compose(String to,String cc,String from,String fromPersonal,String subject,String content)编写要发送的电邮信息。参数 to 和 cc 可以包含多个电邮地址,只需用逗号分隔。
send()发送刚编写的信息。
sendAsync()异步发送刚编写的信息。请注意,每次程序运行只能调用一次 sendAsync。
attach(String url)将文档附加到信息中。URL 应为包含 https:// 的完整 URL。
setSendRaw(boolean b)设置内容是否不转换为 HTML。如果您的内容已经是 HTML,请将此设置为 true。
sendAppNotification(String email,String message)如果订户已安装 Ragic iOS 应用或 Android 应用,则向该订户发送移动应用通知。
sendAppNotification(String email,String message,String pathToForm,int nodeId)如果订户已安装 Ragic iOS 应用或 Android 应用,则向该订户发送移动应用通知。订户点击此通知时将重定向到指定记录。“pathToForm”应以 /forms/1 格式,不包括帐户名称,包含标签文件夹和工作表索引。

util

方法描述
getURL(String urlstring)透过 GET 方法调用 URL
postURL(String urlstring,String postBody)透过 POST 方法调用 URL。
deleteURL(String urlstring)透过 DELETE 方法调用 URL。
putURL(String urlstring,String putBody)透过 PUT 方法调用 URL。
setHeader(String name,String value)设置将在随后的 URL 调用中使用的 HTTP 首部。
ignoreSSL()忽略当前 HTTP 请求的 SSL 证书检查
removeHeader(String name)从随后的 URL 调用中移除 HTTP 首部。
logWorkflowError(String text)在工作流程日志中记录字符串文本信息,您可以在数据库维护页面面中找到它。

account

方法描述
getUserName(String email)透过电邮地址获取订户的全名。
getUserEmail(String userName)获取指定用户名称的电邮地址。
reset()在程序和重新加载页面面运行完成后清除所有帐户相关的高速缓存。
getTimeZoneOffset()获取此帐户的时区时差(以毫秒为单元)。
getTimeZoneOffsetInHours()获取此帐户的时区时差(以小时为单元)。

param

这是订户在保存到数据库之前提交的订户请求物件。在编写 Pre-workflow 程序时特别有用。

方法描述
getUpdatedEntry()仅限 Post-workflow。回传刚创建或更新的纪录。
getNewNodeId(int fieldId)回传给定字段的新值写入后的节点 ID(整数)。
getOldNodeId(int fieldId)回传给定字段的新值写入前的节点 ID(整数)。
getNewValue(int fieldId)回传给定字段的新值写入后的值。
getOldValue(int fieldId)回传给定字段的新值写入前的值。
getNewValues(int fieldId)类似于 getNewValue,但可以同时访问多个值,这在处理多选字段时非常有用。
getOldValues(int fieldId)类似于 getOldValue,但可以同时访问多个值,这在处理多选字段时非常有用。
getSubtableEntry(int fieldId)回传可以操作子表格中每笔纪录的参数列表。
isCreateNew()回传数据是否是新创建的。

approval

方法描述
create(String[] wfSigner)仅限 Post-workflow。 wfSigner 是一个包含特定 JSON 格式对象的数组。 {

'stepIndex' : 签核的步骤 - 从 0 开始,

'approver' : 签核人的电邮

'stepName' : 签核人的名称或职位

}

单步签核范例:

wfSigner push({

'stepIndex':'1',

'approver':'kingjo@ragic.com',

'stepName':'Jo'

})

请注意,wfSigner 应符合设计模式中设置的签核。 假设设计模式中第二步的签核候选人只有“HR00@gmail.com”,那么您应提供一个 approver 为 HR00@gmail.com 且 stepIndex 为 1 的 JSON。

cancel()仅限 Post-workflow。撤销数据的签核。

approvalParam

方法描述
getEntryRootNodeId()获取数据的根节点 ID
getApprovalAction()获取签核的动作。可为 CREATE、APPROVE、FINISH、CANCEL、REJECT

util

方法描述
getURL(String urlstring)通过 GET 方法调用 URL
postURL(String urlstring,String postBody)通过 POST 方法调用 URL
deleteURL(String urlstring)通过 DELETE 方法调用 URL
putURL(String urlstring,String putBody)通过 PUT 方法调用 URL
setHeader(String name,String value)设置将在随后的 URL 调用中使用的 HTTP 首部
ignoreSSL()忽略当前 HTTP 请求的 SSL 证书检查
removeHeader(String name)从随后的 URL 调用中移除 HTTP 首部
logWorkflowError(String text)在工作流程日志中记录一笔文本日志消息,您可以在数据库维护页面面中找到它

account

方法描述
getUserName(String email)透过电邮地址获取订户的全名
getUserEmail(String userName)获取指定用户名称的电邮地址
reset()在程序运行完毕并重新加载页面面后,清除所有帐户相关的高速缓存
getTimeZoneOffset()获取此帐户的时区时差(以毫秒为单元)
getTimeZoneOffsetInHours()获取此帐户的时区时差(以小时为单元)

param

这是订户在保存到数据库之前提交的请求对象。这在编写 Pre-workflow 程序时特别有用。

方法描述
getUpdatedEntry()仅限 Post-workflow。回传刚刚创建或更新的数据
getNewNodeId(int fieldId)回传在新值写入后给定字段的节点 ID(整数)
getOldNodeId(int fieldId)回传在新值写入前给定字段的节点 ID(整数)
getNewValue(int fieldId)回传在新值写入后给定字段的值
getOldValue(int fieldId)回传在新值写入前给定字段的值
getNewValues(int fieldId)类似于 getNewValue,但可以同时访问多个值,这在处理多选字段时非常有用
getOldValues(int fieldId)类似于 getOldValue,但可以同时访问多个值,这在处理多选字段时非常有用
getSubtableEntry(int fieldId)回传可以操作子表格中每笔纪录的参数列表
isCreateNew()回传数据是否是新创建的

approval

方法描述
create(String[] wfSigner)仅限 Post-workflow。 wfSigner 是一个包含特定 JSON 格式对象的数组。{

'stepIndex' : 签核步骤 - 从 0 开始,

'approver' : 签核人的电邮,

'stepName' : 签核人的名称或职位

}

单步签核范例:

wfSigner.push({

'stepIndex':'1',

'approver':'kingjo@ragic.com',

'stepName':'Jo'

})

请注意,wfSigner 应符合设计模式中设置的签核。假设设计模式中第二步的签核候选人只有 "HR00@gmail.com",那么您应提供一个 approver 为 HR00@gmail.com 且 stepIndex 为 1 的 JSON。

cancel()仅限 Post-workflow。撤销数据的签核

approvalParam

方法描述
getEntryRootNodeId()获取数据的根节点 ID
getApprovalAction()获取签核的操作。可为 CREATE、APPROVE、FINISH、CANCEL、REJECT

回最上面 目录

马上登记
免费试用 Ragic!

用 Google 帐号登记

立即科技 Ragic, Inc.
02-7728-8692
台北市中正区南昌路二段81号9楼