模块: OA 审批 · 发起审批
日期: 2026-08-28
状态: 待实现
UI Demo: docs/demos/oa-start-history-demo.html
决策记录:
oa:start:history:all 控制id;完成时间 = 终态 update_time;不改表OA 审批已具备完整工作流。客户希望在「发起审批」页面每张流程卡片的「发起」按钮左侧增加「历史记录」,弹窗展示该流程的发起记录(默认按发起时间倒序),支持筛选与分页,并按权限决定看本人还是看租户内全员。
成功标准:
oa:start:history:all 可见本租户该流程全部,并显示「申请人」筛选| 项 | 说明 |
|---|---|
| 入口 | web-admin/src/views/oa-approval/start/index.vue 流程卡片 |
| 弹窗 | 新组件 OaAppHistoryDialog.vue |
| API | GET /web/admin/oa-approval/instances/history |
| 权限 | 按钮级菜单 perms = oa:start:history:all + SQL 种子 |
| 详情可见性 | 有全员历史权限时可打开本租户任意该流程实例详情(打印同源) |
finish_time 列| 角色/权限 | 「历史记录」按钮 | 列表数据范围 | 「申请人」筛选 |
|---|---|---|---|
能进发起审批页、无 oa:start:history:all |
显示 | 仅本人发起 | 不显示 |
拥有 oa:start:history:all |
显示 | 本租户该 appId 全部实例 |
显示 |
超级管理员 / menuPermAll |
显示 | 同全员 | 显示 |
oa:start:history:allsys_menu 按钮级节点,建议挂在「发起审批」菜单下;交付 docs/sql/ 种子 SQL,可由角色勾选useMenuPerm().hasMenuPerm('oa:start:history:all') 仅控制 UI(申请人筛选项等)user_has_menu_perm 强制收窄数据;忽略客户端伪造的「全员」意图GET /web/admin/oa-approval/instances/history
鉴权:管理端登录用户(与发起页一致);数据范围由权限字符决定。
| 参数 | 必填 | 说明 |
|---|---|---|
appId |
是 | 锁定流程;缺失返回 400 |
instanceId |
否 | 审批 ID,对 oa_instance.id 做包含匹配(LIKE %value%) |
instanceStatus |
否 | running / completed / rejected / returned / cancelled |
initiatorName |
否 | 申请人昵称模糊;仅全员权限生效,无权限时忽略 |
applyTimeFrom / applyTimeTo |
否 | 发起时间,YYYY-MM-DD,过滤 create_time |
finishTimeFrom / finishTimeTo |
否 | 完成时间,YYYY-MM-DD;见 §4.4 |
page / pageSize |
否 | 分页;默认排序 create_time DESC |
{
"list": [ /* 行对象 */ ],
"total": 0,
"canViewAll": true
}
行对象要点(在现有 _enrich_list_rows / _instance_to_dict 摘要之上扩展):
| 字段 | 说明 |
|---|---|
id |
审批 ID(列表列「审批 ID」) |
appName / title |
流程名称 |
initiatorUserName |
申请人 |
applyTime |
发起时间(create_time) |
finishTime |
完成时间;非终态为 null |
status |
审批状态 |
currentNodeName 等 |
与任务列表 enrich 一致 |
previewFields |
最多 6 项 { label, value },按该实例锁定版本 form_schema_json 取前 6 个可摘要字段 |
另:可将 previewFields 上限从现有任务列表的 3 参数化为 limit;历史接口传 6,既有 tasks/{kind} 保持 3 以免影响其它页。
终态集合(有 finishTime):completed、rejected、cancelled
非终态(finishTime = null):running、returned
update_time;否则空status IN (completed, rejected, cancelled) 且 update_time 落在 [finishTimeFrom, finishTimeTo] 日界内tenant_no 隔离 + del_flag = 0 + app_id = appIdinitiator_user_id = 当前用户initiatorName 筛选)oa_instance_draft 不参与)现有 GET /instances/{id} 若仅允许发起人/审批人/抄送人查看,则全员历史用户无法「查看/打印」他人单据。
本期约定:调用方拥有 oa:start:history:all 且实例属于同租户时,允许读取该实例详情(打印走同一详情接口)。实现落在详情鉴权分支,避免仅放开列表却打不开详情。
文件:web-admin/src/views/oa-approval/start/index.vue
[历史记录] [发起]
@click.stop 打开历史弹窗文件:web-admin/src/components/oa-approval/OaAppHistoryDialog.vue
dialog-form-layout + append-to-body,宽度约 1080pxopen({ id, appName }):锁定 appId,标题 历史记录 · {appName}| 字段 | 行为 |
|---|---|
| 流程名称 | 只读预填,不可改 |
| 审批状态 | 下拉,枚举同任务中心 |
| 审批 ID | 文本 |
| 发起时间 | daterange,YYYY-MM-DD |
| 完成时间 | daterange,YYYY-MM-DD |
| 申请人 | 仅 canViewAll / hasMenuPerm('oa:start:history:all') 时显示 |
操作:重置、搜索(可与任务中心一致做防抖即时检索,非必须;至少支持显式搜索/重置)。
el-tag)动态列:按当前页数据的 previewFields 标签对齐;不足 6 个则少列;缺值显示 -。
与 views/oa-approval/mine/index.vue 对齐:
/system-manage/oa-approval/instances/:id(或项目现有详情打开方式)fetchOaInstanceDetail + exportOaApprovalPdf,带 loading 防重复web-admin/src/api/oaApproval.ts 新增 fetchOaInstanceHistory(params)。
| 位置 | 变更 |
|---|---|
app/api/oa_approval.py |
注册 history 路由 |
app/services/oa_engine.py |
list_instance_history;复用/扩展 _apply_instance_list_filters、_enrich_list_rows(preview limit=6,计算 finishTime) |
app/core/menu_guard.py |
使用已有 user_has_menu_perm |
docs/sql/ |
插入按钮菜单种子(perms=oa:start:history:all) |
表结构:不改 oa_instance。
| 场景 | 处理 |
|---|---|
无权限带 initiatorName |
忽略 |
| 无权限搜他人审批 ID | 无结果 |
| 表单字段少于 6 个 | 有几列展示几列 |
| 多版本 schema | 每行按实例锁定版本取前 6 字段 |
appId 非法 |
400 |
| 空列表 | 「暂无历史记录」 |
oa:start:history:all:仅本人;无「申请人」筛选appId 必填、previewFields 长度、终态 finishTime、详情放宽分支docs/demos/oa-start-history-demo.html(列序已按「业务字段在发起时间前」;文案「审批 ID」以实现为准同步 Demo)pending / minemine/index.vue + exportOaApprovalPdf