> ## Documentation Index
> Fetch the complete documentation index at: https://docs-docflow.textin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AP 审单场景（无工作空间）

> 在财务部门 AP（应付账款）审单业务场景中，调用 DocFlow API 完成发票、采购订单、收货单等单据的自动化交叉审核。

> [!TIP]
>
> 本文以 **AP 审单**（应付账款审核）为业务场景，演示如何通过 API 完成从创建空间、配置类别、上传文件、获取抽取结果到智能审核的完整流程。
> 如果您刚刚接触 DocFlow，建议先在 [Web 页面](https://docflow.textin.com/) 体验一下产品的基本功能，再阅读本文。

## 01 场景说明

在 AP（应付账款）审单业务中，财务人员每次付款前需要对一组采购单据进行交叉核验。典型的单据组合包括：

* 发票（含数电票、纸质增值税专用发票/普通发票等）：记录销售方/购买方信息、开票金额和税率
* 采购订单（PDF/Word）：约定供应商信息、合同金额、税率和产品明细
* 收货单（PDF）：记录实际收货数量、物料信息及关联的采购订单号

通过 DocFlow，您只需配置一次分类和字段，后续上传的单据即可自动完成**分类识别**和**结构化信息抽取**；配置好审核规则库后，还可对多份单据进行**跨文档智能审核**，自动发现供应商不一致、金额超标、数量异常等问题。

## 02 业务流程

![AP 审单业务流程](https://mintcdn.com/docflow/NHmfC3xyBtH2bZya/docflow/cn/images/expense_reimbursement_flow.png?fit=max\&auto=format\&n=NHmfC3xyBtH2bZya\&q=85\&s=f294139c4cf2119d8d430dfb67107809)

> [!NOTE]
>
> **工作空间、文件类别和审核规则库只需配置一次**，后续可持续复用——直接上传新的待处理文件并创建新的审核任务即可。本示例为演示完整流程，将配置步骤和处理步骤放在同一段代码中运行。

## 03 先决条件

1. 登录 [TextIn 控制台](https://www.textin.com/console/dashboard/setting)，获取 `x-ti-app-id` 和 `x-ti-secret-code`
2. 下载[示例样本文件](https://github.com/ichaozai/docflow-docs/tree/master/examples/sample_files/ap_review)，或使用自己的单据文件

## 04 类别与字段配置

本示例配置四个文件类别，均通过 `category/create` 接口创建并配置字段。

> [accordion] 国内票-数电票（样本：sample\_invoice.pdf）
>
> 增值税电子发票（数电票），包含发票号码、开票日期、购买方/销售方名称及税号、价税合计等基本信息字段，以及商品明细表格字段：
>
> > [!TIP]
> >
> > 示例样本文件，可点击查看或下载：[sample\_invoice.pdf](https://dllf.intsig.net/download/2026/CustomService/sample_invoice.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=%2BjHQOCGSfbdg/JY2/vS4QwiQofPFnPxCe4AnEo28UK0%3D)
> >
> > [https://dllf.intsig.net/download/2026/CustomService/sample\_invoice.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=%2BjHQOCGSfbdg/JY2/vS4QwiQofPFnPxCe4AnEo28UK0%3D](https://dllf.intsig.net/download/2026/CustomService/sample_invoice.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=%2BjHQOCGSfbdg/JY2/vS4QwiQofPFnPxCe4AnEo28UK0%3D)
>
> | 字段名 | 类型 |
> | - | - |
> | 发票号码 | 基本信息字段 |
> | 开票日期 | 基本信息字段 |
> | 价税合计 | 基本信息字段 |
> | 税前金额 | 基本信息字段 |
> | 税额 | 基本信息字段 |
> | 销售方名称 | 基本信息字段 |
> | 销售方纳税人识别号 | 基本信息字段 |
> | 购买方名称 | 基本信息字段 |
> | 购买方纳税人识别号 | 基本信息字段 |
> | 发票备注 | 基本信息字段 |
> | 商品名称 | 表格字段 |
> | 规格型号 | 表格字段 |
> | 单位 | 表格字段 |
> | 数量 | 表格字段 |
> | 单价 | 表格字段 |
> | 金额 | 表格字段 |
> | 税率 | 表格字段 |
> | 税额 | 表格字段 |

> [accordion] 采购合同（样本：sample\_contract.pdf）
>
> 采购合同是约定交易条款的核心文件，包含合同编号、甲乙方信息、金额、税率和产品明细。字段配置同时使用**基本信息字段**和**表格字段**：
>
> > [!TIP]
> >
> > 示例样本文件，可点击查看或下载：[sample\_contract.pdf](https://dllf.intsig.net/download/2026/CustomService/sample_contract.pdf?se=2036-11-02T07%3A10%3A43Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=Rp5O%2B/FMDr/pb1aRC8YLDqOK2AVvc82dL3EUM2N8UiM%3D)
> >
> > [https://dllf.intsig.net/download/2026/CustomService/sample\_contract.pdf?se=2036-11-02T07%3A10%3A43Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=Rp5O%2B/FMDr/pb1aRC8YLDqOK2AVvc82dL3EUM2N8UiM%3D](https://dllf.intsig.net/download/2026/CustomService/sample_contract.pdf?se=2036-11-02T07%3A10%3A43Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=Rp5O%2B/FMDr/pb1aRC8YLDqOK2AVvc82dL3EUM2N8UiM%3D)
>
> | 字段名 | 类型 |
> | - | - |
> | 编号 | 基本信息字段 |
> | 甲方 | 基本信息字段 |
> | 乙方 | 基本信息字段 |
> | 签订日期 | 基本信息字段 |
> | 合作期间 | 基本信息字段 |
> | 支付条款 | 基本信息字段 |
> | 乙方银行账户信息 | 基本信息字段 |
> | 开票信息 | 基本信息字段 |
> | 违约金条款 | 基本信息字段 |
> | 采购物料/服务数量 | 基本信息字段 |
> | 合同类型 | 基本信息字段 |
> | 采购金额 | 基本信息字段 |
> | 采购单价 | 基本信息字段 |
> | 税率 | 基本信息字段 |
> | 乙方税号 | 基本信息字段 |
> | 采购物料/服务 | 基本信息字段 |
> | 产品型号 | 表格字段 |
> | 产品说明 | 表格字段 |
> | 单价 | 表格字段 |
> | 数量 | 表格字段 |
> | 金额 | 表格字段 |

> [accordion] 入库单（样本：sample\_inbound.pdf）
>
> 入库单是仓库收货的凭证，记录实收数量、物料信息和供应商信息。字段配置同时使用**基本信息字段**和**表格字段**：
>
> > [!TIP]
> >
> > 示例样本文件，可点击查看或下载：[sample\_inbound.pdf](https://dllf.intsig.net/download/2026/CustomService/sample_inbound.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=qEbKFY1CTmj3p56PtoWTJDdJfhZLoA%2Bg/9NtNl2q/7s%3D)
> >
> > [https://dllf.intsig.net/download/2026/CustomService/sample\_inbound.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=qEbKFY1CTmj3p56PtoWTJDdJfhZLoA%2Bg/9NtNl2q/7s%3D](https://dllf.intsig.net/download/2026/CustomService/sample_inbound.pdf?se=2036-11-02T07%3A10%3A45Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=qEbKFY1CTmj3p56PtoWTJDdJfhZLoA%2Bg/9NtNl2q/7s%3D)
>
> | 字段名 | 类型 |
> | - | - |
> | 收货单编号 | 基本信息字段 |
> | 收货日期 | 基本信息字段 |
> | 对应合同号 | 基本信息字段 |
> | 供应商名称 | 基本信息字段 |
> | 仓库／库位 | 基本信息字段 |
> | 物流单号 | 基本信息字段 |
> | 入库总金额 | 基本信息字段 |
> | 收货结论 | 基本信息字段 |
> | 备注 | 基本信息字段 |
> | 仓库收货人 | 基本信息字段 |
> | 仓库收货人日期 | 基本信息字段 |
> | 质检确认 | 基本信息字段 |
> | 质检确认日期 | 基本信息字段 |
> | 供应商送货人 | 基本信息字段 |
> | 供应商送货人日期 | 基本信息字段 |
> | 供应商税号 | 基本信息字段 |
> | 收货入库明细-物料编码 | 表格字段 |
> | 收货入库明细-物料描述 | 表格字段 |
> | 收货入库明细-单位 | 表格字段 |
> | 收货入库明细-应收 | 表格字段 |
> | 收货入库明细-实收 | 表格字段 |
> | 收货入库明细-差异 | 表格字段 |
> | 收货入库明细-质检 | 表格字段 |
> | 收货入库明细-签收人 | 表格字段 |

> [accordion] 验收单（样本：sample\_acceptance.pdf）
>
> 验收单是确认货物/服务交付质量的凭证，仅包含基本信息字段：
>
> > [!TIP]
> >
> > 示例样本文件，可点击查看或下载：[sample\_acceptance.pdf](https://dllf.intsig.net/download/2026/CustomService/sample_acceptance.pdf?se=2036-11-02T07%3A10%3A41Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=y5Ozdi/lFJ%2BqJfrOrZjhC4Lfk9EZizoJzNxTwbhGPD8%3D)
> >
> > [https://dllf.intsig.net/download/2026/CustomService/sample\_acceptance.pdf?se=2036-11-02T07%3A10%3A41Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=y5Ozdi/lFJ%2BqJfrOrZjhC4Lfk9EZizoJzNxTwbhGPD8%3D](https://dllf.intsig.net/download/2026/CustomService/sample_acceptance.pdf?se=2036-11-02T07%3A10%3A41Z\&sp=r\&sv=2024-11-04\&sr=b\&sig=y5Ozdi/lFJ%2BqJfrOrZjhC4Lfk9EZizoJzNxTwbhGPD8%3D)
>
> | 字段名 | 类型 |
> | - | - |
> | 项目名称 | 基本信息字段 |
> | 合同编号 | 基本信息字段 |
> | 甲方单位名称 | 基本信息字段 |
> | 乙方单位名称 | 基本信息字段 |
> | 甲方验收人 | 基本信息字段 |
> | 乙方施工人 | 基本信息字段 |
> | 交付内容 | 基本信息字段 |
> | 验收说明 | 基本信息字段 |
> | 验收结论 | 基本信息字段 |
> | 验收数量 | 基本信息字段 |
> | 验收日期 | 基本信息字段 |
> | 乙方税号 | 基本信息字段 |

## 05 审核规则配置

本示例的审核规则库包含 **2 个规则组、12 条审核规则**，覆盖跨单据业务一致性核验和文档完整性预检两个维度：

> [accordion] 规则组 1：业务一致性审核（跨单据交叉核验）
>
> | 规则名称 | 风险等级 | 审核逻辑 |
> | - | - | - |
> | 供应商一致性 | ● 高风险 | 若均存在税号，则发票销售方税号 = 合同乙方税号 = 入库单供应商税号；否则比对名称 |
> | 金额匹配 | ● 高风险 | 发票价税合计金额 ≤ 采购合同总金额；框架协议（金额为空或 0）时不校验 |
> | 数量一致性（入库单维度） | ● 中风险 | 若发票含商品明细，则发票数量合计 ≤ 入库单实收数量合计 |
> | 标的一致性 | ● 低风险 | 合同约定的规格型号须与入库单、发票中的规格型号一致；未约定规格型号时校验标的物描述是否指向同一商品 |
> | 税率一致性 | ● 中风险 | 发票各行税率须与合同约定税率一致；合同未约定税率时跳过 |
> | 验收结论校验 | ● 中风险 | 验收单的验收结论须为合格/通过/验收通过/同意验收或类似认可状态 |
> | 数量一致性（验收单维度） | ● 中风险 | 若发票含商品明细且验收单有合格数量，则发票数量合计 ≤ 验收单合格数量 |
> | 合同关联性 | ● 中风险 | 入库单合同编号 = 采购合同编号；验收单合同编号 = 采购合同编号 |
>
> > [!TIP]
> >
> > 跨文档规则的 `category_ids` 包含多个分类 ID，只有当审核任务覆盖所有关联分类时，该规则才会被触发执行。

> [accordion] 规则组 2：文档采集与预处理审核
>
> | 规则名称 | 风险等级 | 审核逻辑 |
> | - | - | - |
> | 信息完整性校验 | ● 中风险 | 检查四类文档齐全性并核验各文档必填字段非空（详见审核点说明） |
> | 发票日期合规性 | ● 中风险 | 发票开票日期 ≥ 合同签订日期 |
> | 购买方信息匹配 | ● 高风险 | 发票购买方名称 = 上海合合信息科技股份有限公司；购买方税号 = 91310110791485269J |
> | 税率合规性校验 | ● 中风险 | 货物类税率应为 13%，服务类应为 6%，小规模纳税人应为 1% 或 3% |

## 06 代码结构说明

示例代码将完整的七步流程放在一起运行，便于理解端到端的调用链路。在实际生产中，**步骤 1、2、5（创建工作空间、配置文件类别、配置审核规则库）只需执行一次**；后续处理新单据时，只需重复**步骤 3、4、6、7（上传文件 → 获取抽取结果 → 提交审核任务 → 获取审核结果）**，直接复用已有的配置即可。参见 [AP 审单场景（已完成配置）](https://docs-docflow.textin.com/docflow/cn/00-overview/ap_review_already_configured.md)。

示例代码中的函数分为两类，理解这一点有助于对照 API 文档进行调试和扩展。

### 两类函数

**REST API 调用函数** — 每个函数直接封装一个 API 端点，函数参数与接口文档一一对应：

| 函数（Python） | 方法（Java） | 对应 API 端点 | 说明 |
| - | - | - | - |
| `create_workspace` | `createWorkspace` | `POST /workspace/create` | 创建工作空间，返回 workspace\_id |
| `create_category` | `createCategory` | `POST /category/create` | 创建文件类别并上传样本，返回 category\_id |
| `batch_add_category_fields` | `batchAddCategoryFields` | `POST /category/fields/batch_add` | 为已有类别追加字段（用于添加表格字段） |
| `upload_file` | `uploadFile` | `POST /file/upload` | 异步上传文件，返回 batch\_number，需轮询获取结果 |
| `upload_file_sync` | `uploadFileSync` | `POST /file/upload/sync` | 同步上传文件，直接返回抽取结果，无需轮询 |
| `create_rule_repo` | `createRuleRepo` | `POST /review/rule_repo/create` | 创建审核规则库，返回 repo\_id |
| `create_rule_group` | `createRuleGroup` | `POST /review/rule_group/create` | 在规则库内创建规则组，返回 group\_id |
| `create_rule` | `createRule` | `POST /review/rule/create` | 在规则组内创建审核规则，绑定适用分类 |
| `submit_review_task` | `submitReviewTask` | `POST /review/task/submit` | 提交审核任务，返回审核 task\_id |

**工具辅助函数** — 不直接对应 API 端点，提供公共基础能力或封装轮询/展示逻辑：

| 函数（Python） | 方法（Java） | 作用 |
| - | - | - |
| `_headers` | `authHeaders` | 构造鉴权请求头 |
| `_check` | `checkResponse` | 校验响应 code，统一异常处理 |
| `_mime` | `mimeType` | 根据扩展名推断 MIME 类型 |
| `wait_for_result` | `waitForResult` | 循环轮询 `file/fetch`，等待抽取完成 |
| `display_result` | `displayResult` | 格式化打印抽取结果 |
| `wait_for_review` | `waitForReview` | 循环轮询 `review/task/result`，等待审核完成 |
| `display_review_result` | `displayReviewResult` | 格式化打印审核结果 |

### 逐步代码说明

> [accordion] 步骤 2：创建含表格字段的文件类别
>
> 国内票-数电票、采购合同和入库单均包含表格字段，需先创建类别（配置基本信息字段），再通过 `batch_add_category_fields` 追加表格字段。`table_id=-1` 表示挂载到默认表格。
>
> > [tab] Python
> >
> > ```python theme={null}
> > # 国内票-数电票（基本信息字段 + 明细表格字段）
> > invoice_id = create_category(
> >     workspace_id=workspace_id,
> >     name="国内票-数电票",
> >     sample_file_path="sample_invoice.pdf",
> >     fields=[
> >         {"name": "发票号码"}, {"name": "开票日期"}, {"name": "价税合计"},
> >         # ... 其余基本信息字段
> >     ],
> > )
> > batch_add_category_fields(workspace_id, invoice_id, table_id=-1, fields=[
> >     {"name": "商品名称"}, {"name": "规格型号"}, {"name": "单位"},
> >     {"name": "数量"}, {"name": "单价"}, {"name": "金额"}, {"name": "税率"}, {"name": "税额"}
> > ])
> >
> > # 采购合同（基本信息字段 + 表格字段）
> > contract_id = create_category(
> >     workspace_id=workspace_id,
> >     name="采购合同",
> >     sample_file_path="sample_contract.pdf",
> >     fields=[{"name": "编号"}, {"name": "甲方"}, {"name": "乙方"}, ...],
> > )
> > batch_add_category_fields(workspace_id, contract_id, table_id=-1, fields=[
> >     {"name": "产品型号"}, {"name": "产品说明"}, {"name": "单价"}, {"name": "数量"}, {"name": "金额"}
> > ])
> > ```
>
> > [tab] Java
> >
> > ```java theme={null}
> > // 国内票-数电票
> > String invoiceId = createCategory(workspaceId, "国内票-数电票",
> >         SAMPLE_DIR + "/sample_invoice.pdf", invoiceFields, "增值税电子发票（数电票）...");
> > batchAddCategoryFields(workspaceId, invoiceId, "-1",
> >         List.of("商品名称", "规格型号", "单位", "数量", "单价", "金额", "税率", "税额"));
> > // 采购合同
> > String contractId = createCategory(workspaceId, "采购合同",
> >         SAMPLE_DIR + "/sample_contract.pdf", contractFields, "");
> > batchAddCategoryFields(workspaceId, contractId, "-1",
> >         List.of("产品型号", "产品说明", "单价", "数量", "金额"));
> > ```

> [accordion] 步骤 3：上传待处理文件
>
> 文件上传支持两种模式，可根据业务场景选择：
>
> * **异步上传**（`file/upload`）：上传后立即返回 `batch_number`，需配合步骤 4 轮询 `file/fetch` 获取抽取结果。适合大批量文件并发处理。
> * **同步上传**（`file/upload/sync`）：上传后等待处理完成，直接返回抽取结果，无需轮询。适合单文件或少量文件的实时场景。
>
> **方式一：异步上传（需配合步骤 4 轮询）**
>
> > [tab] Python
> >
> > ```python theme={null}
> > batch_numbers = []
> > for file_path in [
> >     os.path.join(SAMPLE_DIR, "sample_invoice.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_contract.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_inbound.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_acceptance.pdf"),
> > ]:
> >     batch_number = upload_file(workspace_id, file_path)
> >     batch_numbers.append(batch_number)
> > ```
>
> > [tab] Java
> >
> > ```java theme={null}
> > List<String> batchNumbers = new ArrayList<>();
> > for (String path : new String[]{
> >         SAMPLE_DIR + "/sample_invoice.pdf",
> >         SAMPLE_DIR + "/sample_contract.pdf",
> >         SAMPLE_DIR + "/sample_inbound.pdf",
> >         SAMPLE_DIR + "/sample_acceptance.pdf"}) {
> >     batchNumbers.add(uploadFile(workspaceId, path));
> > }
> > ```
>
> **方式二：同步上传（直接返回抽取结果，跳过步骤 4）**
>
> > [tab] Python
> >
> > ```python theme={null}
> > def upload_file_sync(workspace_id: str, file_path: str) -> dict:
> >     """同步上传：直接返回抽取结果，无需轮询。"""
> >     url = f"{BASE_URL}/api/app-api/sip/platform/v2/file/upload/sync"
> >     with open(file_path, "rb") as f:
> >         resp = requests.post(url,
> >             params={"workspace_id": workspace_id},
> >             files={"file": (os.path.basename(file_path), f, _mime(file_path))},
> >             headers=_headers(), timeout=300)
> >     data = _check(resp, "同步上传文件")
> >     return data["result"]["files"][0]   # 返回结构与 file/fetch 一致
> >
> > # 调用示例：上传即得到抽取结果，可直接用于审核
> > raw_results = [upload_file_sync(workspace_id, p) for p in [
> >     os.path.join(SAMPLE_DIR, "sample_invoice.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_contract.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_inbound.pdf"),
> >     os.path.join(SAMPLE_DIR, "sample_acceptance.pdf"),
> > ]]
> > ```
>
> > [tab] Java
> >
> > ```java theme={null}
> > public static JsonObject uploadFileSync(String workspaceId, String filePath) throws IOException {
> >     File file = new File(filePath);
> >     HttpUrl url = HttpUrl.parse(BASE_URL + "/api/app-api/sip/platform/v2/file/upload/sync")
> >             .newBuilder().addQueryParameter("workspace_id", workspaceId).build();
> >     MultipartBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
> >             .addFormDataPart("file", file.getName(),
> >                     RequestBody.create(file, MediaType.get(mimeType(file.getName()))))
> >             .build();
> >     Request req = new Request.Builder().url(url).headers(authHeaders()).post(body).build();
> >     try (Response resp = HTTP.newCall(req).execute()) {
> >         return checkResponse(resp.body().string(), "同步上传文件")
> >                 .getAsJsonObject("result").getAsJsonArray("files")
> >                 .get(0).getAsJsonObject();
> >     }
> > }
> >
> > // 调用示例
> > List<JsonObject> rawResults = new ArrayList<>();
> > for (String path : new String[]{
> >         SAMPLE_DIR + "/sample_invoice.pdf",
> >         SAMPLE_DIR + "/sample_contract.pdf",
> >         SAMPLE_DIR + "/sample_inbound.pdf",
> >         SAMPLE_DIR + "/sample_acceptance.pdf"}) {
> >     rawResults.add(uploadFileSync(workspaceId, path));
> > }
> > ```

> [accordion] 步骤 4：获取抽取结果（使用同步上传时可跳过）
>
> > [!NOTE]
> >
> > 若步骤 3 使用了同步上传 `file/upload/sync`，则已直接获得抽取结果，可跳过本步骤。
>
> 异步上传后，需轮询 `file/fetch` 接口等待处理完成：
>
> > [tab] Python
> >
> > ```python theme={null}
> > raw_results = []
> > for batch_number in batch_numbers:
> >     result = wait_for_result(workspace_id, batch_number)
> >     raw_results.append(result)
> >     display_result(result)
> > ```
>
> > [tab] Java
> >
> > ```java theme={null}
> > List<JsonObject> rawResults = new ArrayList<>();
> > for (String batchNumber : batchNumbers) {
> >     JsonObject result = waitForResult(workspaceId, batchNumber);
> >     rawResults.add(result);
> >     displayResult(result);
> > }
> > ```

> [accordion] 步骤 5：配置跨文档审核规则
>
> 跨文档规则在 `category_ids` 中传入多个分类 ID。DocFlow 会从各分类已抽取的结果中提取规则关联字段，交由 AI 统一判断。
>
> > [tab] Python
> >
> > ```python theme={null}
> > # 供应商一致性——关联发票、合同、入库单三个分类
> > create_rule(workspace_id, repo_id, group1_id,
> >     "供应商一致性",
> >     "若均存在税号字段，则发票【销售方纳税人识别号】= 合同【乙方纳税人识别号】"
> >     "= 入库单【供应商税号】；否则比对名称",
> >     [invoice_id, contract_id, inbound_id], 10)
> > ```
>
> > [tab] Java
> >
> > ```java theme={null}
> > createRule(workspaceId, repoId, group1Id, "供应商一致性",
> >         "若均存在税号字段，则发票【销售方纳税人识别号】= 合同【乙方纳税人识别号】"
> >         + "= 入库单【供应商税号】；否则比对名称",
> >         Arrays.asList(invoiceId, contractId, inboundId), 10);
> > ```

### 抽取结果示例

![抽取结果示例](https://mintcdn.com/docflow/NHmfC3xyBtH2bZya/docflow/cn/images/senario_extract_result.png?fit=max\&auto=format\&n=NHmfC3xyBtH2bZya\&q=85\&s=7a2f79ed743421aca3dcf92df0653d9a)

### 审核结果示例

![审核结果示例](https://mintcdn.com/docflow/NHmfC3xyBtH2bZya/docflow/cn/images/senario_review_result.png?fit=max\&auto=format\&n=NHmfC3xyBtH2bZya\&q=85\&s=2a52846ea3b8711b8e78706fd0c6e9e9)

## 07 完整示例代码下载

完整可运行代码（含 Python、Java 两个版本）已内置在文档仓库的 `examples/` 目录下：

```
examples/
├── python/
│   ├── ap_review.py               # Python 完整示例
│   ├── requirements.txt
│   └── README.md
├── java/
│   ├── src/main/java/com/docflow/ApReview.java
│   ├── pom.xml
│   └── README.md
└── sample_files/
    └── ap_review/
        ├── sample_invoice.pdf
        ├── sample_contract.pdf
        ├── sample_inbound.pdf
        └── sample_acceptance.pdf
```

> [card] [Python 示例](https://github.com/ichaozai/docflow-docs/tree/master/examples/python)
>
> 查看 Python 完整示例代码

> [card] [Java 示例](https://github.com/ichaozai/docflow-docs/tree/master/examples/java)
>
> 查看 Java 完整示例代码

## 08 运行示例

> [tab] Python
>
> **环境要求**：Python 3.8+
>
> **1. 安装依赖**
>
> ```bash theme={null}
> cd examples/python
> pip install -r requirements.txt
> ```
>
> **2. 填写配置**
>
> 打开 `ap_review.py`，填写文件顶部的配置项：
>
> ```python theme={null}
> APP_ID        = "your-app-id"      # x-ti-app-id
> SECRET_CODE   = "your-secret-code" # x-ti-secret-code
> ```
>
> **3. 运行**
>
> ```bash theme={null}
> python ap_review.py
> ```

> [tab] Java
>
> **环境要求**：JDK 11+，Maven 3.6+
>
> **1. 填写配置**
>
> 打开 `src/main/java/com/docflow/ApReview.java`，填写文件顶部的配置项：
>
> ```java theme={null}
> private static final String APP_ID        = "your-app-id";
> private static final String SECRET_CODE   = "your-secret-code";
> ```
>
> **2. 编译并运行**
>
> ```bash theme={null}
> cd examples/java
> mvn compile -q
> mvn exec:java -Dexec.mainClass="com.docflow.ApReview"
> ```

> [!TIP]
>
> 运行成功后，可登录 [DocFlow Web 页面](https://docflow.textin.com/)，在对应工作空间下直观查看每份文件的分类、字段抽取结果和智能审核结果，便于与代码输出对照验证。

### 预期控制台输出

成功运行后，控制台将输出如下内容（workspace\_id、category\_id 等 ID 因运行环境不同而变化）：

```
============================================================
  DocFlow AP 审单场景示例
============================================================
[步骤1] 工作空间创建成功  workspace_id=<workspace_id>
[步骤2] 文件类别创建成功  name=国内票-数电票  category_id=<category_id>
  追加字段成功  name=商品名称  field_id=<field_id>
  追加字段成功  name=规格型号  field_id=<field_id>
  追加字段成功  name=单位  field_id=<field_id>
  追加字段成功  name=数量  field_id=<field_id>
  追加字段成功  name=单价  field_id=<field_id>
  追加字段成功  name=金额  field_id=<field_id>
  追加字段成功  name=税率  field_id=<field_id>
  追加字段成功  name=税额  field_id=<field_id>
[步骤2] 文件类别创建成功  name=采购合同  category_id=<category_id>
  追加字段成功  name=产品型号  field_id=<field_id>
  追加字段成功  name=产品说明  field_id=<field_id>
  追加字段成功  name=单价  field_id=<field_id>
  追加字段成功  name=数量  field_id=<field_id>
  追加字段成功  name=金额  field_id=<field_id>
[步骤2] 文件类别创建成功  name=入库单  category_id=<category_id>
  追加字段成功  name=收货入库明细-物料编码  field_id=<field_id>
  追加字段成功  name=收货入库明细-物料描述  field_id=<field_id>
  追加字段成功  name=收货入库明细-单位  field_id=<field_id>
  追加字段成功  name=收货入库明细-应收  field_id=<field_id>
  追加字段成功  name=收货入库明细-实收  field_id=<field_id>
  追加字段成功  name=收货入库明细-差异  field_id=<field_id>
  追加字段成功  name=收货入库明细-质检  field_id=<field_id>
  追加字段成功  name=收货入库明细-签收人  field_id=<field_id>
[步骤2] 文件类别创建成功  name=验收单  category_id=<category_id>

配置完成  workspace_id=<workspace_id>
  国内票-数电票: category_id=<category_id>
  采购合同:      category_id=<category_id>
  入库单:        category_id=<category_id>
  验收单:        category_id=<category_id>

开始上传待处理文件...
[步骤3] 文件上传成功  name=sample_invoice.pdf  batch_number=<batch_number>
[步骤3] 文件上传成功  name=sample_contract.pdf  batch_number=<batch_number>
[步骤3] 文件上传成功  name=sample_inbound.pdf  batch_number=<batch_number>
[步骤3] 文件上传成功  name=sample_acceptance.pdf  batch_number=<batch_number>

开始获取处理结果...
[步骤4] 等待处理结果（batch_number=<batch_number>）..... 完成

============================================================
文件名   : sample_invoice.pdf
分类结果 : 国内票-数电票

── 普通字段 ──────────────────────────
  发票号码                : 25442000000012345678
  开票日期                : 2025-01-15
  价税合计                : 50,900.00
  税前金额                : 48,000.00
  税额                   : 2,900.00
  销售方名称               : 上海某某科技有限公司
  销售方纳税人识别号         : 91310000XXXXXXXXXX
  购买方名称               : 合合信息科技（上海）有限公司
  购买方纳税人识别号         : 91310000YYYYYYYYYY

── 表格行数据 ────────────────────────
  第1行: 商品名称=智能硬件设备  |  规格型号=XH-2000  |  单位=台  |  数量=10  |  单价=4,800.00  |  金额=48,000.00  |  税率=6%  |  税额=2,880.00

[步骤4] 等待处理结果（batch_number=<batch_number>）......... 完成

============================================================
文件名   : sample_contract.pdf
分类结果 : 采购合同

── 普通字段 ──────────────────────────
  编号                   : HT-2025-001
  甲方                   : 合合信息科技（上海）有限公司
  乙方                   : 上海某某科技有限公司
  签订日期                : 2025-01-10
  采购金额                : 50,900.00
  税率                   : 6%
  乙方税号                : 91310000XXXXXXXXXX

[步骤4] 等待处理结果（batch_number=<batch_number>）...... 完成

============================================================
文件名   : sample_inbound.pdf
分类结果 : 入库单

── 普通字段 ──────────────────────────
  收货单编号               : RK-2025-0115
  收货日期                : 2025-01-20
  对应合同号               : HT-2025-001
  供应商名称               : 上海某某科技有限公司
  入库总金额               : 50,900.00
  供应商税号               : 91310000XXXXXXXXXX

[步骤4] 等待处理结果（batch_number=<batch_number>）.... 完成

============================================================
文件名   : sample_acceptance.pdf
分类结果 : 验收单

── 普通字段 ──────────────────────────
  合同编号                : HT-2025-001
  甲方单位名称              : 合合信息科技（上海）有限公司
  乙方单位名称              : 上海某某科技有限公司
  验收结论                : 验收合格

开始配置审核规则库...
[步骤5] 规则库创建成功  name=AP审单场景审核规则库  repo_id=<repo_id>
  规则组创建成功  name=供应商一致性校验  group_id=<group_id>
    规则创建成功  name=供应商一致性  rule_id=<rule_id>
    规则创建成功  name=发票与合同金额匹配  rule_id=<rule_id>
    规则创建成功  name=发票购买方与合同甲方一致  rule_id=<rule_id>
  规则组创建成功  name=入库与合同一致性  group_id=<group_id>
    规则创建成功  name=入库数量与合同数量匹配  rule_id=<rule_id>
    规则创建成功  name=入库单号关联合同号  rule_id=<rule_id>
  规则组创建成功  name=验收合规性  group_id=<group_id>
    规则创建成功  name=验收单与入库单物料一致  rule_id=<rule_id>
[步骤6] 审核任务提交成功  task_id=<task_id>
[步骤7] 等待审核结果（task_id=<task_id>）................. 完成

============================================================
审核任务状态  : 审核通过
规则通过数    : 6
规则不通过数  : 0

── 规则组：供应商一致性校验 ───────────────────
  ✓ [高风险] 供应商一致性: 审核通过
    依据: 发票销售方纳税人识别号与采购合同乙方税号均为 91310000XXXXXXXXXX，一致。
  ✓ [高风险] 发票与合同金额匹配: 审核通过
    依据: 发票价税合计 50,900.00 与采购合同采购金额 50,900.00 完全一致。
  ✓ [中风险] 发票购买方与合同甲方一致: 审核通过
    依据: 发票购买方"合合信息科技（上海）有限公司"与合同甲方一致。

── 规则组：入库与合同一致性 ───────────────────
  ✓ [高风险] 入库数量与合同数量匹配: 审核通过
    依据: 入库单实收数量 10 台与采购合同约定数量 10 台一致。
  ✓ [中风险] 入库单号关联合同号: 审核通过
    依据: 入库单对应合同号 HT-2025-001 与采购合同编号一致。

── 规则组：验收合规性 ───────────────────
  ✓ [中风险] 验收单与入库单物料一致: 审核通过
    依据: 验收单合同编号与入库单对应合同号均为 HT-2025-001，物料关联一致。

============================================================
  示例运行完成
============================================================
```

## 09 结果说明

### 抽取结果

处理完成后，每份文件将返回分类结果和字段抽取结果。字段抽取结果位于 `data.fields[]`，表格字段位于 `data.items[][]`，每个字段包含 `key`、`value` 及坐标 `position`（可用于原文高亮回显）。

以下为发票样本文件的实际接口返回（来自 `file/fetch`，省略了部分 `position` 坐标）：

> [accordion] sample\_invoice.pdf
>
> ```json theme={null}
> {
>   "id": "2029124607672344576",
>   "name": "sample_invoice.pdf",
>   "format": "pdf",
>   "category": "国内票-数电票",
>   "recognition_status": 1,
>   "duration_ms": 4832,
>   "data": {
>     "fields": [
>       { "key": "发票号码",           "value": "25442000000012345678" },
>       { "key": "开票日期",           "value": "2025-01-15" },
>       { "key": "价税合计",           "value": "50900.00" },
>       { "key": "税前金额",           "value": "48000.00" },
>       { "key": "税额",              "value": "2900.00" },
>       { "key": "销售方名称",          "value": "上海某某科技有限公司" },
>       { "key": "销售方纳税人识别号",   "value": "91310000XXXXXXXXXX" },
>       { "key": "购买方名称",          "value": "合合信息科技（上海）有限公司" },
>       { "key": "购买方纳税人识别号",   "value": "91310000YYYYYYYYYY" },
>       { "key": "发票备注",           "value": "" }
>     ],
>     "items": [
>       [
>         { "key": "商品名称", "value": "智能硬件设备" },
>         { "key": "规格型号", "value": "XH-2000" },
>         { "key": "单位",    "value": "台" },
>         { "key": "数量",    "value": "10" },
>         { "key": "单价",    "value": "4800.00" },
>         { "key": "金额",    "value": "48000.00" },
>         { "key": "税率",    "value": "6%" },
>         { "key": "税额",    "value": "2880.00" }
>       ]
>     ],
>     "stamps": [],
>     "handwritings": []
>   }
> }
> ```

### 审核结果

审核完成后，可从 `review/task/result` 接口获取以下信息：

* **`status`**：任务整体状态（`1`=审核通过，`4`=审核不通过，`2`=审核失败）
* **`statistics`**：规则通过数、不通过数汇总
* **`groups[].review_tasks[]`**：每条规则的详细审核结果，包含：
  * `review_result`：该规则的审核结论（`1`=通过，`4`=不通过）
  * `reasoning`：AI 给出的审核依据说明
  * `anchors`：依据在原文中的坐标位置（可用于高亮回显）

```json theme={null}
{
  "task_id": "31415926",
  "task_name": "AP审核",
  "status": 1,
  "statistics": { "pass_count": 6, "failure_count": 0, "error_count": 0 },
  "groups": [
    {
      "group_name": "供应商一致性校验",
      "review_tasks": [
        {
          "rule_name": "供应商一致性",
          "risk_level": 10,
          "review_result": 1,
          "reasoning": "发票销售方纳税人识别号与采购合同乙方税号均为 91310000XXXXXXXXXX，一致，审核通过。"
        },
        {
          "rule_name": "发票与合同金额匹配",
          "risk_level": 10,
          "review_result": 1,
          "reasoning": "发票价税合计 50900.00 与采购合同采购金额 50900.00 完全一致，审核通过。"
        },
        {
          "rule_name": "发票购买方与合同甲方一致",
          "risk_level": 20,
          "review_result": 1,
          "reasoning": "发票购买方"合合信息科技（上海）有限公司"与采购合同甲方一致，审核通过。"
        }
      ]
    },
    {
      "group_name": "入库与合同一致性",
      "review_tasks": [
        {
          "rule_name": "入库数量与合同数量匹配",
          "risk_level": 10,
          "review_result": 1,
          "reasoning": "入库单实收数量 10 台与采购合同约定数量 10 台一致，审核通过。"
        },
        {
          "rule_name": "入库单号关联合同号",
          "risk_level": 20,
          "review_result": 1,
          "reasoning": "入库单对应合同号 HT-2025-001 与采购合同编号一致，审核通过。"
        }
      ]
    },
    {
      "group_name": "验收合规性",
      "review_tasks": [
        {
          "rule_name": "验收单与入库单物料一致",
          "risk_level": 20,
          "review_result": 1,
          "reasoning": "验收单合同编号与入库单对应合同号均为 HT-2025-001，物料关联一致，审核通过。"
        }
      ]
    }
  ]
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.