|
|
@@ -0,0 +1,147 @@
|
|
|
+# OA 历史记录 · 按部门检索设计
|
|
|
+
|
|
|
+**模块**: OA 审批 · 发起审批 · 历史记录
|
|
|
+**日期**: 2026-10-16
|
|
|
+**状态**: 已确认
|
|
|
+**关联**: `docs/superpowers/specs/2026-08-28-oa-start-history-design.md`
|
|
|
+**决策记录**:
|
|
|
+- 部门树展示当前租户**全部部门**
|
|
|
+- 选中部门后匹配 **本级 + 全部下级**(`initiator_dept_id IN (self ∪ descendants)`)
|
|
|
+- 匹配字段为实例快照 `initiator_dept_id`,不是发起人当前所属部门
|
|
|
+- 数据权限模型不变:仍仅由 `oa:start:history:all` 决定「本人 / 全员」;部门条件在该范围之上叠加
|
|
|
+- 列表与「导出全部」共用同一部门参数
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 背景与目标
|
|
|
+
|
|
|
+【历史记录】页(`web-admin` `#/system-manage/oa-approval/history/:appId`)已有审批状态、审批 ID、发起/完成时间、以及全员权限下的「申请人」筛选。业务需要再按**发起部门**检索。
|
|
|
+
|
|
|
+**成功标准**:
|
|
|
+- 检索区可选择租户内任意部门并清空
|
|
|
+- 选中后列表仅含该部门及其下级发起的审批实例
|
|
|
+- 无全员权限时仍只见本人,部门条件在本人记录内生效
|
|
|
+- 「导出全部」沿用当前检索条件(含部门)
|
|
|
+- 后端强制过滤,前端无法伪造绕过
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 范围
|
|
|
+
|
|
|
+### 2.1 在范围内
|
|
|
+
|
|
|
+| 项 | 说明 |
|
|
|
+|----|------|
|
|
|
+| 前端 | `web-admin/src/views/oa-approval/history/index.vue` 检索区「部门」 |
|
|
|
+| API | `GET .../instances/history`、`GET .../instances/history/export` 增加 `initiatorDeptId` |
|
|
|
+| 后端 | `list_instance_history` / `_history_export_query` / `export_instance_history` 按部门树展开过滤 |
|
|
|
+| 测试 | 扩展 `backend/tests/test_oa_instance_history.py` |
|
|
|
+
|
|
|
+### 2.2 非目标
|
|
|
+
|
|
|
+- 不改角色「数据范围」(本部门 / 本部门及以下等)模型
|
|
|
+- 不按当前审批人、抄送人部门过滤
|
|
|
+- 不在表格中新增「部门」列(导出已有「创建人部门」)
|
|
|
+- 不改移动端历史记录页(本期仅 web-admin)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 权限与可见性
|
|
|
+
|
|
|
+| 能力 | 规则 |
|
|
|
+|------|------|
|
|
|
+| 能否打开历史记录页 | 与现网一致(发起审批入口) |
|
|
|
+| 表格行可见范围 | 无 `oa:start:history:all` → 仅 `initiator_user_id = 当前用户`;有权限或 `super_admin` → 本租户该 `appId` 全部 |
|
|
|
+| 「部门」筛选项 | **始终显示**(与「申请人」不同;申请人仍仅全员权限显示) |
|
|
|
+| 部门条件与全员权限 | 先按全员权限收窄,再叠加部门 `IN` 过滤 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 交互设计
|
|
|
+
|
|
|
+### 4.1 检索区
|
|
|
+
|
|
|
+在现有 `filter-grid` 中增加一项:
|
|
|
+
|
|
|
+- 标签:`部门`
|
|
|
+- 控件:`el-tree-select`,`check-strictly`、`filterable`、`clearable`
|
|
|
+- 数据源:`fetchDeptTree()`(当前租户全部部门)
|
|
|
+- 下拉节点文案:本级名称
|
|
|
+- 选中后输入框:全路径,分隔符 ` / `(复用 `buildTreePathLabelFromFlat` / 页内 path label 惯例)
|
|
|
+- 占位:`请选择部门`
|
|
|
+- 重置:清空 `initiatorDeptId` 与其它条件一并恢复
|
|
|
+
|
|
|
+### 4.2 查询与导出
|
|
|
+
|
|
|
+- 搜索 / 分页 / 导出全部:若已选部门,传 `initiatorDeptId=<deptId>`
|
|
|
+- 导出勾选:仍以勾选 ID 为准;导出参数可附带当前筛选(与现网 `buildExportParams` 行为一致,一并带上部门 ID)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. API 设计
|
|
|
+
|
|
|
+### 5.1 新增查询参数
|
|
|
+
|
|
|
+| 参数 | 必填 | 说明 |
|
|
|
+|------|:----:|------|
|
|
|
+| `initiatorDeptId` | 否 | 发起部门 ID;空则不按部门过滤 |
|
|
|
+
|
|
|
+列表与导出两个端点均接收该参数。
|
|
|
+
|
|
|
+### 5.2 过滤语义
|
|
|
+
|
|
|
+1. `initiatorDeptId` 为空或仅空白 → 不加部门条件
|
|
|
+2. 非空 → 在当前租户 `sys_dept`(`del_flag=0`)上解析 **自身 + 全部子孙** ID 集合
|
|
|
+3. `OaInstance.initiator_dept_id IN 集合`
|
|
|
+4. 若选中部门不存在或不属于当前租户 → 结果为空列表(`IN ()` 等价无匹配),不报 400
|
|
|
+
|
|
|
+复用既有 `_get_child_dept_ids`(`app/core/data_scope.py`)或等价 BFS,避免重复实现。
|
|
|
+
|
|
|
+### 5.3 与现有筛选组合
|
|
|
+
|
|
|
+顺序保持:租户 + `appId` + 全员权限收窄 → 审批 ID / 申请人 / 时间 / 状态 → **部门** → 分页。
|
|
|
+部门过滤与其它条件为 AND。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 实现要点
|
|
|
+
|
|
|
+### 6.1 后端
|
|
|
+
|
|
|
+- `oa_approval.py`:`list_oa_instance_history`、`export_oa_instance_history` 增加 `initiatorDeptId` Query,传入 engine
|
|
|
+- `oa_engine.list_instance_history` / `_history_export_query` / `export_instance_history`:增加 `initiator_dept_id` 参数并应用 `IN` 过滤
|
|
|
+- 不改 `_apply_instance_list_filters` 签名亦可:在 history 专用路径旁直接 filter,减少无关列表接口影响
|
|
|
+
|
|
|
+### 6.2 前端
|
|
|
+
|
|
|
+- `searchForm.initiatorDeptId`
|
|
|
+- 挂载时加载部门树;`handleSearch` / `handleReset` / `loadList` / `buildExportParams` 透传参数
|
|
|
+- `fetchOaInstanceHistory` / `fetchOaInstanceHistoryExport` 类型与 params 透传(若 API 封装为透传 Query 则仅页面改即可)
|
|
|
+
|
|
|
+### 6.3 测试
|
|
|
+
|
|
|
+在 `test_oa_instance_history.py` 增加:
|
|
|
+
|
|
|
+- 父部门过滤命中本级 + 子部门实例
|
|
|
+- 选中子部门不命中仅属父部门的实例
|
|
|
+- 无全员权限时部门过滤仍限制在本人发起记录内
|
|
|
+
|
|
|
+需在测试库创建 `SysDept` 表及带 `initiator_dept_id` 的实例行。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 非功能
|
|
|
+
|
|
|
+- 最小改动;不重构历史页布局
|
|
|
+- UI 对齐 Fresh Mint 筛选区与用户管理页部门树选惯例
|
|
|
+- 完成后按需跑 `./scripts/update-graph.sh backend`(及若前端有显著符号变更则 `frontend`)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 验收清单
|
|
|
+
|
|
|
+1. 打开某流程历史记录,检索区可见「部门」,树含租户全部部门
|
|
|
+2. 选中父部门 → 列表含本级与下级发起记录;清空 → 恢复原范围
|
|
|
+3. 无 `oa:start:history:all` 账号:部门条件只影响本人可见行;仍不能看到他人
|
|
|
+4. 「导出全部」结果与当前含部门条件的列表一致
|
|
|
+5. 相关单测通过
|