fix: resolve remaining clippy warnings and improve workflow frontend
- Collapse nested if-let in user_service.rs search filter - Suppress dead_code warning on ApiDoc struct - Refactor server routing: nest all routes under /api/v1 prefix - Simplify health check route path - Improve workflow ProcessDesigner with edit mode and loading states - Update workflow pages with enhanced UX - Add Phase 2 implementation plan document
This commit is contained in:
@@ -1,135 +1,137 @@
|
||||
# Phase 3: 系统配置模块 — 实施计划
|
||||
# Phase 4: 工作流引擎模块 — 实施计划
|
||||
|
||||
## Context
|
||||
|
||||
Phase 1(基础设施)和 Phase 2(身份与权限)已完成。Phase 3 需要实现系统配置模块(erp-config),提供数据字典、动态菜单、系统参数、编号规则、i18n 框架和主题自定义能力。当前 `erp-config` 仅为 placeholder。
|
||||
Phase 1(基础设施)、Phase 2(身份与权限)和 Phase 3(系统配置)已完成。Phase 4 需要实现工作流引擎模块(erp-workflow),提供流程定义、流程实例管理、任务审批、Token 驱动的执行引擎和可视化流程设计器。当前 `erp-workflow` 仅为 placeholder。
|
||||
|
||||
## 前置重构:将 RBAC 移至 erp-core
|
||||
|
||||
**问题:** `require_permission` 在 `erp-auth/src/middleware/rbac.rs` 中,但只依赖 `erp-core` 的 `TenantContext` 和 `AppError`。erp-config 不能依赖 erp-auth(架构铁律:业务 crate 禁止直接依赖)。
|
||||
|
||||
**方案:**
|
||||
1. 将 `erp-auth/src/middleware/rbac.rs` → `erp-core/src/rbac.rs`
|
||||
2. `erp-core/src/lib.rs` 添加 `pub mod rbac;`
|
||||
3. 更新 `erp-auth` 所有 handler 的 import:`crate::middleware::rbac` → `erp_core::rbac`
|
||||
4. `erp-auth/src/middleware/mod.rs` 移除 `pub mod rbac;`
|
||||
用户选择"完整实施"方案,包括 BPMN 子集解析器、Token 驱动执行引擎、完整 CRUD 端点和 React Flow 可视化设计器。
|
||||
|
||||
---
|
||||
|
||||
## Task 1: erp-config 骨架 + ConfigState
|
||||
## Task 1: erp-workflow 骨架 + WorkflowState + Error
|
||||
|
||||
**目标:** 创建可编译的最小 crate,注册到 erp-server。
|
||||
|
||||
**创建/修改文件:**
|
||||
- 修改: `crates/erp-config/Cargo.toml` — 添加完整依赖
|
||||
- 修改: `crates/erp-config/src/lib.rs` — 模块声明 + re-export
|
||||
- 创建: `crates/erp-config/src/config_state.rs` — ConfigState { db, event_bus }
|
||||
- 创建: `crates/erp-config/src/error.rs` — ConfigError 枚举
|
||||
- 创建: `crates/erp-config/src/module.rs` — ConfigModule + 空路由
|
||||
- 创建: `crates/erp-config/src/dto.rs` — 占位
|
||||
- 创建: `crates/erp-config/src/entity/mod.rs` — 占位
|
||||
- 创建: `crates/erp-config/src/service/mod.rs` — 占位
|
||||
- 创建: `crates/erp-config/src/handler/mod.rs` — 占位
|
||||
- 修改: `crates/erp-server/Cargo.toml` — 添加 erp-config 依赖
|
||||
- 修改: `crates/erp-server/src/state.rs` — 添加 FromRef<AppState> for ConfigState
|
||||
- 修改: `crates/erp-server/src/main.rs` — 注册 ConfigModule
|
||||
- 修改: `crates/erp-workflow/Cargo.toml` — 添加完整依赖
|
||||
- 修改: `crates/erp-workflow/src/lib.rs` — 模块声明 + re-export
|
||||
- 创建: `crates/erp-workflow/src/workflow_state.rs` — `WorkflowState { db, event_bus }`
|
||||
- 创建: `crates/erp-workflow/src/error.rs` — WorkflowError 枚举
|
||||
- 创建: `crates/erp-workflow/src/module.rs` — WorkflowModule + ErpModule trait
|
||||
- 创建: `crates/erp-workflow/src/dto.rs` — 占位
|
||||
- 创建: `crates/erp-workflow/src/entity/mod.rs` — 占位
|
||||
- 创建: `crates/erp-workflow/src/service/mod.rs` — 占位
|
||||
- 创建: `crates/erp-workflow/src/handler/mod.rs` — 占位
|
||||
- 创建: `crates/erp-workflow/src/engine/mod.rs` — 占位
|
||||
- 修改: `crates/erp-server/Cargo.toml` — 确认 erp-workflow 依赖
|
||||
- 修改: `crates/erp-server/src/state.rs` — 添加 `FromRef<AppState>` for WorkflowState
|
||||
- 修改: `crates/erp-server/src/main.rs` — 注册 WorkflowModule
|
||||
|
||||
**依赖:**
|
||||
```toml
|
||||
erp-core.workspace = true
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
uuid = { workspace = true, features = ["v7", "serde"] }
|
||||
chrono = { workspace = true, features = ["serde"] }
|
||||
axum = { workspace = true }
|
||||
sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls", "with-uuid", "with-chrono", "with-json"] }
|
||||
tracing = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
utoipa = { workspace = true, features = ["uuid", "chrono"] }
|
||||
async-trait = { workspace = true }
|
||||
```
|
||||
|
||||
**验证:** `cargo check` 通过
|
||||
|
||||
---
|
||||
|
||||
## Task 2: 数据库迁移(6 张表)
|
||||
|
||||
**目标:** 创建所有配置模块表。
|
||||
## Task 2: 数据库迁移(5 张表)
|
||||
|
||||
**创建文件(`crates/erp-server/migration/src/`):**
|
||||
- `m20260412_000012_create_dictionaries.rs` — 字典分类表
|
||||
- `m20260412_000013_create_dictionary_items.rs` — 字典项表
|
||||
- `m20260412_000014_create_menus.rs` — 菜单树形表
|
||||
- `m20260412_000015_create_menu_roles.rs` — 菜单-角色关联表
|
||||
- `m20260412_000016_create_settings.rs` — 分层键值配置表
|
||||
- `m20260412_000017_create_numbering_rules.rs` — 编号规则表
|
||||
- `m20260412_000018_create_process_definitions.rs`
|
||||
- `m20260412_000019_create_process_instances.rs`
|
||||
- `m20260412_000020_create_tokens.rs`
|
||||
- `m20260412_000021_create_tasks.rs`
|
||||
- `m20260412_000022_create_process_variables.rs`
|
||||
- 修改: `lib.rs` — 注册新迁移
|
||||
|
||||
**表结构:**
|
||||
|
||||
### dictionaries
|
||||
### process_definitions
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | uuid PK | UUIDv7 |
|
||||
| tenant_id | uuid NOT NULL | 租户 ID |
|
||||
| name | string NOT NULL | 显示名称 |
|
||||
| code | string NOT NULL | 字典键(如 gender) |
|
||||
| description | text NULL | 说明 |
|
||||
| name | string NOT NULL | 流程名称 |
|
||||
| key | string NOT NULL | 流程唯一编码 |
|
||||
| version | int NOT NULL DEFAULT 1 | 版本号 |
|
||||
| category | string NULL | 分类(如 leave, expense) |
|
||||
| description | text NULL | 描述 |
|
||||
| nodes | jsonb NOT NULL DEFAULT '[]' | 节点定义(BPMN 子集) |
|
||||
| edges | jsonb NOT NULL DEFAULT '[]' | 连线定义 |
|
||||
| status | string NOT NULL DEFAULT 'draft' | draft/published/deprecated |
|
||||
| + 标准审计字段 | | |
|
||||
| 唯一索引: | `(tenant_id, code) WHERE deleted_at IS NULL` | |
|
||||
| 唯一索引: | `(tenant_id, key, version) WHERE deleted_at IS NULL` | |
|
||||
|
||||
### dictionary_items
|
||||
### process_instances
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | uuid PK | UUIDv7 |
|
||||
| tenant_id | uuid NOT NULL | |
|
||||
| dictionary_id | uuid NOT NULL | FK → dictionaries |
|
||||
| label | string NOT NULL | 显示标签 |
|
||||
| value | string NOT NULL | 存储值 |
|
||||
| sort_order | int DEFAULT 0 | 排序 |
|
||||
| color | string NULL | 颜色标签 |
|
||||
| definition_id | uuid NOT NULL FK → process_definitions | |
|
||||
| business_key | string NULL | 业务关联键(如请假单 ID) |
|
||||
| status | string NOT NULL DEFAULT 'running' | running/suspended/completed/terminated |
|
||||
| started_by | uuid NOT NULL | 发起人 user_id |
|
||||
| started_at | timestamptz NOT NULL DEFAULT NOW() | |
|
||||
| completed_at | timestamptz NULL | |
|
||||
| + 标准审计字段 | | |
|
||||
| 唯一索引: | `(dictionary_id, value) WHERE deleted_at IS NULL` | |
|
||||
| 索引: | `idx_instances_status (tenant_id, status)` | |
|
||||
|
||||
### menus(树形自引用)
|
||||
### tokens
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | uuid PK | UUIDv7 |
|
||||
| tenant_id | uuid NOT NULL | |
|
||||
| parent_id | uuid NULL | 自引用 |
|
||||
| title | string NOT NULL | 菜单标题 |
|
||||
| path | string NULL | 前端路由 |
|
||||
| icon | string NULL | 图标名 |
|
||||
| sort_order | int DEFAULT 0 | |
|
||||
| visible | bool DEFAULT true | |
|
||||
| menu_type | string DEFAULT 'page' | page/link/button |
|
||||
| permission | string NULL | 所需权限码 |
|
||||
| + 标准审计字段 | | |
|
||||
| instance_id | uuid NOT NULL FK → process_instances | |
|
||||
| node_id | string NOT NULL | 当前所在节点 ID |
|
||||
| status | string NOT NULL DEFAULT 'active' | active/consumed/terminated |
|
||||
| created_at | timestamptz NOT NULL DEFAULT NOW() | |
|
||||
| consumed_at | timestamptz NULL | |
|
||||
| 索引: | `idx_tokens_instance (instance_id)` | |
|
||||
|
||||
### menu_roles(复合主键)
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| menu_id | uuid NOT NULL | PK 组成 |
|
||||
| role_id | uuid NOT NULL | PK 组成 |
|
||||
| tenant_id | uuid NOT NULL | |
|
||||
| + 标准审计字段 | | |
|
||||
| 唯一索引: | `(menu_id, role_id) WHERE deleted_at IS NULL` | |
|
||||
|
||||
### settings(分层配置)
|
||||
### tasks
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | uuid PK | UUIDv7 |
|
||||
| tenant_id | uuid NOT NULL | |
|
||||
| scope | string NOT NULL | platform/tenant/org/user |
|
||||
| scope_id | uuid NULL | 平台=NULL, 租户=tenant_id 等 |
|
||||
| setting_key | string NOT NULL | |
|
||||
| setting_value | jsonb DEFAULT '{}' | |
|
||||
| instance_id | uuid NOT NULL FK → process_instances | |
|
||||
| token_id | uuid NOT NULL FK → tokens | |
|
||||
| node_id | string NOT NULL | 对应的流程节点 |
|
||||
| node_name | string NULL | 节点名称(冗余,便于查询) |
|
||||
| assignee_id | uuid NULL | 指定处理人 |
|
||||
| candidate_groups | jsonb NULL | 候选角色组 |
|
||||
| status | string NOT NULL DEFAULT 'pending' | pending/approved/rejected/delegated |
|
||||
| outcome | string NULL | 审批结果 |
|
||||
| form_data | jsonb NULL | 表单数据 |
|
||||
| due_date | timestamptz NULL | 到期时间 |
|
||||
| completed_at | timestamptz NULL | |
|
||||
| + 标准审计字段 | | |
|
||||
| 唯一索引: | `(scope, scope_id, setting_key) WHERE deleted_at IS NULL` | |
|
||||
| 索引: | `idx_tasks_assignee (tenant_id, assignee_id, status)` | |
|
||||
| 索引: | `idx_tasks_instance (instance_id)` | |
|
||||
|
||||
### numbering_rules
|
||||
### process_variables
|
||||
| 列 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | uuid PK | UUIDv7 |
|
||||
| tenant_id | uuid NOT NULL | |
|
||||
| name | string NOT NULL | 规则名称 |
|
||||
| code | string NOT NULL | 唯一编码(如 INV) |
|
||||
| prefix | string DEFAULT '' | 前缀 |
|
||||
| date_format | string NULL | 如 %Y%m%d |
|
||||
| seq_length | int DEFAULT 4 | 序列位数 |
|
||||
| seq_start | int DEFAULT 1 | 起始值 |
|
||||
| seq_current | bigint DEFAULT 0 | 当前序列 |
|
||||
| separator | string DEFAULT '-' | 分隔符 |
|
||||
| reset_cycle | string DEFAULT 'never' | never/daily/monthly/yearly |
|
||||
| last_reset_date | date NULL | |
|
||||
| + 标准审计字段 | | |
|
||||
| 唯一索引: | `(tenant_id, code) WHERE deleted_at IS NULL` | |
|
||||
| instance_id | uuid NOT NULL FK → process_instances | |
|
||||
| name | string NOT NULL | 变量名 |
|
||||
| var_type | string NOT NULL DEFAULT 'string' | string/number/boolean/date/json |
|
||||
| value_string | text NULL | |
|
||||
| value_number | double precision NULL | |
|
||||
| value_boolean | boolean NULL | |
|
||||
| value_date | timestamptz NULL | |
|
||||
| 唯一索引: | `(instance_id, name)` | |
|
||||
|
||||
**验证:** `cargo run -p erp-server` 启动后 `\dt` 可见新表
|
||||
|
||||
@@ -137,18 +139,15 @@ Phase 1(基础设施)和 Phase 2(身份与权限)已完成。Phase 3 需
|
||||
|
||||
## Task 3: SeaORM Entity
|
||||
|
||||
**目标:** 为 6 张表创建 Entity 定义。
|
||||
|
||||
**创建文件(`crates/erp-config/src/entity/`):**
|
||||
**创建文件(`crates/erp-workflow/src/entity/`):**
|
||||
- `mod.rs` — 导出所有实体
|
||||
- `dictionary.rs` — Dictionary Entity
|
||||
- `dictionary_item.rs` — DictionaryItem Entity
|
||||
- `menu.rs` — Menu Entity
|
||||
- `menu_role.rs` — MenuRole Entity(复合主键模式,参考 role_permission)
|
||||
- `setting.rs` — Setting Entity
|
||||
- `numbering_rule.rs` — NumberingRule Entity
|
||||
- `process_definition.rs`
|
||||
- `process_instance.rs`
|
||||
- `token.rs`
|
||||
- `task.rs`
|
||||
- `process_variable.rs`
|
||||
|
||||
**模式:** 参考 `erp-auth/src/entity/role.rs`,包含 Relation 和 Related 实现。
|
||||
**模式:** 参考 `erp-config/src/entity/numbering_rule.rs`,包含 Relation 和 Related。
|
||||
|
||||
**验证:** `cargo check` 通过
|
||||
|
||||
@@ -156,174 +155,215 @@ Phase 1(基础设施)和 Phase 2(身份与权限)已完成。Phase 3 需
|
||||
|
||||
## Task 4: DTO 定义
|
||||
|
||||
**目标:** 定义所有配置端点的请求/响应类型。
|
||||
|
||||
**修改文件:** `crates/erp-config/src/dto.rs`
|
||||
**修改文件:** `crates/erp-workflow/src/dto.rs`
|
||||
|
||||
**包含:**
|
||||
- 字典 DTO:DictionaryResp, DictionaryItemResp, CreateDictionaryReq, UpdateDictionaryReq, CreateDictionaryItemReq, UpdateDictionaryItemReq
|
||||
- 菜单 DTO:MenuResp(含 children 递归), CreateMenuReq, UpdateMenuReq, BatchSaveMenuReq
|
||||
- 设置 DTO:SettingResp, UpdateSettingReq
|
||||
- 编号规则 DTO:NumberingRuleResp, CreateNumberingRuleReq, UpdateNumberingRuleReq, GenerateNumberResp
|
||||
- 主题 DTO:ThemeResp, UpdateThemeReq(委托 settings 存储)
|
||||
- 语言 DTO:LanguageResp, UpdateLanguageReq(委托 settings 存储)
|
||||
- 流程定义:`ProcessDefinitionResp`, `CreateProcessDefinitionReq`, `UpdateProcessDefinitionReq`, `PublishDefinitionReq`
|
||||
- 流程实例:`ProcessInstanceResp`, `StartInstanceReq`
|
||||
- 任务:`TaskResp`, `CompleteTaskReq`(含 outcome + form_data)
|
||||
- 流程变量:`ProcessVariableResp`, `SetVariableReq`
|
||||
- 流程图:`NodeDef`(BPMN 节点), `EdgeDef`(连线), `FlowDiagram`(完整图)
|
||||
|
||||
**节点类型:** StartEvent, EndEvent, UserTask, ServiceTask, ExclusiveGateway, ParallelGateway
|
||||
**连线条件:** `condition` 字段为可选表达式字符串(如 `amount > 1000`)
|
||||
|
||||
**验证:** `cargo check` 通过
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Service — 字典 + 系统参数
|
||||
## Task 5: BPMN 解析器 + 表达式引擎
|
||||
|
||||
**创建文件(`crates/erp-config/src/service/`):**
|
||||
- `dictionary_service.rs` — CRUD + 字典项管理 + 按 code 查询
|
||||
- `setting_service.rs` — 分层读取(User>Org>Tenant>Platform)+ 写入
|
||||
**创建文件(`crates/erp-workflow/src/engine/`):**
|
||||
- `model.rs` — 流程图内存模型(FlowDiagram, FlowNode, FlowEdge, NodeType 枚举)
|
||||
- `parser.rs` — 解析 JSON nodes/edges 为内存模型,验证流程图合法性
|
||||
- `expression.rs` — 简单表达式求值器(支持比较运算和流程变量引用)
|
||||
|
||||
**关键逻辑:**
|
||||
- SettingService::get 实现分层覆盖查找
|
||||
- SettingService::set 使用 upsert 语义(INSERT ON CONFLICT UPDATE)
|
||||
- DictionaryService 遵循 RoleService 的无状态模式
|
||||
- `FlowDiagram::validate()` — 检查:恰好 1 个 StartEvent,至少 1 个 EndEvent,无悬空连线,网关分支/汇合配对
|
||||
- `ExpressionEvaluator::eval(expr, variables) -> bool` — 支持 `var > 1000`, `status == "approved"`, `amount <= budget` 格式
|
||||
- 解析器将 `nodes` 和 `edges` jsonb 反序列化为 `Vec<FlowNode>` 和 `Vec<FlowEdge>`
|
||||
|
||||
**验证:** 单元测试覆盖:合法流程验证、缺少 StartEvent 报错、表达式求值
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Service — 菜单 + 编号规则
|
||||
## Task 6: Token 驱动执行引擎
|
||||
|
||||
**创建文件(`crates/erp-config/src/service/`):**
|
||||
- `menu_service.rs` — 菜单树构建 + 角色过滤 + 批量保存
|
||||
- `numbering_service.rs` — 编号规则 CRUD + generate_number
|
||||
**创建文件:** `crates/erp-workflow/src/engine/executor.rs`
|
||||
|
||||
**关键逻辑:**
|
||||
- MenuService::get_menu_tree — 按 role_ids 过滤 menu_role,HashMap 分组构建树(参考 OrgService 的 build_org_tree)
|
||||
- NumberingService::generate_number — PostgreSQL advisory_lock + 事务内序列递增:
|
||||
```sql
|
||||
SELECT pg_advisory_xact_lock(hashtext($1), $2::int)
|
||||
-- $1 = rule_code, $2 = hash(tenant_id)
|
||||
```
|
||||
生成格式:`{prefix}{separator}{date}{separator}{seq_padded}`
|
||||
**核心逻辑:**
|
||||
```
|
||||
start(instance_id, definition) → 在 StartEvent 创建 token
|
||||
advance(token_id, instance_id, definition, variables) → 消费当前 token,在下一节点创建新 token
|
||||
- 到达 EndEvent → 消费 token,检查实例是否所有 token 都完成 → 完成实例
|
||||
- 到达 UserTask → 创建 token + 创建 task 记录
|
||||
- 到达 ServiceTask → 创建 token + 执行动作(占位,发布事件)
|
||||
- 到达 ExclusiveGateway → 求值条件,选择一条分支
|
||||
- 到达 ParallelGateway(分支)→ 为每条出边创建 token
|
||||
- 到达 ParallelGateway(汇合)→ 消费当前 token,等待所有入边 token 到达后创建新 token
|
||||
```
|
||||
|
||||
**并发安全:** 使用 `pg_advisory_xact_lock` 保护 token 操作(参考 NumberingService 模式)
|
||||
|
||||
**验证:** 单元测试覆盖:直线流程、排他网关分支、并行网关分支与汇合
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Handler 层
|
||||
## Task 7: Service 层
|
||||
|
||||
**创建文件(`crates/erp-config/src/handler/`):**
|
||||
- `dictionary_handler.rs` — 5 个端点
|
||||
- `menu_handler.rs` — 2 个端点
|
||||
- `setting_handler.rs` — 2 个端点
|
||||
- `numbering_handler.rs` — 4 个端点(含 generate)
|
||||
- `theme_handler.rs` — 2 个端点(委托 SettingService)
|
||||
- `language_handler.rs` — 2 个端点(委托 SettingService)
|
||||
**创建文件(`crates/erp-workflow/src/service/`):**
|
||||
- `definition_service.rs` — 流程定义 CRUD + 发布 + 版本管理
|
||||
- `instance_service.rs` — 启动实例 + 查询 + 挂起/恢复/终止
|
||||
- `task_service.rs` — 查询待办 + 完成任务 + 委派 + 查询已办
|
||||
|
||||
**关键逻辑:**
|
||||
- `DefinitionService::publish` — draft → published,验证流程图合法性
|
||||
- `InstanceService::start` — 创建实例 + 初始化变量 + 调用 executor.start
|
||||
- `TaskService::complete` — 更新 task 状态 + 调用 executor.advance + 处理下一节点
|
||||
|
||||
---
|
||||
|
||||
## Task 8: Handler 层
|
||||
|
||||
**创建文件(`crates/erp-workflow/src/handler/`):**
|
||||
- `definition_handler.rs` — 5 个端点
|
||||
- `instance_handler.rs` — 4 个端点
|
||||
- `task_handler.rs` — 4 个端点
|
||||
|
||||
**端点映射:**
|
||||
```
|
||||
GET/POST /config/dictionaries
|
||||
PUT/DELETE /config/dictionaries/{id}
|
||||
GET/PUT /config/menus
|
||||
GET/PUT /config/settings/{key}
|
||||
GET/POST /config/numbering-rules
|
||||
PUT /config/numbering-rules/{id}
|
||||
POST /config/numbering-rules/{id}/generate
|
||||
GET/PUT /config/themes
|
||||
GET /config/languages
|
||||
PUT /config/languages/{code}
|
||||
GET/POST /workflow/definitions
|
||||
GET /workflow/definitions/{id}
|
||||
PUT /workflow/definitions/{id}
|
||||
POST /workflow/definitions/{id}/publish
|
||||
POST /workflow/instances
|
||||
GET /workflow/instances
|
||||
GET /workflow/instances/{id}
|
||||
POST /workflow/instances/{id}/suspend
|
||||
POST /workflow/instances/{id}/terminate
|
||||
GET /workflow/tasks/pending — 我的待办
|
||||
GET /workflow/tasks/completed — 我的已办
|
||||
POST /workflow/tasks/{id}/complete — 完成任务
|
||||
POST /workflow/tasks/{id}/delegate — 委派任务
|
||||
```
|
||||
|
||||
**RBAC:** 所有端点使用 `require_permission(&ctx, "workflow:xxx")`
|
||||
|
||||
---
|
||||
|
||||
## Task 8: 模块注册 + 种子数据
|
||||
## Task 9: 模块注册 + 种子数据
|
||||
|
||||
**修改文件:**
|
||||
- `crates/erp-config/src/module.rs` — 填充真实路由
|
||||
- `crates/erp-auth/src/service/seed.rs` — 添加配置模块权限(dictionary/menu/setting/numbering/theme/language)
|
||||
- `crates/erp-server/src/main.rs` — 确认路由集成
|
||||
- `crates/erp-workflow/src/module.rs` — 填充真实路由(12 个端点)
|
||||
- `crates/erp-auth/src/service/seed.rs` — 添加工作流权限
|
||||
- `crates/erp-server/src/main.rs` — 注册 WorkflowModule,合并路由
|
||||
|
||||
**新增种子权限(17 个):**
|
||||
- dictionary: create/read/update/delete/list
|
||||
- menu: read/update
|
||||
- setting: read/update
|
||||
- numbering: create/read/update/generate
|
||||
- theme: read/update
|
||||
- language: read/update
|
||||
**新增种子权限(8 个):**
|
||||
- workflow:create, workflow:list, workflow:read, workflow:update
|
||||
- workflow:publish, workflow:start, workflow:approve, workflow:delegate
|
||||
|
||||
**验证:** `cargo check` + `cargo test` 通过,服务器启动后 Swagger UI 可见新端点
|
||||
**验证:** `cargo check` + `cargo test` 通过
|
||||
|
||||
---
|
||||
|
||||
## Task 9: 前端 API 层 + Settings 页面框架
|
||||
## Task 10: 前端 API 层 + 工作流页面
|
||||
|
||||
**创建文件(`apps/web/src/`):**
|
||||
- `api/dictionaries.ts` — 字典 CRUD API
|
||||
- `api/menus.ts` — 菜单 API
|
||||
- `api/settings.ts` — 设置 API
|
||||
- `api/numberingRules.ts` — 编号规则 API
|
||||
- `pages/Settings.tsx` — Tabs 壳页面
|
||||
- `api/workflowDefinitions.ts` — 流程定义 API
|
||||
- `api/workflowInstances.ts` — 流程实例 API
|
||||
- `api/workflowTasks.ts` — 任务 API
|
||||
- `pages/Workflow.tsx` — Tab 壳页面(流程定义 | 我的待办 | 我的已办 | 流程监控)
|
||||
|
||||
**修改文件:**
|
||||
- `App.tsx` — 替换 settings 占位组件
|
||||
|
||||
**Tabs 结构:** 数据字典 | 菜单配置 | 编号规则 | 系统参数 | 主题设置
|
||||
- `App.tsx` — 添加 workflow 路由
|
||||
- `MainLayout.tsx` — 侧边栏添加工作流菜单
|
||||
|
||||
---
|
||||
|
||||
## Task 10: 前端设置子页面
|
||||
## Task 11: React Flow 可视化设计器
|
||||
|
||||
**创建文件(`apps/web/src/pages/settings/`):**
|
||||
- `DictionaryManager.tsx` — Table + 展开行显示字典项,参考 Roles.tsx
|
||||
- `MenuConfig.tsx` — Tree + 编辑表单,参考 Organizations.tsx
|
||||
- `NumberingRules.tsx` — Table + Modal CRUD + 生成按钮
|
||||
- `SystemSettings.tsx` — 键值编辑列表
|
||||
- `ThemeSettings.tsx` — 颜色选择器 + 表单
|
||||
**创建文件(`apps/web/src/pages/workflow/`):**
|
||||
- `ProcessDesigner.tsx` — React Flow 画布 + 节点面板 + 属性面板
|
||||
- `nodes/` — 自定义节点组件(StartEvent, EndEvent, UserTask, ServiceTask, Gateway)
|
||||
- `edges/` — 条件标签连线组件
|
||||
- `hooks/useFlowValidation.ts` — 流程图前端验证
|
||||
|
||||
**修改文件:**
|
||||
- `Settings.tsx` — 导入子组件
|
||||
- `MainLayout.tsx` — 更新设置菜单图标
|
||||
**依赖:** `@xyflow/react` npm 包
|
||||
|
||||
**验证:** `pnpm dev` 启动,访问 /settings 各 tab 可正常交互
|
||||
**功能:**
|
||||
- 拖拽添加节点到画布
|
||||
- 连线编辑(含条件表达式)
|
||||
- 节点属性编辑面板
|
||||
- 导出为 JSON nodes/edges 格式(匹配后端 DTO)
|
||||
- 流程图合法性前端验证
|
||||
|
||||
---
|
||||
|
||||
## Task 12: 流程图查看器 + 超时框架
|
||||
|
||||
**创建文件(`apps/web/src/pages/workflow/`):**
|
||||
- `ProcessViewer.tsx` — 只读 React Flow 渲染,高亮当前活跃节点
|
||||
- `InstanceDetail.tsx` — 实例详情页(流程图 + 变量 + 任务历史)
|
||||
|
||||
**超时框架(后端占位):**
|
||||
- `crates/erp-workflow/src/engine/timeout.rs` — 超时检查接口
|
||||
- Task 表 `due_date` 字段已支持
|
||||
|
||||
**验证:** `pnpm dev` 启动,工作流设计器可拖拽节点、连线、保存
|
||||
|
||||
---
|
||||
|
||||
## 依赖图
|
||||
|
||||
```
|
||||
前置重构(RBAC→erp-core)
|
||||
|
|
||||
Task 1(骨架)
|
||||
|
|
||||
|
|
||||
Task 2(迁移)→ Task 3(Entity)→ Task 4(DTO)
|
||||
|
|
||||
+----------------+----------------+
|
||||
| |
|
||||
Task 5(字典+设置 Service) Task 6(菜单+编号 Service)
|
||||
| |
|
||||
+----------------+----------------+
|
||||
|
|
||||
Task 7(Handler)
|
||||
|
|
||||
Task 8(集成+种子)
|
||||
|
|
||||
Task 9(前端API+壳)
|
||||
|
|
||||
Task 10(前端页面)
|
||||
|
|
||||
+---------------+---------------+
|
||||
| |
|
||||
Task 5(BPMN 解析器) Task 6(执行引擎)
|
||||
| |
|
||||
+---------------+---------------+
|
||||
|
|
||||
Task 7(Service)
|
||||
|
|
||||
Task 8(Handler)
|
||||
|
|
||||
Task 9(集成+种子)
|
||||
|
|
||||
+---------------+---------------+
|
||||
| |
|
||||
Task 10(前端页面) Task 11(可视化设计器)
|
||||
| |
|
||||
+---------------+---------------+
|
||||
|
|
||||
Task 12(查看器+超时)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验证清单
|
||||
|
||||
- [ ] `cargo check` 全 workspace 通过
|
||||
- [ ] `cargo test --workspace` 全部通过
|
||||
- [ ] Docker 环境正常启动
|
||||
- [ ] 所有迁移可正/反向执行
|
||||
- [ ] API 端点可通过 Swagger UI 测试
|
||||
- [ ] 前端 /settings 页面各 Tab 正常工作
|
||||
- [ ] 12 个工作流 API 端点可测试
|
||||
- [ ] 前端工作流设计器可拖拽节点和连线
|
||||
- [ ] 流程图保存和加载正常
|
||||
- [ ] 所有代码已提交
|
||||
|
||||
## 关键参考文件
|
||||
|
||||
| 用途 | 文件路径 |
|
||||
|------|----------|
|
||||
| Service 模式 | `crates/erp-auth/src/service/role_service.rs` |
|
||||
| Handler 模式 | `crates/erp-auth/src/handler/role_handler.rs` |
|
||||
| 树构建模式 | `crates/erp-auth/src/service/org_service.rs` |
|
||||
| 迁移模式 | `crates/erp-server/migration/src/m20260411_000005_create_roles.rs` |
|
||||
| Service 模式 | `crates/erp-config/src/service/numbering_service.rs` |
|
||||
| Handler 模式 | `crates/erp-config/src/handler/numbering_handler.rs` |
|
||||
| State 桥接 | `crates/erp-server/src/state.rs` |
|
||||
| 复合主键 Entity | `crates/erp-auth/src/entity/role_permission.rs` |
|
||||
| 模块注册 | `crates/erp-config/src/module.rs` |
|
||||
| 迁移模式 | `crates/erp-server/migration/src/m20260412_000016_create_settings.rs` |
|
||||
| Advisory Lock | `crates/erp-config/src/service/numbering_service.rs` (generate_number) |
|
||||
| 前端 Table CRUD | `apps/web/src/pages/Roles.tsx` |
|
||||
| 前端树形展示 | `apps/web/src/pages/Organizations.tsx` |
|
||||
| RBAC 工具函数 | `crates/erp-auth/src/middleware/rbac.rs`(待迁移到 erp-core) |
|
||||
| RBAC | `crates/erp-core/src/rbac.rs` |
|
||||
|
||||
Reference in New Issue
Block a user