0. 概述
- 待办中心API,用于任务源头系统和任务中心系统进行集成
- 应用系统(任务源)可以选择通过推或者拉的方式,将任务同步到待办中心系统中
1. 技术规范
1.1. OAuth2授权
1.2. GraphQL接口
变更定义:
type Mutation {
# Mutation【1】:全量同步一个流程实例,待办中心会最终与传入Process及其Tasks信息保持一致
# ProcessInput 数据结构和 Process 一致
syncProcess(process:ProcessInput!, timestamp:Long):Process
# Mutation【2】:增量同步一个流程实例及其的Tasks列表,Tasks列表内容按Id视为新增或更新
pushProcess(process:ProcessInput!, timestamp:Long):Process
# Mutation【3】:增量删除一个流程实例的Tasks列表,Tasks列表仅需给出Id即可
deleteTasks(process:ProcessInput!, timestamp:Long):Process
# Mutation【4】:删除一个流程实例,仅需给出Id(或entry+system)即可
deleteProcess(process:ProcessInput!, timestamp:Long):Process
}
- timestamp给出该Process变更的毫秒级Unix时间戳。待办中心按照此时间戳保障任务级的时间箭头的一致性
查询定义:
type Query {
# Query【1】:根据流程Id或“流水号+系统”查询给定流程实例及其任务详情
process(id:Long, entry:Long, system:String):Process
# Query【2】:查询用户的任务列表,cate可选范围:[todo],含义:[待办]
tasks(cate:String!, userId:String, filter:TaskFilter):[Task!]
# Query【2P】:同上,但支持分页
tasksPaged(cate:String!, userId:String, first: Int, offset: Int, filter:TaskFilter):TaskConnection
###
# Query【3】:查询用户的流程实例列表
# cate可选范围:[doing|done|completed],含义:[进行中]已完成|doing+done] order:[create asc|create desc|update asc|update desc],含义:[创建时间升序]创建时间升序|更新时间升序|更新时间降序]
# keyword:[流水号|来源名称|实例名称|发起人账号|发起人姓名]
###
processes(cate:String!, userId:String, keyword:String, page: Int, size: Int, filter: ProcessFilter, order: String):ProcessConnection
# Query【4】:查询应用自身的流程
processesAdmin(cate:String, first: Int, offset: Int, filter: ProcessFilter): ProcessConnection
# Query【5】:查询系统及其统计,filter支持 "userId-eq"
systemStat(filter:SystemStatFilter): [System!]
# Query【6】:查询用户可办理流程(应用)列表,含义:[可办]
apps(userId:String):[App!]
}
订阅定义(pubsub):
type Subscription {
# Subscription【1】
tasks(cate:String!, userId:String!, timestamp:Long!):[Tasks]
}
- 格式同 Query【2】,增加 timestamp:Long 参数用于指定订阅消息开始的时间。
- 通过 WebSocket 实现,用于 Web 页面的实时刷新
2. 方案
- 每个应用(任务源)可根据自身的特性,选择推、拉等方式或者其组合。
- 在此基础上建立的办事大厅需使用Query【2】、【3】和 Subscription【1】来实现。
2.1. 方案比较
| 方案 |
实现难度 |
实时性 |
页面性能 |
压力 |
统计分析 |
待办通知 |
| 拉模式 |
简单 |
实时 |
低 |
低 |
不支持 |
不支持 |
| 按实例全量推 |
中等 |
较差 |
高 |
高 |
支持 |
可支持 |
| 按实例增量推 |
复杂 |
中等 |
高 |
中 |
支持 |
可支持 |
| 推拉结合 |
复杂 |
实时 |
低 |
高 |
支持 |
可支持 |
拉模式
按实例全量推
- 任务源通过调用 Mutation【1】【4】实现
- 可同时实现上述“拉模式”接口以提高实时性
按实例增量推
- 任务源通过调用 Mutation【2】【3】【4】实现,为保障数据一致性,需辅助使用Query【1】对比。
- 可同时实现上述“拉模式”接口以提高实时性
推拉结合
附录:数据结构定义
- 本节定义本组API的 GraphQL Schema
附1. 类型定义:App
// TYPE {app}
{
"id":{guid}, // 无意义的唯一id
"name":{string}, // 可办事项名称
"uri":{string}, // 启动uri
"code":{string}, // 应用代码,可用于部分api调用,表示该app的发布版
"abbreviation":{string}, // 缩略名
"description":{string}, // 服务摘要
"tags":{string}, // 应用标签,可以有多个,以逗号分隔,第一个作为主分类
"icon":{uri}, // 图标uri
"palette":{string}, // 调色板颜色,形如:#ff0000
"department":{string}, // 负责院系
"contact":{string}, // 联系人及其方式描述
"recommend":{integer}, // 推荐度,整数
"rating":{integer}, // 评价汇总,0到100分
"rated":{integer}, // 评价次数
"system":{string}, // 所属系统
}
附2. 类型定义:Process
- 工作流应用的实例。一个App可以被发起多个Process
// TYPE {process}
{
"id":{guid}, // 无意义的唯一id
"name":{string}, // 流程实例名称
"uri":{string}, // 查看流程实例用到的uri
"tags":{string}, // 该流程实例的标签,可以有多个,以逗号分隔
"entry":{string}, // 流程实例流水号
"create":{long}, // 流程实例创建时间
"update":{long}, // 流程实例最后操作时间
"sort":{long}, // 排序值,会根据排序方式而不同,可参考order参数,目前均为时间戳。
"app":{app}, // 所属应用
"owner":{profile}, // 流程实例所有者,用于区分是我的事宜还是别人的事宜
"actualUser":{profile}, // 委托发起的流程的实际发起人
"status":{string}, // 流程状态:doing、suspended、done、killed
"stateEx":{string}, // 流程终止节点状态
"version":{long}, // 所属App版本的创建时间戳
"rating":{int}, // 评价星级,1-5
"review":{string}, // 评价内容
"screen":{string}, // 发起人使用的终端:desktop/mobile/ios/android/wechat 之一
"ip":{string}, // 发起人IP,仅需Mutation提供,考虑到隐私Query不给出此信息
"pendingTasks":{string}, // 当前的待办任务名称列表,逗号分割
"priority":{string}, // 优先级:normal、important,可为空默认normal
"milestone":{Milestone}, // 本流程经到达的最后一个里程碑
"tasks":[{Task}], // 任务列表
"ancestors": [{Process}], // 祖先流程,近当前流程为“子流程”时有效
}
# 里程碑(流程进度)
type Milestone {
# 里程碑描述
name: String
# 里程碑百分比,0-100
percent: Int
# 里程碑状态:[todo|doing|done]
status: String
# 里程碑到达时条件的描述
nameIn: {string}
# 里程碑所属分支,层次关系即branch间的前缀关系
branch: String
}
附3. 类型定义:Task
- 需要用户办理的任务,每个Process由1或多个Task组成。
// Type: {task}
{
"id":{guid},
"name":{string}, // 当前任务名,如:"待审核"、"申请单填写"
"uri":{string}, // 展示本任务表单所需的url
"description":{string}, // 摘要
"process":{process}, // 所属流程实例
"subProcess":{process}, // 对应的子流程,仅对子流程任务有效
"assignUser":{profile}, // 指派给的用户,可能为空,表示未指定具体用户
"actionUser":{profile}, // 办理用户,仅对doing|done有效
"actualUser":{profile}, // 实际操作的用户,"被委托人"
"assignTime":{long}, // 指派时间
"actionTime":{long}, // 办理时间
"actionName":{string}, // 办理时选择的动作名称
"expireTime":{long}, // 承诺办理时间
"renderTime":{long}, // 此任务表单第一次渲染的时间,用于标记该任务“已读”
"remark":{string}, // 办理用户填写的备注信息
"screen":{string}, // 办理用户使用的终端:desktop/mobile/ios/android/wechat 之一
"ip":{string}, // 办理用户IP,仅需Mutation提供,考虑到隐私Query不给出此信息
"status":{string}, // 状态:[todo|done|sub]
"actioners": [{profile}], // 可办理人列表
"reviewers": [{profile}], // 被抄送人列表
"actionDepts": [{ // 任务所属部门列表,2020/03新增
"code": {string},
"name": {string},
}],
}
附4. 类型定义:Profile
// TYPE {profile}
{
"id":{guid}, // 无意义的唯一id
"name":{string}, // 实名
"account":{string}, // 租户内的用户id,租户唯一
}
附5. 类型定义:System
// TYPE {system}
{
"id":{string}, // 系统编码
"name":{string}, // 系统显示名
"stats": { // 统计,类型名 {SystemStat}
"todo": {integer}, // 待办任务数。如果 filter.userId 给出,统计的当前用户的
"doing": {integer}, // 进行中流水数
"done": {integer}, // 已完成流水数
"completed": {integer}, // 进行中 + 已完成,同流水合并
}
}
附6. 输入Filter定义
input StringFilter {
eq: String
}
input BooleanFilter {
eq: Boolean
}
input TaskFilter {
# 所属应用的标签(分类)
appTags: StringFilter
# 是否包含延迟办理的任务,默认为false(不包含)
postponed: BooleanFilter
}
input ProcessFilter {
# 所属应用的标签(分类)
appTags: StringFilter
}
附7. order参数