From 40bac74f5c587ae7c16021fe9265214ace68ca42 Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 18 Apr 2026 08:12:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=A1=E8=AE=A1=E4=BF=AE=E5=A4=8D=20?= =?UTF-8?q?=E2=80=94=20ErrorBoundary=20=E6=8E=A5=E5=85=A5=20+=20data=5Fsco?= =?UTF-8?q?pe=20=E5=85=A8=E7=AB=AF=E7=82=B9=E6=8E=A5=E7=BA=BF=20+=20invent?= =?UTF-8?q?ory.wasm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. H1: App.tsx 接入 ErrorBoundary 包裹 Suspense,防止页面渲染错误导致白屏 2. H2: data_scope 行级权限扩展到 count/aggregate/timeseries 端点, 所有数据查询操作现在都受 data_scope 过滤 3. M3: 进销存插件 WASM 编译部署到 apps/web/public/inventory.wasm --- apps/web/public/inventory.wasm | Bin 0 -> 22139 bytes apps/web/src/App.tsx | 3 ++ crates/erp-plugin/src/data_service.rs | 32 +++++++++++++++--- crates/erp-plugin/src/handler/data_handler.rs | 18 ++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 apps/web/public/inventory.wasm diff --git a/apps/web/public/inventory.wasm b/apps/web/public/inventory.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ec18f60610d29740f2008b917e01f94f2837aaac GIT binary patch literal 22139 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 YeGEJgQIhP0ssegCIl=~iIlMgn|5BtX+W-In literal 0 HcmV?d00001 diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 2e4d953..b888716 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -4,6 +4,7 @@ import { ConfigProvider, theme as antdTheme, Spin } from 'antd'; import zhCN from 'antd/locale/zh_CN'; import MainLayout from './layouts/MainLayout'; import Login from './pages/Login'; +import { ErrorBoundary } from './components/ErrorBoundary'; import { useAuthStore } from './stores/auth'; import { useAppStore } from './stores/app'; @@ -133,6 +134,7 @@ export default function App() { element={ + }> } /> @@ -151,6 +153,7 @@ export default function App() { } /> + } diff --git a/crates/erp-plugin/src/data_service.rs b/crates/erp-plugin/src/data_service.rs index e5455bc..c12e236 100644 --- a/crates/erp-plugin/src/data_service.rs +++ b/crates/erp-plugin/src/data_service.rs @@ -527,6 +527,7 @@ impl PluginDataService { db: &sea_orm::DatabaseConnection, filter: Option, search: Option, + scope: Option, ) -> AppResult { let info = resolve_entity_info(plugin_id, entity_name, tenant_id, db).await?; @@ -543,7 +544,7 @@ impl PluginDataService { } }; - let (sql, values) = DynamicTableManager::build_filtered_count_sql( + let (mut sql, mut values) = DynamicTableManager::build_filtered_count_sql( &info.table_name, tenant_id, filter, @@ -551,6 +552,13 @@ impl PluginDataService { ) .map_err(|e| AppError::Validation(e))?; + // 合并数据权限条件 + let scope_condition = build_scope_sql(&scope, &info.generated_fields); + if !scope_condition.0.is_empty() { + sql = merge_scope_condition(sql, &scope_condition); + values.extend(scope_condition.1); + } + #[derive(FromQueryResult)] struct CountResult { count: i64, @@ -578,10 +586,11 @@ impl PluginDataService { db: &sea_orm::DatabaseConnection, group_by_field: &str, filter: Option, + scope: Option, ) -> AppResult> { let info = resolve_entity_info(plugin_id, entity_name, tenant_id, db).await?; - let (sql, values) = DynamicTableManager::build_aggregate_sql( + let (mut sql, mut values) = DynamicTableManager::build_aggregate_sql( &info.table_name, tenant_id, group_by_field, @@ -589,6 +598,13 @@ impl PluginDataService { ) .map_err(|e| AppError::Validation(e))?; + // 合并数据权限条件 + let scope_condition = build_scope_sql(&scope, &info.generated_fields); + if !scope_condition.0.is_empty() { + sql = merge_scope_condition(sql, &scope_condition); + values.extend(scope_condition.1); + } + #[derive(FromQueryResult)] struct AggRow { key: Option, @@ -621,7 +637,7 @@ impl PluginDataService { filter: Option, ) -> AppResult> { // TODO: 未来版本添加 Redis 缓存层 - Self::aggregate(plugin_id, entity_name, tenant_id, db, group_by_field, filter).await + Self::aggregate(plugin_id, entity_name, tenant_id, db, group_by_field, filter, None).await } /// 时间序列聚合 — 按时间字段截断为 day/week/month 统计计数 @@ -634,10 +650,11 @@ impl PluginDataService { time_grain: &str, start: Option, end: Option, + scope: Option, ) -> AppResult> { let info = resolve_entity_info(plugin_id, entity_name, tenant_id, db).await?; - let (sql, values) = DynamicTableManager::build_timeseries_sql( + let (mut sql, mut values) = DynamicTableManager::build_timeseries_sql( &info.table_name, tenant_id, time_field, @@ -647,6 +664,13 @@ impl PluginDataService { ) .map_err(|e| AppError::Validation(e))?; + // 合并数据权限条件 + let scope_condition = build_scope_sql(&scope, &info.generated_fields); + if !scope_condition.0.is_empty() { + sql = merge_scope_condition(sql, &scope_condition); + values.extend(scope_condition.1); + } + #[derive(FromQueryResult)] struct TsRow { period: Option, diff --git a/crates/erp-plugin/src/handler/data_handler.rs b/crates/erp-plugin/src/handler/data_handler.rs index e6d0104..ce16f7c 100644 --- a/crates/erp-plugin/src/handler/data_handler.rs +++ b/crates/erp-plugin/src/handler/data_handler.rs @@ -390,6 +390,11 @@ where let fine_perm = compute_permission_code(&manifest_id, &entity, "list"); require_permission(&ctx, &fine_perm)?; + // 解析数据权限范围 + let scope = resolve_data_scope( + &ctx, &manifest_id, &entity, &fine_perm, &state.db, + ).await?; + // 解析 filter JSON let filter: Option = params .filter @@ -403,6 +408,7 @@ where &state.db, filter, params.search, + scope, ) .await?; @@ -434,6 +440,11 @@ where let fine_perm = compute_permission_code(&manifest_id, &entity, "list"); require_permission(&ctx, &fine_perm)?; + // 解析数据权限范围 + let scope = resolve_data_scope( + &ctx, &manifest_id, &entity, &fine_perm, &state.db, + ).await?; + // 解析 filter JSON let filter: Option = params .filter @@ -447,6 +458,7 @@ where &state.db, ¶ms.group_by, filter, + scope, ) .await?; @@ -483,6 +495,11 @@ where let fine_perm = compute_permission_code(&manifest_id, &entity, "list"); require_permission(&ctx, &fine_perm)?; + // 解析数据权限范围 + let scope = resolve_data_scope( + &ctx, &manifest_id, &entity, &fine_perm, &state.db, + ).await?; + let result = PluginDataService::timeseries( plugin_id, &entity, @@ -492,6 +509,7 @@ where ¶ms.time_grain, params.start, params.end, + scope, ) .await?;