feat(plugin): timeseries 聚合 API — date_trunc 时间序列

This commit is contained in:
iven
2026-04-17 11:01:43 +08:00
parent c9a58e9d34
commit a333b3673f
5 changed files with 233 additions and 1 deletions

View File

@@ -581,6 +581,52 @@ impl PluginDataService {
// TODO: 未来版本添加 Redis 缓存层
Self::aggregate(plugin_id, entity_name, tenant_id, db, group_by_field, filter).await
}
/// 时间序列聚合 — 按时间字段截断为 day/week/month 统计计数
pub async fn timeseries(
plugin_id: Uuid,
entity_name: &str,
tenant_id: Uuid,
db: &sea_orm::DatabaseConnection,
time_field: &str,
time_grain: &str,
start: Option<String>,
end: Option<String>,
) -> AppResult<Vec<crate::data_dto::TimeseriesItem>> {
let info = resolve_entity_info(plugin_id, entity_name, tenant_id, db).await?;
let (sql, values) = DynamicTableManager::build_timeseries_sql(
&info.table_name,
tenant_id,
time_field,
time_grain,
start.as_deref(),
end.as_deref(),
)
.map_err(|e| AppError::Validation(e))?;
#[derive(FromQueryResult)]
struct TsRow {
period: Option<String>,
count: i64,
}
let rows = TsRow::find_by_statement(Statement::from_sql_and_values(
sea_orm::DatabaseBackend::Postgres,
sql,
values,
))
.all(db)
.await?;
Ok(rows
.into_iter()
.map(|r| crate::data_dto::TimeseriesItem {
period: r.period.unwrap_or_default(),
count: r.count,
})
.collect())
}
}
/// 从 plugins 表解析 manifest metadata.id如 "erp-crm"