轻易云
注册体验

飞书费用报销单同步至 MySQL:单策略集成实战教程

· 集成方案库· 44 次浏览· 约 4 分钟读完
MySQL飞书飞书审批财务同步字段映射集成策略踩坑复盘

这个策略解决什么问题(场景与价值)

飞书审批里的费用报销单字段多达四十多个,里面还嵌着「预算明细表」「费用明细表」两类子表单,下游 MySQL 报销表却只接受扁平字段。一次实际项目中,客户希望每 5 分钟把飞书新提交的报销单抓回财务中间库,供 BI 与对账使用。难点在于三件事:嵌套表单如何取值、往来单位如何编码映射、审批未完成时占位时间如何兜底。我们用轻易云数据集成平台(Qeasy)承接了这条策略,把一张 1:N 的审批表单压平写入单表。

数据流向与字段映射(源 → 中间层 → 目标)

源端:飞书审批 /open-apis/approval/v4/instances,表单 ID 即素材中的 approval_code,按 start_time/end_time 窗口拉取。 中间层:轻易云内部字段映射表达式层,使用 CASE、COALESCE、FROM_UNIXTIME 等函数完成转换。 目标端:MySQL 报销表,主键为 id,并以 serial_number / instance_code / bfn_num 做业务去重键,写入采用 REPLACE INTO,单批 200 条。

关键字段对照:

业务含义源字段目标字段映射类型转换规则
审批单编号serial_numberserial_numberDIRECT原样
审批实例 IDinstance_codeinstance_codeDIRECT原样
唯一 IDbfn_numbfn_numDIRECT去重
报销类型widget17131584834230001_textreimbursement_typeDIRECT原样
借款情况4 个备选 widgetloan_situationTRANSFORMCOALESCE 取首个非空,兜底 fallback
预算承担部门widget17579334192410001.0.widget17580115872700001_textbudget_departmentDIRECT预算明细表首行
本次付款金额widget17579334192410001.0.widget17612731842700001current_payment_amountDIRECT预算明细表首行
费用承担部门widget17579337089770001_widget17592232346890001_textexpense_departmentDIRECT费用明细表选中行
往来单位编码widget*employee_idTRANSFORMCASE 按客户/供应商/员工/其他分支取值
申请付款金额widget*application_payment_amountTRANSFORM申请退款→退款金额;否则→付款金额
审批完成时间end_timeend_timeTRANSFORM0→默认日期;否则毫秒转 datetime

在轻易云上如何配置

  1. 新建源端「飞书」连接器,接口选 /open-apis/approval/v4/instances,请求体里把 approval_code 写成固定值,start_time/end_time 用 {{CURRENT_TIME}}000 占位,让平台按调度时间自动注入。
  2. 新建目标端「MySQL」连接器,写入方式选 batchexecute,主键 id 勾选 idCheck: true,写入策略 REPLACE INTO。
  3. 在策略画布里拖入「字段映射」节点:直接映射用表达式原样引用 {{widget...}};嵌套取值用 {{widget17579334192410001.0.widget...}} 这种点号语法取数组首行;表格选中行用 {{widget17579337089770001_widget...}} 下划线语法。
  4. 编码映射集中管理:把「往来单位 → employee_id」做成一个可复用的 CASE 表达式,放到平台的「公共映射」中,后续别的单据直接引用,避免散落在多个策略里。
  5. 时间兜底:在 end_time 字段上加 IF({{end_time}}=0, '1000-01-01 00:00:00', FROM_UNIXTIME(FLOOR({{end_time}}/1000)))。

实施步骤

阶段一:增量起点。先把飞书过去 7 天的历史单据做一次性全量回刷,确认编码映射与扁平化取值正确;之后调度从 CURRENT_TIME 起改为增量,按 start_time/end_time 滚动窗口。

阶段二:全量触发。在轻易云里手动触发一次「全量回灌」,观察目标表行数与源端实例数是否一致;不一致时优先排查费用明细表选中行为空的单据。

阶段三:调度频率。线上落地后调度改为 */5 * * * *,每 5 分钟拉取一次;同时在源端加 start_time 偏移 5 分钟的兜底,避免边界单据漏拉。

阶段四:监控。平台内置的成功率、耗时、单据计数告警配齐,连续两轮空跑就触发人工排查。

踩坑复盘

  1. 嵌套数组取错行。典型错误是直接 widget17579334192410001.xxx,这会拿到整段 JSON 字符串而报错。稳妥的做法是显式写 widget17579334192410001.0.xxx,锁定首行;若以后要展开多行,再切换到子表映射。
  2. 费用明细选中行为空。飞书的表格控件在用户未选行时返回空,映射表达式拿到空字符串会写入脏数据。务必在目标端把可空字段设为允许 NULL,并在平台里加一个「选中行空值过滤」的预校验。
  3. 编码映射散落各处。我们见过客户把 CASE 写在每个策略的字段表达式里,改一次供应商编码要翻十几个策略。轻易云客户常见的应对模式是编码映射集中管理,放到「公共映射」或独立函数库。
  4. end_time=0 的占位时间。审批未完成时飞书返回 end_time=0,直接落库会让 BI 把这些当作 1970 年。必须做 0 值兜底,建议用业务约定的占位日期(如 1000-01-01)而不是 NULL,方便后续按状态过滤。
  5. REPLACE INTO 的副作用。按主键覆盖意味着同一笔报销单如果后续被人为修改过某些非关键字段,旧值会被无声覆盖。增量与全量双轨能缓解:日常走 */5 * * * * 增量回写,月底跑一次全量比对,对账差异单独立项处理。

适用场景与不适用场景

适用:单据结构稳定、字段在 50 以内、可接受扁平化写单表、对账时效在分钟级的财务报销、采购付款等轻量同步场景。 不适用:需要保留多行明细(如预算多行同时落库)、对历史版本有强追溯需求、或下游已上湖仓需要原始嵌套 JSON 的场景,建议改用主子表方案或直接同步到数据仓库。

本文为原创内容,转载请注明出处:https://www.qeasy.cloud/insights/solutions/strat-mysql-feishu-1122-mysql-1ed6cb73

评论