跳转至

文档(DocumentController)

提供表单数据(Document)的 CRUD、批量保存/删除、局部更新、表单校验,以及视图子表缓存的增删等能力,是 runtime 模块表单数据域的核心控制器。本控制器所有端点均返回 JSON 资源。

  • 接口类型:REST 资源(@RestController,类级 produces = APPLICATION_JSON_VALUE
  • 基址${myapps.context-path.runtime:}/api/runtime/{applicationId}
  • Tag:document

公共说明

  • 鉴权(据源码 RuntimeMvcConfig + RestSecurityHandlerInterceptor:拦截器注册到 /api/runtime/**/api/rest/bpm/**,本控制器路径位于 /api/runtime/{applicationId}/...不在豁免名单(豁免名单仅覆盖 /api/runtime/login.*/api/runtime/dingding/authlogin/api/runtime/synchronization.*/runtime/sync/.* 等,详见 login.md「公共说明 · 鉴权」)。拦截器对非 /rest/ 路径走 Security.getUserIdFromToken(request),未取到再尝试 Security.getDebugUserIdFromToken(request),两者皆无则拒绝访问。因此所有端点均需 accessToken(或 debugToken),可通过 Cookie / 请求头 / query 参数任一方式传递。
  • 路径变量 {applicationId}:必填,经 DES 加密(按当前执行用户密钥),服务端在方法入口处 DesUtil.decryptTextByUserId(applicationId, getUser().getId()) 解密。
  • 其它加密 id:路径与请求体中的 idparentIdchildIdviewId、批量删除数组中的元素等,均按当前执行用户密钥做 DES 加密后传输;服务端逐个解密。请求体中字段值若为加密串也会被 DesUtil.decryptTextByUserId 还原(见 AbstractRuntimeController.getParams())。
  • Document 请求体:除 PATCH 与 GET 外,POST/PUT 端点的 @RequestBodyDocument JSON 字符串,由 AbstractRuntimeController.prepareDocument() 解析。结构如下(字段缺省按需传入):
    {
      "id": "<文档Id,DES 加密密文;新建可空>",
      "formId": "<表单Id,必填>",
      "viewId": "<视图Id,可选>",
      "stateId": "<流程实例Id,可选>",
      "parentId": "<父文档Id,DES 加密密文,可选>",
      "sign": "<签名,可选>",
      "isRelate": "<是否关联父文档:'true'/'false',可选>",
      "items": { "<字段名>": "<字段值>" },
      "subDocuments": [ { "...": "嵌套子文档,结构同上" } ],
      "delete": false,
      "edit": false,
      "exparams": { "<额外参数名>": "<值>" }
    
    formId 用于加载表单定义;items 为字段名到字段值的映射(选项类字段的显示值会在服务端转换为存储值)。
  • 响应结构:统一 Resource(见 ../index.md「统一响应结构」),字段为 errcode/errmsg/data/errorsResource.data 的类型见各端点说明。
  • 分页响应GET /documentssuccessWithPaginationResource.dataJSONObject,结构为:
    {
      "data": [ <Document>, ... ],
      "page": <当前页号>,
      "page_lines": <每页条数>,
      "row_count": <总记录数>
    }
    
    (上述字段名 page/page_lines/row_count 与底层 DataPackagepageNo/linesPerPage/rowCount 不同,以控制器实际响应为准。)
  • HTTP 状态码:成功默认 200;其中 POST /documentsPOST /documents/withoutValid 类级标注 @ResponseStatus(HttpStatus.CREATED),正常返回 HTTP 201。业务错误由响应体 errcode 体现(错误码表见 ../index.md)。ResourceNotFoundException → HTTP 404;Exception/OBPMValidateException → HTTP 500;MethodArgumentTypeMismatchException → HTTP 406(errcode=40035);PathNotFoundException(JsonPath 解析失败)→ HTTP 406(errcode=406)。

1. 获取文档

根据文档 Id 获取单个文档对象。文档不存在时抛 ResourceNotFoundException,由全局异常处理器返回 404。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/documents/{id}(完整:{runtime-context}/api/runtime/{applicationId}/documents/{id}
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
id path string 文档Id(DES 加密密文)

请求示例

GET /api/runtime/__APPID__/documents/__DOCID__ HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataDocument,文档对象(含字段值、子文档、流程状态引用等)。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "id": "__DOCID__",
    "formid": "form-001",
    "applicationid": "app-001",
    "items": [{ "name": "金额", "value": "1200.00" }],
    "state": null,
    "subDocuments": []
  },
  "errors": null
}

失败示例(文档不存在)

{
  "errcode": 404,
  "errmsg": "Not Found",
  "data": null,
  "errors": null
}


2. 创建文档(带校验)

新建文档并执行表单校验;校验通过后落库,并处理嵌套子文档的增删改。校验失败返回 errcode=4001

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/documents(完整:{runtime-context}/api/runtime/{applicationId}/documents
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string(Document) Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

POST /api/runtime/__APPID__/documents HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "formId": "__FORMID__",
  "items": {
    "金额": "1200.00",
    "事由": "客户拜访"
  }
}

响应

结构:统一 ResourcedataDocument,保存后的文档对象(含服务端生成的 id、重计算后的字段值等)。HTTP 状态码为 201(@ResponseStatus(CREATED))。

成功示例

{
  "errcode": 0,
  "errmsg": "保存成功",
  "data": { "id": "__NEWDOCID__", "formid": "__FORMID__", "items": [] },
  "errors": null
}

失败示例(表单校验不通过)

{
  "errcode": 4001,
  "errmsg": "表单校验不通过",
  "data": null,
  "errors": [
    { "errcode": 40001, "errmsg": "金额不能为空", "field": "金额" }
  ]
}

失败示例(服务端异常)

{ "errcode": 500, "errmsg": "<异常信息>", "data": null, "errors": null }


3. 创建文档(不校验)

新建文档但不执行表单校验,直接落库;同样会处理嵌套子文档的增删改。

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/documents/withoutValid(完整:{runtime-context}/api/runtime/{applicationId}/documents/withoutValid
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string(Document) Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

POST /api/runtime/__APPID__/documents/withoutValid HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "formId": "__FORMID__",
  "items": { "金额": "1200.00" }
}

响应

结构:统一 ResourcedataDocument,保存后的文档对象。HTTP 状态码为 201。

成功示例

{
  "errcode": 0,
  "errmsg": "保存成功",
  "data": { "id": "__NEWDOCID__", "formid": "__FORMID__" },
  "errors": null
}

失败示例(服务端异常)

{ "errcode": 500, "errmsg": "<异常信息>", "data": null, "errors": null }


4. 更新文档(不校验)

更新已有文档,不执行表单校验。会同步处理嵌套子文档的增删改,并校正失效的流程实例引用。

  • 接口类型:REST 资源
  • 请求方式PUT
  • 请求路径/documents/{id}/withoutValid(完整:{runtime-context}/api/runtime/{applicationId}/documents/{id}/withoutValid
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
id path string 文档Id(仅用于路由匹配;实际更新目标以请求体内的 id 为准)
content body string(Document) Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

PUT /api/runtime/__APPID__/documents/__DOCID__/withoutValid HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "id": "__DOCID__",
  "formId": "__FORMID__",
  "items": { "金额": "1500.00" }
}

响应

结构:统一 ResourcedataDocument,更新后的文档对象。

成功示例

{
  "errcode": 0,
  "errmsg": "保存成功",
  "data": { "id": "__DOCID__", "formid": "__FORMID__" },
  "errors": null
}

失败示例(异常被包装为校验失败)

{
  "errcode": 4001,
  "errmsg": "文档校验不通过",
  "data": null,
  "errors": [
    { "errcode": 40001, "errmsg": "<异常信息>", "field": "" }
  ]
}

说明:服务端捕获异常后统一以 errcode=4001「文档校验不通过」 返回,errors[0].errmsg 承载实际异常描述(如 OBPMValidateException 校验信息、字段超长 Data too long for column 等)。


5. 更新文档(带校验)

更新已有文档,先执行表单校验(含子表单逐条校验),通过后落库并校正流程实例引用。

  • 接口类型:REST 资源
  • 请求方式PUT
  • 请求路径/documents/{id}(完整:{runtime-context}/api/runtime/{applicationId}/documents/{id}
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
id path string 文档Id(仅用于路由匹配;实际更新目标以请求体内的 id 为准)
content body string(Document) Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

PUT /api/runtime/__APPID__/documents/__DOCID__ HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "id": "__DOCID__",
  "formId": "__FORMID__",
  "items": { "金额": "1500.00" }
}

响应

结构:统一 ResourcedataDocument,更新后的文档对象。

成功示例

{
  "errcode": 0,
  "errmsg": "保存成功",
  "data": { "id": "__DOCID__", "formid": "__FORMID__" },
  "errors": null
}

失败示例(表单校验不通过)

{
  "errcode": 4001,
  "errmsg": "表单校验不通过",
  "data": null,
  "errors": [{ "errcode": 40001, "errmsg": "金额必须大于 0", "field": "金额" }]
}

失败示例(子表单校验不通过)

{
  "errcode": 4001,
  "errmsg": "子表单校验不通过",
  "data": null,
  "errors": [{ "errcode": 40001, "errmsg": "明细数量不能为空", "field": "数量" }]
}


6. 批量更新文档(带校验)

在一次事务内批量更新与删除多个文档:先校验并更新 edit==true && delete!=true 的文档,再删除 delete==true 的文档(避免先删后插导致同 id 重建)。

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/documents/batch(完整:{runtime-context}/api/runtime/{applicationId}/documents/batch
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string 批量请求 JSON 字符串(结构见下)

请求体

{
  "data": [
    {
      "edit": true,
      "id": "<文档Id,DES 加密密文>",
      "formId": "<表单Id>",
      "items": { "<字段名>": "<字段值>" }
    },
    {
      "delete": true,
      "id": "<文档Id,DES 加密密文>",
      "parentId": "<父文档Id,DES 加密密文,删除子文档时需要>"
    }
  ]
}

服务端通过 JsonPath $.data[?(@.edit == true && @.delete != true)] 提取待更新集合,通过 $.data[?(@.delete == true)] 提取待删除集合。

请求示例

POST /api/runtime/__APPID__/documents/batch HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "data": [
    { "edit": true, "id": "__DOCID1__", "formId": "__FORMID__", "items": { "金额": "1500.00" } },
    { "delete": true, "id": "__DOCID2__", "parentId": "__PARENTID__" }
  ]
}

响应

结构:统一 ResourcedataList<Document>,更新成功的文档集合(被删除的文档不在列表中)。

成功示例

{
  "errcode": 0,
  "errmsg": "保存成功",
  "data": [
    { "id": "__DOCID1__", "formid": "__FORMID__" }
  ],
  "errors": null
}

失败示例(校验不通过,整体回滚)

{
  "errcode": 4001,
  "errmsg": "表单校验不通过",
  "data": null,
  "errors": [{ "errcode": 40001, "errmsg": "<校验错误>", "field": "<字段名>" }]
}

失败示例(异常,整体回滚)

{ "errcode": 500, "errmsg": "<异常信息>", "data": null, "errors": null }


7. 删除文档

根据文档 Id 删除单个文档,并从用户私有缓存中清除。

  • 接口类型:REST 资源
  • 请求方式DELETE
  • 请求路径/documents/{id}(完整:{runtime-context}/api/runtime/{applicationId}/documents/{id}
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
id path string 文档Id(DES 加密密文)

请求示例

DELETE /api/runtime/__APPID__/documents/__DOCID__ HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resourcedatanull

成功示例

{ "errcode": 0, "errmsg": "ok", "data": null, "errors": null }


8. 获取文档集合(分页)

按过滤条件分页查询文档列表。返回分页封装结构。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/documents(完整:{runtime-context}/api/runtime/{applicationId}/documents
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string 过滤条件 JSON(整体作为 filter Map 传入);可空
sortby query/form string 排序字段(源码方法签名未显式标注 @RequestParam,按名称绑定 query/form 均可)
order query/form string 排序方向(升序/降序)
_pagelines query int 每页条数,缺省走平台默认值(Web.DEFAULT_LINES_PER_PAGE

说明:分页参数 _pagelines_page 等通过 ParamsTable.convertHTTP(request) 统一抽取(见 AbstractRuntimeController.getParams())。

请求示例

GET /api/runtime/__APPID__/documents?sortby=lastModified&order=desc&_pagelines=20 HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

带过滤条件时(body 为过滤 JSON):

GET /api/runtime/__APPID__/documents?_pagelines=20 HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{ "金额": "1200.00" }

响应

结构:统一 Resourcedata:分页 JSONObject(见本页「公共说明 · 分页响应」),含 data/page/page_lines/row_count 四个字段。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "data": [
      { "id": "__DOCID1__", "formid": "__FORMID__" },
      { "id": "__DOCID2__", "formid": "__FORMID__" }
    ],
    "page": 1,
    "page_lines": 20,
    "row_count": 53
  },
  "errors": null
}


9. 批量删除文档

按文档 Id 数组批量删除,并从用户私有缓存中清除。

  • 接口类型:REST 资源
  • 请求方式DELETE
  • 请求路径/documents(完整:{runtime-context}/api/runtime/{applicationId}/documents
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string DES 加密文档Id 的 JSON 数组字符串

请求体

["__ENC_DOCID1__", "__ENC_DOCID2__"]

请求示例

DELETE /api/runtime/__APPID__/documents HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

["__ENC_DOCID1__", "__ENC_DOCID2__"]

响应

结构:统一 Resourcedatanull

成功示例

{ "errcode": 0, "errmsg": "ok", "data": null, "errors": null }


10. 更新缓存中子表数据

视图子表行编辑场景:将一行子文档暂存到主文档的用户私有缓存(不入库),并返回确认脚本执行结果与变化字段。

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/views/{viewId}/documents/{parentId}/childs(完整:{runtime-context}/api/runtime/{applicationId}/views/{viewId}/documents/{parentId}/childs
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
viewId path string 视图Id(DES 加密密文)
parentId path string 主表文档Id(DES 加密密文)
content body string(Document) 子文档 Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

POST /api/runtime/__APPID__/views/__VIEWID__/documents/__PARENTID__/childs HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "formId": "__SUBFORMID__",
  "items": { "数量": "10", "单价": "20.00" }
}

响应

结构:统一 ResourcedataJSONObject,可能的字段: - type(string,可选):视图「确认活动脚本」返回的 JsMessage.type(如 TYPE_DANGER)。 - content(string,可选):确认脚本返回的提示文案。 - changedField(array,可选):本次相对原值发生变化的字段列表,每个元素为 { "<字段名>": "<新值>" }

字段缺失时该键不出现。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "type": "danger",
    "content": "数量超过上限",
    "changedField": [{ "数量": "10" }, { "金额": "200.00" }]
  },
  "errors": null
}

失败示例(校验不通过)

{
  "errcode": 4001,
  "errmsg": "校验不通过",
  "data": null,
  "errors": [{ "errcode": 40001, "errmsg": "<校验错误>", "field": "<字段名>" }]
}


11. 删除缓存中子表数据

视图子表行编辑场景:从主文档的用户私有缓存中移除一行子文档,并执行视图「删除活动脚本」。仅作用于缓存,不入库。

  • 接口类型:REST 资源
  • 请求方式DELETE
  • 请求路径/views/{viewId}/documents/{parentId}/childs/{childId}(完整:{runtime-context}/api/runtime/{applicationId}/views/{viewId}/documents/{parentId}/childs/{childId}
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
viewId path string 视图Id(DES 加密密文)
parentId path string 主表文档Id(DES 加密密文)
childId path string 子文档Id(DES 加密密文)

请求示例

DELETE /api/runtime/__APPID__/views/__VIEWID__/documents/__PARENTID__/childs/__CHILDID__ HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resourcedatanull

成功示例

{ "errcode": 0, "errmsg": "ok", "data": null, "errors": null }


12. 校验文档

按 Document 请求体执行表单校验,不落库。用于提交前的预校验。

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/documents/validate(完整:{runtime-context}/api/runtime/{applicationId}/documents/validate
  • 鉴权:是(需 accessToken,据源码)
  • Tag:document

请求参数

参数名 位置 类型 必填 说明
applicationId path string 应用Id(DES 加密密文)
content body string(Document) Document JSON 字符串(结构见本页「公共说明 · Document 请求体」)

请求示例

POST /api/runtime/__APPID__/documents/validate HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "formId": "__FORMID__",
  "items": { "金额": "1200.00" }
}

响应

结构:统一 Resourcedata:校验通过为 null;不通过时 data=nullerrors 携带错误明细(每个错误的 errmsg 已剥离单引号)。

成功示例

{ "errcode": 0, "errmsg": "ok", "data": null, "errors": null }

失败示例

{
  "errcode": 4001,
  "errmsg": "表单校验不通过",
  "data": null,
  "errors": [{ "errcode": 40001, "errmsg": "金额必须大于 0", "field": "金额" }]
}