跳转至

页面小工具执行(PageWidgetController)

页面小工具(首页 Widget)执行接口:获取/保存用户首页 Widget 配置(PC + 手机端)、获取指定 Widget 内容、首页三类待办聚合查询(我的待办 / 我的经办 / 我的抄办,跨当前用户所有软件)。

  • 接口类型:REST 资源(@Component 继承 AbstractRuntimeController;类级 produces = MediaType.APPLICATION_JSON_UTF8_VALUE,方法返回类型为 Resource,由 Spring Jackson 序列化为 JSON,据源码)
  • 基址${myapps.context-path.runtime:}/api/runtime
  • Tag:页面小工具执行模块

公共说明

  • 鉴权(据源码):类级基址位于 /api/runtime/**,在 RestSecurityHandlerInterceptor 覆盖范围内,且不在豁免名单(豁免仅覆盖 /api/runtime/login.*/api/runtime/dingding/authlogin/api/runtime/synchronization.*、URI 以 /showjrxml 结尾、含 /getCustomColumnsInfos、含 /accessToken、含 /macro、以 /clear 结尾、含 /pages/ 等,详见 login.md「公共说明 · 鉴权」)。拦截器走 Security.getUserIdFromToken(request),未取到再尝试 Security.getDebugUserIdFromToken(request),两者皆无则拒绝。故需 accessToken(或 debugToken),可通过 Cookie / 请求头 / query 参数任一方式传递。控制器内 getUser()(继承自 AbstractRuntimeController)必须能取到非空 WebUser,否则在 DesUtil.decryptTextByUserId(applicationId, getUser().getId()) 时即抛 NPE。
  • 路径变量 {applicationId}:在 #1/#3 中为 DES 加密密文,服务端 DesUtil.decryptTextByUserId(applicationId, getUser().getId()) 解密;在 #2/#4/#5/#6/#7 中为 query 参数(required=false),DES 解密后允许为 null
  • 响应结构:本控制器响应使用统一 Resource(见 ../index.md「统一响应结构」)。

1. 获取指定 Widget 内容

widgetId 加载并返回小工具内容(PageWidgetRunTimeService.displayWidget,参数含 getParams() 全量 query 参数)。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/{applicationId}/widgets/{widgetId}(完整:{runtime-context}/api/runtime/{applicationId}/widgets/{widgetId}
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId path string 软件id(DES 加密密文)
widgetId path string 小工具id(DES 加密密文)

请求示例

GET /api/runtime/__APPID__/widgets/__WIDGETID__ HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataObject(由 displayWidget 决定,视小工具类型而定)。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": { "id": "__WIDGETID__", "type": "view", "content": "..." },
  "errors": null
}

失败示例

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


2. 获取指定用户首页 Widget 配置

applicationIdisMobile 读取当前用户的首页小工具配置(PageWidgetRunTimeService.getUserPageWidgetSetting),并对类型为 summary/view/customizeReport/chart/system_workflow/carboncopy/carousel 的小工具的 actionContent/applicationId 字段经 DES 加密后返回。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/homepage/config(完整:{runtime-context}/api/runtime/homepage/config
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId query string 软件id(DES 加密密文)
isMobile query boolean 是否移动端,由 getParams().getParameterAsBoolean("isMobile") 解析,默认 false

请求示例

GET /api/runtime/homepage/config?applicationId=__ENC_APPID__&isMobile=false HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataJSONObject,含 widgets(key 为 widgetId,value 为 widget 配置)与 setting(首页布局配置)两个子对象;类型为视图/统计图/报表/系统流程/抄送/轮播等的 widget 中 actionContent/applicationId 已 DES 加密。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "widgets": {
      "__WIDGETID__": {
        "id": "__WIDGETID__",
        "type": "view",
        "actionContent": "__ENC_VIEWID__",
        "applicationId": "__ENC_APPID__"
      }
    },
    "setting": { "layout": "grid" }
  },
  "errors": null
}

失败示例

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


3. 获取手机端(微信)首页 Widget 配置

applicationId 加载软件级别的 Widget 系统设置(Application.systemWidgetSetting),为空时返回默认配置(Banner=truemenuIcon=truesystem_workflow=true)。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/{applicationId}/homepage/phoneConfig(完整:{runtime-context}/api/runtime/{applicationId}/homepage/phoneConfig
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

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

请求示例

GET /api/runtime/__APPID__/homepage/phoneConfig HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataJSONObject,软件级 Widget 系统设置;为空时返回默认 {Banner:true, menuIcon:true, system_workflow:true}

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": { "Banner": true, "menuIcon": true, "system_workflow": true },
  "errors": null
}

失败示例

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


4. 保存用户首页 Widget 配置

将用户首页 Widget 模板字符串保存到 UserDefined(按用户 + 应用维度去重,存在则更新 templateElement,不存在则新建),关联当前用户与 applicationId

  • 接口类型:REST 资源
  • 请求方式POST
  • 请求路径/homepage/config(完整:{runtime-context}/api/runtime/homepage/config
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId query string 软件id(DES 加密密文)
content body string(JSON) 首页 Widget 模板 JSON 字符串;为空时存为空串,非空时仅做 JSONObject.parseObject(...).toJSONString() 规范化

请求示例

POST /api/runtime/homepage/config?applicationId=__ENC_APPID__ HTTP/1.1
Content-Type: application/json
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

{
  "widgets": { "__WIDGETID__": { "type": "view" } },
  "setting": { "layout": "grid" }
}

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 datanull

成功示例

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

说明:源码对 body 解析异常仅 e.printStackTrace() 并继续以 templateElement = null/规范化后值入库,仍返回 errcode=0


5. 我的待办(跨多个软件)

聚合查询当前用户在所有可见软件下的待办(WorkProcessBean.getPendingList,含流程代理),支持按 applicationId 过滤单个软件;按 lastProcessTime 倒序后内存分页。每条 WorkVO.docId 已按当前用户密钥 DES 加密(保留 -- 后的 sealed 段)。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/widget/myPending(完整:{runtime-context}/api/runtime/widget/myPending
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId query string 软件id(DES 加密密文);非空时仅查询该软件,为空时遍历当前用户全部 applicationIds
pageNo query int 页码,默认 1
linesPerPage query int 每页条数,默认 5

请求示例

GET /api/runtime/widget/myPending?applicationId=__ENC_APPID__&pageNo=1&linesPerPage=5 HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataDataPackage<WorkVO>,含 datas: List<WorkVO>(当前页)、rowCount: int(跨软件合计)、linesPerPagepageNodocId 字段已 DES 加密。

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "datas": [
      { "id": "__WORKID__", "docId": "__ENC_DOCID__", "flowName": "请假流程", "lastProcessTime": "2026-08-01 10:00:00" }
    ],
    "rowCount": 23,
    "linesPerPage": 5,
    "pageNo": 1
  },
  "errors": null
}

失败示例

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


6. 我的经办(跨多个软件)

聚合查询当前用户在所有可见软件下的经办(WorkProcessBean.getProcessedRunningListFlowInterventionVO.STATUS_PENDING),支持按 applicationId 过滤;按 lastProcessTime 倒序后内存分页。docId 已 DES 加密。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/widget/myProcessing(完整:{runtime-context}/api/runtime/widget/myProcessing
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId query string 软件id(DES 加密密文);非空时仅查询该软件
pageNo query int 页码,默认 1
linesPerPage query int 每页条数,默认 5

请求示例

GET /api/runtime/widget/myProcessing?pageNo=1&linesPerPage=5 HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataDataPackage<WorkVO>,结构同 #5

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "datas": [
      { "id": "__WORKID__", "docId": "__ENC_DOCID__", "flowName": "报销流程", "lastProcessTime": "2026-07-30 14:00:00" }
    ],
    "rowCount": 8,
    "linesPerPage": 5,
    "pageNo": 1
  },
  "errors": null
}

失败示例

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


7. 我的抄送(跨多个软件)

聚合查询当前用户在所有可见软件下的抄送记录(FlowCenterRumTimeService.carboncopy),支持按 applicationId 过滤与已读过滤;按 lastProcessTime 倒序后内存分页。

  • 接口类型:REST 资源
  • 请求方式GET
  • 请求路径/widget/myCopy(完整:{runtime-context}/api/runtime/widget/myCopy
  • 鉴权:是(需 accessToken,据源码)
  • Tag:页面小工具执行模块

请求参数

参数名 位置 类型 必填 说明
applicationId query string 软件id(DES 加密密文);非空时仅查询该软件
pageNo query int 页码,默认 1
linesPerPage query int 每页条数,默认 5
isread query boolean 是否已读过滤;由 getParams().getParameterAsBoolean("isread") 解析,源码据此设置内部 _isRead(1/0)

请求示例

GET /api/runtime/widget/myCopy?pageNo=1&linesPerPage=5&isread=false HTTP/1.1
Cookie: accessToken=eyJhbGciOiJIUzI1NiJ9...

响应

结构:统一 Resource(见 ../index.md「统一响应结构」)。 dataDataPackage<Object>,含 datas: List<Map>(当前页,每条为抄送行 MaplastProcessTime 等)、rowCount: int(跨软件合计)、linesPerPagepageNo

成功示例

{
  "errcode": 0,
  "errmsg": "ok",
  "data": {
    "datas": [
      { "id": "__COPYID__", "flowName": "请假流程", "lastProcessTime": "2026-07-28 09:00:00" }
    ],
    "rowCount": 3,
    "linesPerPage": 5,
    "pageNo": 1
  },
  "errors": null
}

失败示例

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