Files
zkxw/docs/superpowers/specs/2026-08-06-oa-approval-instance-draft-design.md
T
zlwuandCursor de22678c87 feat: ship OA drafts/badges, role dual-track, and test-env deploy tooling.
Add approval instance drafts with menu badges, dual-track user/role read model and role bound names, form-designer outline docs, and bare-metal test deploy scripts. Ignore local test-server credential file.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 13:58:47 +08:00

124 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OA 发起审批草稿箱 Design
| 项 | 内容 |
|----|------|
| 日期 | 2026-08-06 |
| 状态 | 已定稿(UI 以 `docs/demos/oa-approval-draft-box-demo.html` 为准) |
| 范围 | 发起审批「暂存草稿」+ 侧栏「草稿箱」列表(再编辑 / 保存 / 提交 / 删除) |
## 背景
现状「发起审批」弹窗仅有「取消」「提交」,填到一半关闭即丢失。客户要求可暂存草稿,并在「发起审批」下方增加「草稿箱」菜单集中管理。
现有 `oa_app_version.status=draft` 仅为**模板设计草稿**,与本需求的**发起人填写草稿**无关,不得混用。
## 目标与非目标
**目标**
- 发起弹窗可「暂存草稿」,不进入审批流、不产生待办。
- 侧栏「草稿箱」列出当前用户草稿;支持编辑、再次保存、提交审批、删除与批量删除。
- 草稿仅本人可见(租户内 + 发起人 = 当前用户)。
**非目标**
- 不与「我发起的」实例混排;草稿不是 `oa_instance`。
- 不做跨用户共享草稿、不做审批人代填。
- 不做自动定时暂存(仅显式点击「暂存草稿 / 保存草稿」)。
- 不改造小程序端(本期仅 web-admin)。
## 方案对比与结论
| 方案 | 做法 | 优点 | 缺点 |
|------|------|------|------|
| A(推荐) | 独立表 `oa_instance_draft` | 与引擎解耦;「我发起的」无需过滤 draft;语义清晰 | 多一张表与一套 CRUD |
| B | `oa_instance.status=draft` | 少表 | 引擎/列表/关联审批处处要排除;误发起风险高 |
| C | 仅浏览器 localStorage | 无后端 | 换设备丢失;无法做菜单级权限与审计 |
**选定 A。** 提交时调用现有 `start_instance`,成功后软删对应草稿。
## 数据模型
表名:`oa_instance_draft`
| 字段 | 说明 |
|------|------|
| `id` | VARCHAR(64) PK,UUID |
| `app_id` | 审批应用 ID |
| `app_version_id` | 暂存时锁定的已发布版本(提交时优先用最新已发布版,见下) |
| `title` | 可选标题(可由应用名或表单字段推导,可空) |
| `form_data_json` | 表单数据 JSON |
| `initiator_select_json` | 发起人自选 `{nodeId:[userId,...]}` |
| `initiator_dept_id` | 发起部门(与发起接口一致) |
| `owner_user_id` | 草稿所属人(= 创建人) |
| 公共字段 | `tenant_no` … `del_flag`(遵循 database-conventions) |
约束与行为:
- 同一用户对同一 `app_id` **允许多条**草稿(与 Demo 列表一致)。
- 列表默认 `create_time DESC` 不适用时,用 **`update_time DESC`**(最近保存优先)。
- 删除:软删 `del_flag=1`。
- **暂存不做完整必填校验**;**提交**走与正式发起相同的校验。
### 版本策略
- 暂存:写入当时「最新已发布」`app_version_id`。
- 编辑打开:用该草稿的 `app_id` 取**当前最新已发布**模板渲染;`form_data` / `initiator_select` 按 field 名回填(字段已删则忽略多余键)。
- 若应用已无已发布版本:编辑/提交时提示「该审批单已下架或未发布」,禁止提交,允许删除草稿。
## API(`/api/admin/oa-approval`)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/drafts` | 当前用户草稿分页;query:`keyword`(流程名)、`groupId`、`updateTimeFrom`/`updateTimeTo`、`page`/`pageSize` |
| GET | `/drafts/{id}` | 草稿详情(含 formData、initiatorSelect、app 基础信息) |
| POST | `/drafts` | 新建草稿(`appId` + formData + initiatorSelect + initiatorDeptId + title?) |
| PUT | `/drafts/{id}` | 更新草稿(仅 owner) |
| DELETE | `/drafts/{id}` | 软删单条 |
| POST | `/drafts/batch-delete` | body: `{ ids: string[] }` 批量软删 |
| POST | `/drafts/{id}/submit` | 校验 + `start_instance`;成功后软删草稿;返回实例信息 |
权限:均需登录管理端用户;读写仅限 `owner_user_id == 当前用户` 且同 `tenant_no`。菜单码:`oa:drafts`(列表/读写统一挂此码,与 `oa:start` 同级授权习惯)。
## 前端
### 菜单与路由
- 侧栏顺序:… → 发起审批 → **草稿箱** → 待办中心 → …
- 路由:`/#/system-manage/oa-approval/drafts`,组件 `web-admin/src/views/oa-approval/drafts/index.vue`
- 前端路由模块 `sqxp.ts` 与库表 `sys_menu`(SQL 脚本)同步增加菜单项。
### 发起页 `start/index.vue`
- 弹窗底栏:**取消** | **暂存草稿** | **提交**(主色仅「提交」)。
- 「暂存草稿」:调用 POST/PUT drafts;成功提示「已存入草稿箱」并关弹窗(或保持打开——**关弹窗**,与 Demo 心智一致)。
- 若路由带 `draftId`(从草稿箱「编辑」跳入):打开对应模板并回填,暂存走 PUT。
### 草稿箱页(对齐「我发起的」列表模式)
列:序号、流程名称、模板版本、最近保存、状态(Tag「草稿」`warning`)、操作(编辑 / 提交审批 / 删除)。
- **编辑**:`router.push` 到发起页并带 `draftId`(或本页弹窗复用发起表单——**推荐跳转发页 + query**,少复制逻辑;若发起页已是弹窗模式,则在草稿箱页复用同一套 dialog 逻辑亦可。实现择一:**草稿箱页内嵌与 start 相同的发起弹窗**,避免整页跳转丢上下文)。
- **提交审批**:调用 `POST /drafts/{id}/submit`;若校验失败,打开编辑弹窗并展示错误。
- **删除 / 批量删除**:二次确认后调用删除接口。
筛选:流程名称、保存时间范围、模板分组(与 Demo 一致)。
## 错误处理
- 非 owner / 已删:404 或 403,文案「草稿不存在或无权访问」。
- 提交时应用不可用:400 + 明确文案。
- 批量删除:跳过无权 id,返回成功数(或全部失败则报错)——采用 **全部校验通过再删**,任一无权则整批失败。
## 测试要点
- 暂存后草稿箱可见;他人不可见。
- 更新草稿只改本人记录。
- 提交成功产生 `oa_instance` 且草稿软删;「我发起的」出现新实例。
- 暂存不产生 `oa_task`。
- 无发布版本时禁止提交。
## UI 权威
`docs/demos/oa-approval-draft-box-demo.html`;视觉遵循 Fresh Mint / `docs/web-admin-ui-spec-fresh-mint.md`。