FaaS 连接器 - 批量新增表单实例
注意:不建议以 HTTP 连接器的形式在前端数据源中直接使用此 OpenAPI,请参考此案例配置 FaaS 连接器后方可使用。否则会导致 systemToken 参数的泄露,威胁应用的数据安全。
1. 使用场景
本例开发语言:NodeJS
本例介绍一下如何使用钉钉开放平台 OpenAPI 实现批量新增表单实例。
2. 实现功能
2.1. 申请钉钉开放平台应用凭证及接口权限
若已申请,可忽略此步骤。
 宜搭自定义连接器鉴权凭证申请及接口权限申请 | 钉钉宜搭·帮助中心
宜搭自定义连接器鉴权凭证申请及接口权限申请 | 钉钉宜搭·帮助中心
2.2. 创建并配置 FaaS 连接器
注意:
- 如果选择不执行校验规则、关联业务规则和第三方服务回调(noExecuteExpression:true),那么同步 / 异步单次批量创建表单实例允许的数量是 500 条。
- 如果选择执行校验规则、关联业务规则和第三方服务回调(noExecuteExpression:false)
- 如果选择同步(asynchronousExecution:false),允许单次 50 条。
- 如果选择异步(asynchronousExecution:true),允许单次 200 条。
2.2.1. 创建 FaaS 连接器

2.2.2. 配置连接器基本信息和开发语言

2.2.3. 配置连接器执行动作



注意解析 Body 并配置成功标志位。
{
  "noExecuteExpression" : true,
  "formUuid" : "String",
  "appType" : "String",
  "asynchronousExecution" : true,
  "keepRunningAfterException" : true,
  "formDataJsonList" : "Array of String"
}
{
  "success": true,
  "content": [ "FINST-XXXXXXX" ],
  "error": ""
}
2.3. 开发 FaaS 连接器
2.3.1. 前往云 IDE 开发并在 dingOpenApiUtil.js 文件中添加代码

添加完毕后需保存。
Windows:Ctrl + S
Mac:Command + S

复制下列代码,整个替换上图标记的「 batchSaveFormData 」。
batchSaveFormData: async function (batchSaveFormDataInputs) {
  let client = createClient();
  let batchSaveFormDataHeaders = new $dingtalkyida_1_0.BatchSaveFormDataHeaders({});
  batchSaveFormDataHeaders.xAcsDingtalkAccessToken = innerGetAccessToken();
  let batchSaveFormDataRequest = new $dingtalkyida_1_0.BatchSaveFormDataRequest(batchSaveFormDataInputs);
  try {
    const result = await client.batchSaveFormDataWithOptions(batchSaveFormDataRequest, batchSaveFormDataHeaders, new $Util.RuntimeOptions({}));
    return result.body.result;
  } catch (err) {
    if (!Util.empty(err.code) && !Util.empty(err.message)) {
      // err 中含有 code 和 message 属性,可帮助开发定位问题
    }
    throw err;
  }
  return null;
}
2.3.2. 将 faasEntry.js 文件中的代码完全替换
注意根据实际情况修改固定参数。
appKey、appSecret 为 2.1 申请的应用凭证。
systemToken 可直接在宜搭 应用设置 - 部署运维 中找到。

const { openApi: OpenAPIUtil, yidaConnector: YidaConnectorUtil, httpUtil: HttpUtil } = require('./utils');
// 注意:涉及数据安全的参数(如:appKey、appSecret、systemToken)一定要在服务端发送,不可在前端数据源里传入。
const appKey = 'XXXXXXXXXXXXXXXXXXXXXX';
const appSecret = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
const systemToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
module.exports = async function (faasInputs) {
    // 这里的 inputs 跟你配置连接器时的 Body 参数及字段格式保持一致
    const { inputs = {}, yidaContext = {} } = faasInputs || {};
    const userId = yidaContext ? yidaContext['userId'] : ''; // 从连接器上下文获取调用人的 userId
    const accessToken = yidaContext ? yidaContext['accessToken'] : '';
    const consumeCode = yidaContext ? yidaContext['consumeCode'] : '';
    OpenAPIUtil.setAccessToken(accessToken);
    await OpenAPIUtil.getCustomAccessTokenThenCache(appKey, appSecret); // 获取调用连接器的 accessToken
    YidaConnectorUtil.setConsumeCode(consumeCode);
    inputs['systemToken'] = systemToken;
    inputs['userId'] = userId;
    return await batchSaveFormData(inputs).then((result) => {
        return {
            success: true,
            content: result,
            error: null,
        };
    }).catch((error) => {
        return {
            success: false,
            content: null,
            error,
        };
    });
};
async function batchSaveFormData(inputs) {
    return await OpenAPIUtil.batchSaveFormData(inputs);
}
2.4. 部署 FaaS 连接器
注意保存添加的代码。

当提示代码部署成功即完成 FaaS 连接器云 IDE 开发。

2.5. 返回连接器配置并点击保存

2.6. 在宜搭页面配置数据源和使用数据源
2.6.1. 获取数据并展示在表格中
可参考下述案例,本例是对下述案例新增数据功能的升级。
2.6.2. 在数据源中选择刚刚创建的连接器


2.6.3. 前端直接调用数据源

// 触发批量新增
export function batchSaveFormData(formDataJsonList) {
  this.dataSourceMap.batchSaveFormData.load({
    inputs: JSON.stringify({
      body: {
        formUuid,
        appType,
        formDataJsonList,
        noExecuteExpression: true,
        asynchronousExecution: true,
        keepRunningAfterException: true,
      }
    })
  }).then(res => {
    const { success, error } = res;
    if (success) {
      this.utils.toast({
        title: '数据新增成功',
        type: 'success'
      });
      setTimeout(() => {
        this.fetchData();
      }, 2000);
    } else {
      this.utils.toast({
        title: error,
        type: 'error',
      });
    };
  }).catch(error => {
    this.utils.toast({
      title: error.message,
      type: 'error'
    });
  });
}

// 批量新增数据--确定
export function onMoreListOk() {
  // 需要校验组件的唯一标识集合
  const fieldList = [
    'tableField_lpamltk2'
  ];
  // 调用表单校验函数 
  this.fieldsValidate(fieldList).then(errorList => {
    setTimeout(() => {
      if (errorList.length > 0) {
        // 表单校验未通过,可做一些数据错误提示
        this.utils.toast({
          title: '请填写新增明细数据',
          type: 'warring'
        });
        return;
      };
      // 表单校验通过,你的后续业务逻辑由此往下写
      const addTableValue = this.$('tableField_lpamltk2').getValue()
      const formDataJsonList = addTableValue.map((item) => {
        return JSON.stringify({
          textField_lcpug407: item.textField_lpamltk3, // 姓名
          radioField_lcpusnic: item.radioField_lpamltk4 || '', // 性别
          numberField_lcpusnib: item.numberField_lpamltk5 || '', // 年龄
          employeeField_lpao1x8f: this.formatEmployeeFieldValue(item.employeeField_lpamltk7), // 负责人
          departmentSelectField_lpao1x8h: item.departmentSelectField_lpamltk8[0] ? [item.departmentSelectField_lpamltk8[0].value] : [], // 所在部门
          dateField_lpao1x8g: item.dateField_lpamltk6 || '', // 入职日期
        })
      })
      this.batchSaveFormData(formDataJsonList)
      this.$('dialog_lpamltk1').hide()
    });
  }, 0);
}
// fieldList:Array,需要校验组件的唯一标识集合
export async function fieldsValidate(fieldList = []) {
  const result = [];
  for (let i = 0; i < fieldList.length; i++) {
    await this.$(fieldList[i]).validate((errors, values) => {
      if (!errors) { return };
      result.push({
        fieldId: fieldList[i], // 组件标识
        errors: this.utils.isMobile() ? errors.errors[fieldList[i]].errors : errors[fieldList[i]].errors // 校验错误信息
      });
    });
  };
  return result;
}
// 获取成员字段的 value --用于处理成员组件格式不一致
export function formatEmployeeFieldValue(userData) {
  if (Array.isArray(userData)) {
    return userData.length ? userData.map((item) => { return item.value; }) : '';
  } else {
    return userData ? [userData.value] : '';
  }
}
3. 实现效果



4. 在线试玩
本文档对您是否有帮助?
