{
  "Name": "把子列表转换为邮件表格",
  "Description": "从子列表 JSON 生成内联样式的 HTML 表格，供审批通知、邮件和文档模板使用。",
  "ImplType": 0,
  "DraftCode": "function parseRows(input) {\n  if (typeof input === \"string\") {\n    try { input = JSON.parse(input); } catch { return []; }\n  }\n  return Array.isArray(input)\n    ? input.filter((row) => row && typeof row === \"object\" && !Array.isArray(row))\n    : [];\n}\n\nfunction escapeHtml(value) {\n  return value.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\")\n    .replaceAll('\"', \"&quot;\").replaceAll(\"'\", \"&#39;\");\n}\n\nfunction cellText(value) {\n  if (value == null) return \"\";\n  if (typeof value === \"boolean\") return value ? \"是\" : \"否\";\n  if (typeof value === \"number\") {\n    return Number.isFinite(value) ? value.toLocaleString(\"zh-CN\", { maximumFractionDigits: 20 }) : \"\";\n  }\n  if (typeof value === \"string\") {\n    const text = value.trim();\n    // 保留日期中的原始日期部分，避免时区转换改变日期。\n    if (/^\\d{4}-\\d{2}-\\d{2}T[\\d:.]+(?:Z|[+-]\\d{2}:\\d{2})?$/.test(text) && !Number.isNaN(Date.parse(text))) {\n      return text.slice(0, 10);\n    }\n    return text;\n  }\n  try { return JSON.stringify(value) ?? \"\"; } catch { return \"\"; }\n}\n\nexport async function main({ params }) {\n  const rows = parseRows(params?.subListJson);\n  const columns = [...new Set(rows.flatMap(Object.keys))].filter((key) => key !== \"_id\" && key !== \"__ctxidx\");\n  const tableStyle = \"width:100%;border-collapse:collapse;font-family:Arial,'Microsoft YaHei',sans-serif;font-size:14px;color:#273449;border:1px solid #dce4ed;\";\n  const headerStyle = \"padding:10px 12px;text-align:left;background:#edf3ff;border-bottom:1px solid #dce4ed;\";\n  const cellStyle = \"padding:9px 12px;border-bottom:1px solid #e1e8f1;vertical-align:top;\";\n  const header = columns.length ? `<thead><tr>${columns.map((key) =>\n    `<th scope=\"col\" style=\"${headerStyle}\">${escapeHtml(key)}</th>`).join(\"\")}</tr></thead>` : \"\";\n  const body = rows.map((row) => columns.map((key) => cellText(Object.hasOwn(row, key) ? row[key] : null)))\n    .filter((cells) => cells.some((text) => text !== \"\"))\n    .map((cells, i) => `<tr${i % 2 ? ' style=\"background:#f7f9fc;\"' : \"\"}>${cells.map((text) =>\n      `<td style=\"${cellStyle}\">${escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, \"<br>\")}</td>`).join(\"\")}</tr>`).join(\"\");\n  const empty = `<tr><td colspan=\"${Math.max(1, columns.length)}\" style=\"${cellStyle}\">暂无明细</td></tr>`;\n  const htmlTable = `<table aria-label=\"子列表明细\" cellpadding=\"0\" cellspacing=\"0\" style=\"${tableStyle}\">${header}<tbody>${body || empty}</tbody></table>`;\n  return { htmlTable };\n}\n",
  "DraftConfig": "{\"params\":[{\"id\":\"subListJson\",\"type\":\"text\",\"desc\":\"子列表行对象的 JSON 数组。\"}],\"connections\":[],\"outputs\":[{\"id\":\"htmlTable\",\"type\":\"text\",\"desc\":\"可插入邮件或通知正文的 HTML 表格。\"}]}",
  "ExtData": null
}
