Unify effective roles via post-role bindings, remove dedicated OA role UI, and update OA assignee resolution plus related SQL/docs. Co-authored-by: Cursor <cursoragent@cursor.com>
123 lines
4.7 KiB
Markdown
123 lines
4.7 KiB
Markdown
# OA 审批人选:工作流角色 → 职位(硬切换)
|
||
|
||
**日期:** 2026-08-04
|
||
**范围:** 去掉 `oa_role` / `oa_role_user` 与【工作流角色】模块;流程审批人/抄送改为选【职位】,运行时按 `sys_user_post` 展开成员。
|
||
**方案:** 方案 1 — `assigneeType: "posts"` + `postIds`
|
||
|
||
## 已确认决策
|
||
|
||
| 项 | 结论 |
|
||
|----|------|
|
||
| 历史流程 | 系统未上线,无历史 `flow_tree` → **硬切换**,不做兼容层 |
|
||
| 预置 GM/CHAIRMAN | **不做**;设计器普通多选启用职位 |
|
||
| 下线范围 | **彻底去掉**:菜单/路由/管理页/API/`fetchOaRole*` |
|
||
| 数据表 | **一并 DROP** `oa_role_user`、`oa_role`(增量 SQL) |
|
||
| 审批人数据源 | **仅** `sys_user_post`(职位成员);**禁止**用 `sys_post_role` / `sys_role` |
|
||
|
||
## 目标模型
|
||
|
||
```
|
||
流程节点 approverConfig
|
||
assigneeType / assigneeTypes: "posts"
|
||
postIds: [sys_post.id, ...]
|
||
│
|
||
▼
|
||
sys_user_post(启用职位 + 启用用户)
|
||
│
|
||
▼
|
||
待办 / 抄送人 userId 列表
|
||
```
|
||
|
||
与权限链分离:
|
||
|
||
```
|
||
职位 → sys_post_role → sys_role → 菜单/数据权限 (登录 RBAC,本需求不改)
|
||
职位 → sys_user_post → 用户 (本需求:审批人选)
|
||
```
|
||
|
||
## Flow JSON(新约定)
|
||
|
||
审批节点示例:
|
||
|
||
```json
|
||
{
|
||
"assigneeType": "posts",
|
||
"postIds": ["<sys_post.id>"],
|
||
"signMode": "or"
|
||
}
|
||
```
|
||
|
||
抄送节点:`assigneeTypes` 可含 `"posts"`(与 `users` / `dept_leader` 等组合),成员来自同一套 `postIds`(或按现抄送结构对每种类型分字段;实现时与现 `oa_roles` 写法一一对应替换)。
|
||
|
||
**删除字段/枚举:** `oa_roles`、`oaRoleIds`、`oaRoleCodes`、`oa_role_ids`、`oa_role_codes`。
|
||
|
||
## 后端
|
||
|
||
### 新增/改造
|
||
|
||
| 位置 | 变更 |
|
||
|------|------|
|
||
| `crud/user.py` 或 `crud/post.py` | `list_user_ids_bound_to_posts(db, post_ids, tenant_no)`:多职位展开用户,过滤职位 `status=1`/`del_flag=0`、用户启用 |
|
||
| `oa_assignee.py` | `assigneeType == "posts"` 分支;`resolve_source: "posts"`;删除 `oa_roles` 分支 |
|
||
| `oa_publish.py` | 校验 `posts` 时 `postIds` 非空;引用校验查 `SysPost`;删除 `validate_oa_roles_referenced` |
|
||
| `oa_engine.py` | 展示标签改职位名称映射;删除 `OaRole` 查询 |
|
||
| `oa_approval.py` API | 删除整个工作流角色路由段 |
|
||
| `crud/oa_approval.py` | 删除 `PRESET_ROLES` / `ensure_presets` / 角色 CRUD / `list_oa_role_user_ids` |
|
||
| `models.py` | 删除 `OaRole`、`OaRoleUser`(与 drop SQL 同步) |
|
||
|
||
### SQL
|
||
|
||
创建 `docs/sql/drop_oa_role.sql`:
|
||
|
||
```sql
|
||
DROP TABLE IF EXISTS `oa_role_user`;
|
||
DROP TABLE IF EXISTS `oa_role`;
|
||
```
|
||
|
||
菜单:软删或删除「工作流角色」菜单项(`oa:roles:list`),与项目菜单维护方式一致。
|
||
|
||
### 错误语义
|
||
|
||
- 发布:未选职位 / 职位不存在或停用 → 明确错误
|
||
- 运行:职位下无有效用户 → 与现「工作流角色成员为空」同等失败(`AssigneeResolveError`)
|
||
|
||
## 前端
|
||
|
||
| 位置 | 变更 |
|
||
|------|------|
|
||
| `FlowDesigner.vue` | 选项「工作流角色」→「职位」;`fetchPostList` 加载(仅 `status==='1'`);`postIds` 多选 |
|
||
| `flow-tree/types.ts` | `AssigneeType` 含 `posts`;去掉 `oa_roles`;`summarizeApprover` 文案「职位」 |
|
||
| `OaProgressChain.vue` | `posts` →「职位」 |
|
||
| 删除 | `views/oa-approval/roles/index.vue`;路由 `oa-approval/roles`;`oaApproval.ts` 中全部 `fetchOaRole*` |
|
||
| 保留 | `OaPostSelect.vue`(表单控件,与审批人选独立) |
|
||
|
||
## 文档与测试
|
||
|
||
- 更新钉钉式 OA 设计文档中「工作流角色」章节为「职位」
|
||
- 需求/OpenSpec 若提及 OA 独立角色作审批人,改为职位
|
||
- 单测:`test_oa_assignee.py` 改为 posts;去掉「不读 sys_role」之外的 oa_role mocks;`test_oa_publish.py` 同步
|
||
- `./scripts/update-graph.sh backend`(及 frontend)
|
||
|
||
## 非目标
|
||
|
||
- 职位权限(`sys_post_role`)行为不变
|
||
- 不种子 GM/CHAIRMAN 职位
|
||
- 不做旧 JSON 兼容读取
|
||
- 不改审批人其它类型:`users` / `dept_leader` / `direct_supervisor` / `initiator_select`
|
||
|
||
## 实现顺序(建议)
|
||
|
||
1. 后端:`list_user_ids_bound_to_posts` + assignee/publish/engine 改 `posts`
|
||
2. 前端:FlowDesigner + types + 进度文案
|
||
3. 删除角色模块(页/路由/API/CRUD/模型)
|
||
4. drop SQL + 菜单清理 + 文档/单测
|
||
5. 图谱更新
|
||
|
||
## 验收
|
||
|
||
1. OA 菜单无「工作流角色」
|
||
2. 流程设计审批/抄送可选职位并保存 `posts`/`postIds`
|
||
3. 职位已关联用户时,发起后待办落到这些用户
|
||
4. 空成员职位无法正常完成解析(错误可读)
|
||
5. 代码库无 `oa_roles` / `fetchOaRole` / `OaRole` 残留(除历史设计文档归档说明外)
|