通过接口传输附件,但下载超时导致失败的校验和重传方案

问答  收藏
2 / 61

背景:明道云通过工作表接口,使用 url 进行附件的新增/更新数据时,如果单个附件的下载时长超过 15 秒,将会下载失败,附件内容无法正常保存。
报错示例:
image.png

解决思路:

step1:第三方系统通过接口新增 or 更新附件的时,将文件名称、文件数量一并传入,保存到明道云表单中

step2:明道云触发工作表事件,解析已保存的文件名称和数量,并与 step1 中传输的文件名称、文件数量做对比,输出比对结果。如果存在传输失败的附件,则记录名称。

step3:可调用第三方系统接口,将附件保存结果主动发送回去,或者第三方系统定时调用明道云接口查询附件保存结果

step4:根据保存结果,如果存在上传失败的附件,尝试挑使用低峰期,第三方系统调用更新记录接口再次更新附件

实现方式示例:

step1:新增 or 更新附件时加上文件名称、文件数量信息

step2:工作流校验

更新到表单上

参考代码

处理保存后的附件格式

//将附件地址转换为JSON数组
var filelist=JSON.parse(input.filelist?input.filelist:'[]');

var result = [];

for (var i = 0; i < filelist.length; i++) {
  var fileurl = filelist[i];
  var url = new URL(fileurl);
  var params = new URLSearchParams(url.search);
  
  // 正则提取 attname 参数(不转码)
  var match = fileurl.match(/(?<=attname=).+?(?=&e)/);
  var filename = "";

  if (match) {
    var fullFilename = decodeURIComponent(match[0]); // 只转码 filename
    filename = fullFilename.replace(/\.[^/.]+$/, ""); // 去除扩展名
  }

  result.push({
    name: filename,
    url: fileurl  // 保留原始 URL,不修改其中的编码
  });
}

//全部输出,按需选择
output={"result":result}

取出文件名

// 接收输入对象的数据
const data = JSON.parse(input.data);

// 提取filename和fileurl并组装成目标格式
const fileUrls = data.map(item => item.url).join(",");
const fileNames = data.map(item => item.name).join(",");

// 统计对象数量
const count = data.length;

// 输出结果到输出对象
output = {
    url: fileUrls,
    name: [fileNames],
    count: count
};

对比差异

const source = input.source;
const target = JSON.parse(input.target);

// 1. 提取 source 中的文件名字符串
const match = source.match(/文件名:\s*([^;;]+)/);

let sourceArr = [];
if (match && match[1]) {
  sourceArr = match[1].split(",");
}

// 2. 展开 target(逐项)
let targetArr = [];
for (let i = 0; i < target.length; i++) {
  targetArr = targetArr.concat(target[i].split(","));
}

// 3. 计算 diff(source 有但 target 没有)
const diff = sourceArr.filter(item => targetArr.indexOf(item) === -1);

// 4. 计算 A / B / C / D
const A = sourceArr.length;
const B = targetArr.length;
const C = A - B;
const D = diff;

// 5. 判断上传结果
let uploadResult = "成功";
if (C === A) {
  uploadResult = "失败";
} else if (C > 0) {
  uploadResult = "部分失败";
}

// 6. 组装最终输出
const result = {
  "上传结果": uploadResult,
  "上传详情": `共需要上传${A}个附件,上传成功${B}条,失败${C}条,上传失败的附件为:${D.join(",")}`
};

console.log(result);


output = { result: result };

step3:第三方系统提供接口,工作流调用接口将保存结果发送给第三方系统

step4:根据保存结果,如果存在上传失败的附件,第三方系统可再次调用更新记录接口更新附件。(或第三方系统定时来查询保存结果)