- 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
8.0 KiB
8.0 KiB
Phase 5-6 Implementation Plan: Message Center + Integration & Polish
Context
Phase 1-4 已完成(core, auth, config, workflow)。现在需要实现 Phase 5(消息中心)和 Phase 6(整合与打磨)。erp-message crate 当前是空壳,需要完整实现。
Phase 5: 消息中心
Task 5.1: 数据库迁移 — 消息相关表
新增 3 个迁移文件:
-
m20260413_000023_create_message_templates.rs— 消息模板表- id (UUID PK), tenant_id, name, code (唯一编码), channel (in_app/email/sms/wechat),
- title_template, body_template (支持
{{variable}}插值), language (zh-CN/en-US), - 标准审计字段 (created_at, updated_at, created_by, updated_by, deleted_at)
-
m20260413_000024_create_messages.rs— 消息表- id (UUID PK), tenant_id, template_id (FK, nullable),
- sender_id (UUID, nullable=系统消息), sender_type (system/user),
- recipient_id (UUID, not null), recipient_type (user/role/department/all),
- title, body, priority (normal/important/urgent),
- business_type (workflow_task/system_notice/...), business_id (deep link ref),
- is_read (bool), read_at (nullable),
- is_archived (bool), archived_at (nullable),
- sent_at (nullable, for scheduled), status (pending/sent/recalled),
- 标准审计字段
-
m20260413_000025_create_message_subscriptions.rs— 消息订阅偏好- id (UUID PK), tenant_id, user_id,
- notification_types (JSON: 订阅的通知类型列表),
- channel_preferences (JSON: 各类型偏好的通道),
- dnd_enabled (bool), dnd_start (time), dnd_end (time),
- 标准审计字段
修改文件:
crates/erp-server/migration/src/lib.rs— 注册 3 个新迁移
Task 5.2: erp-message crate 基础结构
修改/创建文件:
crates/erp-message/Cargo.toml— 补齐缺失依赖 (thiserror, utoipa, async-trait, validator, serde/uuid/chrono features, sea-orm features)crates/erp-message/src/lib.rs— 声明子模块 + pub usecrates/erp-message/src/message_state.rs— MessageState { db, event_bus }crates/erp-message/src/error.rs— MessageError 枚举 + From implscrates/erp-message/src/dto.rs— 请求/响应 DTOscrates/erp-message/src/entity/mod.rs— 实体子模块声明crates/erp-message/src/entity/message_template.rscrates/erp-message/src/entity/message.rscrates/erp-message/src/entity/message_subscription.rscrates/erp-message/src/module.rs— MessageModule 实现 ErpModule
Task 5.3: 消息 CRUD 服务与处理器
创建文件:
crates/erp-message/src/service/mod.rscrates/erp-message/src/service/message_service.rs— 消息 CRUD + 发送 + 已读/未读crates/erp-message/src/service/template_service.rs— 模板 CRUD + 变量插值渲染crates/erp-message/src/service/subscription_service.rs— 订阅偏好 CRUDcrates/erp-message/src/handler/mod.rscrates/erp-message/src/handler/message_handler.rs— 消息 API handlerscrates/erp-message/src/handler/template_handler.rs— 模板 API handlerscrates/erp-message/src/handler/subscription_handler.rs— 订阅 API handlers
路由设计:
GET /messages — 消息列表 (分页, 支持 status/priority/is_read 过滤)
GET /messages/unread-count — 未读消息数
PUT /messages/{id}/read — 标记已读
PUT /messages/read-all — 全部标记已读
DELETE /messages/{id} — 删除消息 (软删除)
POST /messages/send — 发送消息
GET /message-templates — 模板列表
POST /message-templates — 创建模板
PUT /message-subscriptions — 更新订阅偏好
Task 5.4: 服务器端集成
修改文件:
crates/erp-server/Cargo.toml— 添加 erp-message 依赖crates/erp-server/src/state.rs— 添加FromRef<AppState> for MessageStatecrates/erp-server/src/main.rs— 初始化并注册 MessageModule,合并路由
Task 5.5: 前端 — 消息 API 与页面
创建/修改文件:
apps/web/src/api/messages.ts— 消息 API 客户端apps/web/src/api/messageTemplates.ts— 模板 API 客户端apps/web/src/pages/Messages.tsx— 消息中心主页面 (Tabs: 通知列表/已归档)apps/web/src/pages/messages/NotificationList.tsx— 通知列表子组件apps/web/src/pages/messages/MessageTemplates.tsx— 模板管理子组件apps/web/src/pages/messages/NotificationPreferences.tsx— 通知偏好设置apps/web/src/App.tsx— 添加/messages路由apps/web/src/layouts/MainLayout.tsx— 添加消息菜单项 + Bell 点击弹出通知面板
Task 5.6: 通知面板与未读计数
修改文件:
apps/web/src/layouts/MainLayout.tsx— Bell 图标添加 Badge (未读数) + Popover 通知面板apps/web/src/stores/message.ts— Zustand store: unreadCount, fetchUnread, recentMessagesapps/web/src/components/NotificationPanel.tsx— 通知弹出面板组件
Phase 6: 整合与打磨
Task 6.1: 跨模块事件集成 — 工作流 → 消息
修改文件:
crates/erp-message/src/module.rs—register_event_handlers()订阅工作流事件crates/erp-message/src/service/message_service.rs— 添加事件处理方法- 订阅的事件:
workflow.instance.started→ 通知发起人workflow.task.created→ 通知待办人workflow.task.completed→ 通知发起人workflow.instance.completed→ 通知发起人workflow.instance.terminated→ 通知相关人
Task 6.2: 审计日志
创建/修改文件:
- 迁移
m20260413_000026_create_audit_logs.rs— 审计日志表- id, tenant_id, user_id, action, resource_type, resource_id,
- old_value (JSON), new_value (JSON), ip_address, user_agent,
- 标准审计字段
crates/erp-core/src/audit.rs— 审计中间件/工具函数crates/erp-server/src/main.rs— 应用审计中间件到 protected routes
Task 6.3: API 文档完善
修改文件:
crates/erp-server/src/main.rs— 添加 utoipa Swagger UI 路由- 各模块已有 utoipa 注解,确保正确注册到 OpenApi
Task 6.4: 安全审查
检查项:
- JWT 中间件正确性
- 多租户隔离 (所有查询带 tenant_id)
- SQL 注入防护 (SeaORM 参数化)
- CORS 配置
- 密码安全 (Argon2)
- 输入验证 (所有 API 端点)
- 错误信息不泄露敏感数据
Task 6.5: 前端整合完善
修改文件:
apps/web/src/layouts/MainLayout.tsx— 完善通知面板交互- 工作流页面集成消息通知反馈
- 整体 UI 打磨和一致性检查
实施顺序
Task 5.1 (迁移)
→ Task 5.2 (crate 基础)
→ Task 5.3 (服务+处理器)
→ Task 5.4 (服务器集成)
→ Task 5.5 (前端页面)
→ Task 5.6 (通知面板)
→ Task 6.1 (事件集成)
→ Task 6.2 (审计日志)
→ Task 6.3 (API 文档)
→ Task 6.4 (安全审查)
→ Task 6.5 (前端整合)
每个 Task 完成后立即提交。每个 Task 预计产生 1 个 commit。
验证方式
cargo check— 全 workspace 编译通过cargo test --workspace— 所有测试通过cargo run -p erp-server— 服务启动正常- 浏览器验证消息 CRUD 流程
- 验证通知面板未读计数
- 验证工作流事件触发消息通知
- Swagger UI 验证 API 文档
关键文件索引
| 用途 | 文件路径 |
|---|---|
| 迁移注册 | crates/erp-server/migration/src/lib.rs |
| 服务器入口 | crates/erp-server/src/main.rs |
| 状态桥接 | crates/erp-server/src/state.rs |
| 模块 trait | crates/erp-core/src/module.rs |
| 事件总线 | crates/erp-core/src/events.rs |
| 错误类型 | crates/erp-core/src/error.rs |
| 前端路由 | apps/web/src/App.tsx |
| 布局 | apps/web/src/layouts/MainLayout.tsx |
| API 客户端 | apps/web/src/api/client.ts |
| 参考模块 | crates/erp-workflow/ (完整模式参考) |