From 5b2ae16ffb514ba92d878fa97fe72ee9420fa5da Mon Sep 17 00:00:00 2001 From: iven Date: Fri, 17 Apr 2026 10:55:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20API=20=E5=B1=82=E6=89=A9=E5=B1=95?= =?UTF-8?q?=20=E2=80=94=20batch/patch/timeseries/kanban=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PluginFieldSchema 新增 ref_entity/ref_label_field/ref_search_fields/cascade_from/cascade_filter - PluginPageSchema 新增 kanban 页面类型(lane_field/card_title_field 等) - PluginPageSchema dashboard 类型扩展 widgets 字段 - 新增 DashboardWidget 接口(stat_card/bar/pie/funnel/line 图表) - pluginData 新增 batchPluginData/patchPluginData/getPluginTimeseries 三个 API 函数 --- apps/web/src/api/pluginData.ts | 48 ++++++++++++++++++++++++++++++++++ apps/web/src/api/plugins.ts | 30 ++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/apps/web/src/api/pluginData.ts b/apps/web/src/api/pluginData.ts index bc85bc6..e39a079 100644 --- a/apps/web/src/api/pluginData.ts +++ b/apps/web/src/api/pluginData.ts @@ -123,3 +123,51 @@ export async function aggregatePluginData( ); return data.data; } + +// ── 批量操作 ── + +export async function batchPluginData( + pluginId: string, + entity: string, + req: { action: string; ids: string[]; data?: Record }, +) { + const { data } = await client.post<{ success: boolean; data: unknown }>( + `/plugins/${pluginId}/${entity}/batch`, + req, + ); + return data.data; +} + +// ── 部分更新 ── + +export async function patchPluginData( + pluginId: string, + entity: string, + id: string, + req: { data: Record; version: number }, +) { + const { data } = await client.patch<{ success: boolean; data: PluginDataRecord }>( + `/plugins/${pluginId}/${entity}/${id}`, + req, + ); + return data.data; +} + +// ── 时间序列 ── + +export async function getPluginTimeseries( + pluginId: string, + entity: string, + params: { + time_field: string; + time_grain: string; + start?: string; + end?: string; + }, +) { + const { data } = await client.get<{ success: boolean; data: unknown }>( + `/plugins/${pluginId}/${entity}/timeseries`, + { params }, + ); + return data.data; +} diff --git a/apps/web/src/api/plugins.ts b/apps/web/src/api/plugins.ts index 3386f41..7a23e2f 100644 --- a/apps/web/src/api/plugins.ts +++ b/apps/web/src/api/plugins.ts @@ -134,6 +134,11 @@ export interface PluginFieldSchema { sortable?: boolean; visible_when?: string; unique?: boolean; + ref_entity?: string; + ref_label_field?: string; + ref_search_fields?: string[]; + cascade_from?: string; + cascade_filter?: string; } export interface PluginEntitySchema { @@ -157,7 +162,30 @@ export type PluginPageSchema = | { type: 'detail'; entity: string; label: string; sections: PluginSectionSchema[] } | { type: 'tabs'; label: string; icon?: string; tabs: PluginPageSchema[] } | { type: 'graph'; entity: string; label: string; relationship_entity: string; source_field: string; target_field: string; edge_label_field: string; node_label_field: string } - | { type: 'dashboard'; label: string }; + | { type: 'dashboard'; label: string; widgets?: DashboardWidget[] } + | { + type: 'kanban'; + entity: string; + label: string; + icon?: string; + lane_field: string; + lane_order?: string[]; + card_title_field: string; + card_subtitle_field?: string; + card_fields?: string[]; + enable_drag?: boolean; + }; + +export interface DashboardWidget { + type: 'stat_card' | 'bar_chart' | 'pie_chart' | 'funnel_chart' | 'line_chart'; + entity: string; + title: string; + icon?: string; + color?: string; + dimension_field?: string; + dimension_order?: string[]; + metric?: string; +} export type PluginSectionSchema = | { type: 'fields'; label: string; fields: string[] }