fix(用户管理): 修复用户列表页面加载失败问题
修复用户列表页面加载失败导致测试超时的问题,确保页面元素正确渲染
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
# 插件系统增强设计规格
|
||||
|
||||
## Context
|
||||
|
||||
插件系统是 ERP 平台的核心差异化能力,当前声明式层面(manifest schema、动态表、前端页面)已达 90% 成熟度。但 WASM 逻辑层存在根本性限制:
|
||||
|
||||
1. **插件无法自主查询数据** — `db_query` 的 filter/pagination 参数被忽略,只能使用预填充结果
|
||||
2. **无读后写一致性** — 延迟刷新模型导致插件在一次调用中无法读取自己刚写入的数据
|
||||
3. **聚合只有 COUNT** — 缺少 SUM/AVG/MAX/MIN,无法支撑财务、统计类场景
|
||||
4. **热更新无原子回滚** — 旧版本先卸载再加载新版本,中间失败无保障
|
||||
5. **Schema 变更只支持新增实体** — 不支持已有实体的字段演进
|
||||
|
||||
这些限制使插件系统只能支撑"数据管理+展示"型轻量场景(CRM、简单进销存),无法支撑需要复杂业务逻辑的行业(财务、制造、电商)。
|
||||
|
||||
本次增强的目标:**让插件逻辑层从 40% 提升到 80%+,使系统能真正承载不同行业的定制化需求。**
|
||||
|
||||
---
|
||||
|
||||
## 改动 1:混合执行模型(解决查询和读后写一致性)
|
||||
|
||||
### 问题
|
||||
|
||||
`host.rs:99-109` — `db_query` 忽略 `_filter` 和 `_pagination` 参数,只从 `query_results` 预填充缓存取数据。插件无法自主构造查询。
|
||||
|
||||
### 方案:读操作走实时 SQL + 写操作保持延迟批量 + 读前自动 flush
|
||||
|
||||
核心流程变更:
|
||||
|
||||
```
|
||||
当前:
|
||||
WASM 调用 db_insert() → 入队 pending_ops
|
||||
WASM 调用 db_query() → 从预填充缓存读(忽略 filter/pagination)
|
||||
WASM 结束 → flush 全部 pending_ops
|
||||
|
||||
改为:
|
||||
WASM 调用 db_insert() → 入队 pending_ops
|
||||
WASM 调用 db_query() → 先 flush pending_ops → 执行真实 SQL 查询 → 返回结果
|
||||
WASM 结束 → flush 剩余 pending_ops
|
||||
```
|
||||
|
||||
### 改动文件
|
||||
|
||||
#### 1. `crates/erp-plugin/src/host.rs`
|
||||
|
||||
HostState 新增字段:
|
||||
|
||||
```rust
|
||||
pub struct HostState {
|
||||
// ... 现有字段保留 ...
|
||||
pub(crate) db: Option<DatabaseConnection>,
|
||||
pub(crate) event_bus: Option<EventBus>,
|
||||
}
|
||||
```
|
||||
|
||||
db_query 实现变更 — 使用 `tokio::runtime::Handle::current()` 在 `spawn_blocking` 内执行异步 DB 操作:
|
||||
|
||||
1. 先 `block_on(flush_ops(...))` 清空 pending writes
|
||||
2. 解析 filter/pagination 参数
|
||||
3. 调用 `DynamicTableManager::build_query_sql()` 构建查询
|
||||
4. `block_on` 执行查询并返回结果
|
||||
|
||||
向后兼容:`db = None` 时走旧的预填充路径。
|
||||
|
||||
#### 2. `crates/erp-plugin/src/dynamic_table.rs`
|
||||
|
||||
新增 `build_query_sql` 方法,复用 `data_service.rs` 中的查询构建逻辑。
|
||||
|
||||
### 向后兼容
|
||||
|
||||
- `HostState::new()` 不传 db → 走旧的预填充路径
|
||||
- `execute_wasm()` 传 db → 走新的实时查询路径
|
||||
- 现有 WASM 插件无需修改
|
||||
|
||||
---
|
||||
|
||||
## 改动 2:扩展聚合查询
|
||||
|
||||
### 问题
|
||||
|
||||
`data_service.rs:655` 的 `aggregate` 方法只支持 `GROUP BY + COUNT(*)`。
|
||||
|
||||
### 方案
|
||||
|
||||
新增 `aggregate_multi` 方法支持 SUM/AVG/MAX/MIN。
|
||||
|
||||
改动文件:
|
||||
|
||||
1. `data_service.rs` — 新增 `AggregateDef`、`AggregateFunc`、`AggregateResult` 类型和 `aggregate_multi` 方法
|
||||
2. `dynamic_table.rs` — 新增 `build_aggregate_multi_sql` 方法
|
||||
3. `data_handler.rs` — 扩展聚合 API 端点
|
||||
4. 前端 Dashboard Widget 适配多聚合返回格式
|
||||
|
||||
SQL 示例:
|
||||
```sql
|
||||
SELECT _f_status as key,
|
||||
COUNT(*) as count,
|
||||
COALESCE(SUM(_f_amount), 0) as sum_amount,
|
||||
COALESCE(AVG(_f_price), 0) as avg_price
|
||||
FROM plugin_erp_crm__order
|
||||
WHERE tenant_id = $1 AND deleted_at IS NULL
|
||||
GROUP BY _f_status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 改动 3:热更新原子回滚
|
||||
|
||||
### 问题
|
||||
|
||||
`service.rs:578-585` — 先 `unload(old)` 再 `load(new)`,中间失败无回滚。
|
||||
|
||||
### 方案:先加载新版本到临时 key,成功后原子替换
|
||||
|
||||
改动文件:
|
||||
|
||||
1. `service.rs` — upgrade 方法改用临时 key 加载新版本
|
||||
2. `engine.rs` — 新增 `rename_plugin` 方法
|
||||
|
||||
安全保证:新版本加载失败 → 旧版本仍在运行,零停机。
|
||||
|
||||
---
|
||||
|
||||
## 改动 4:Schema 演进(ALTER TABLE 支持)
|
||||
|
||||
### 问题
|
||||
|
||||
升级时只处理新增实体(CREATE TABLE),不处理已有实体的字段变更。
|
||||
|
||||
### 方案:利用 JSONB 特性实现轻量级 Schema 演进
|
||||
|
||||
大部分字段变更不需要 DDL(JSONB 天然支持),仅新增 filterable/sortable 字段需 ALTER TABLE ADD Generated Column + 索引。
|
||||
|
||||
改动文件:
|
||||
|
||||
1. `service.rs` — upgrade 方法增加 schema diff 逻辑
|
||||
2. `dynamic_table.rs` — 新增 `FieldDiff`、`diff_entity_fields`、`alter_add_generated_columns`
|
||||
|
||||
---
|
||||
|
||||
## 实施顺序
|
||||
|
||||
| 阶段 | 改动 | 复杂度 | 影响范围 |
|
||||
|------|------|--------|---------|
|
||||
| 1 | 热更新原子回滚 | 低 | engine.rs + service.rs |
|
||||
| 2 | Schema 演进(ALTER TABLE) | 中低 | service.rs + dynamic_table.rs |
|
||||
| 3 | 扩展聚合查询 | 中 | data_service.rs + data_handler.rs + dynamic_table.rs |
|
||||
| 4 | 混合执行模型(查询能力) | 高 | host.rs + engine.rs + dynamic_table.rs |
|
||||
|
||||
---
|
||||
|
||||
## 验证方案
|
||||
|
||||
### 阶段 1:热更新回滚
|
||||
1. 上传损坏的 WASM 二进制 → 验证旧版本仍在运行
|
||||
2. 上传正确的新版本 → 验证成功切换
|
||||
|
||||
### 阶段 2:Schema 演进
|
||||
1. 升级插件增加 filterable 字段 → 验证 ALTER TABLE 正确执行
|
||||
2. 旧数据上新 Generated Column 值正确填充
|
||||
|
||||
### 阶段 3:聚合查询
|
||||
1. 创建测试数据,调用聚合 API → 验证 SUM/AVG 结果正确
|
||||
2. 前端 Dashboard 展示正确
|
||||
|
||||
### 阶段 4:混合执行模型
|
||||
1. 插件 WASM 中 db_insert 后立即 db_query → 读后写一致性
|
||||
2. 带 filter 的 db_query → 过滤结果正确
|
||||
3. 旧插件(预填充模式)仍能正常工作
|
||||
4. 多次连续 db_query 不超过 Fuel 限制
|
||||
|
||||
---
|
||||
|
||||
## 关键文件清单
|
||||
|
||||
| 文件 | 改动类型 |
|
||||
|------|---------|
|
||||
| `crates/erp-plugin/src/host.rs` | 重构 db_query + 新增 db/事件总线字段 |
|
||||
| `crates/erp-plugin/src/engine.rs` | 调整 execute_wasm + 新增 rename_plugin |
|
||||
| `crates/erp-plugin/src/service.rs` | 升级流程回滚安全 + schema diff |
|
||||
| `crates/erp-plugin/src/dynamic_table.rs` | 新增 build_query_sql + alter_add_generated_columns + diff_entity_fields |
|
||||
| `crates/erp-plugin/src/data_service.rs` | 新增 aggregate_multi + AggregateDef |
|
||||
| `crates/erp-plugin/src/data_handler.rs` | 扩展聚合 API |
|
||||
| `apps/web/src/pages/PluginDashboardPage.tsx` | 适配多聚合返回格式 |
|
||||
Reference in New Issue
Block a user