feat(health): 5 个工作台管理统计 API — 系统健康/用户活跃/模块状态/积分动态/文章统计

- DTO: SystemHealthResp, UserActivityResp, ModuleStatusResp, PointsActivityItem, ArticleStatsResp
- Service: get_article_stats, get_points_recent_activity, get_module_status, get_user_activity, get_system_health
- Handler: 5 个新端点 + 权限码 health.dashboard.manage
- 路由: /health/admin/system-health, user-activity, modules, points/recent-activity, articles/stats
This commit is contained in:
iven
2026-05-02 11:49:34 +08:00
parent 2cc0f5af25
commit 0006e427e2
4 changed files with 487 additions and 1 deletions

View File

@@ -138,3 +138,71 @@ where
let result = stats_service::get_personal_stats(&state, ctx.user_id, ctx.tenant_id).await?;
Ok(Json(ApiResponse::ok(result)))
}
// ---------------------------------------------------------------------------
// 工作台管理统计
// ---------------------------------------------------------------------------
pub async fn get_system_health<S>(
State(state): State<HealthState>,
Extension(_ctx): Extension<TenantContext>,
) -> Result<Json<ApiResponse<SystemHealthResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
let result = stats_service::get_system_health(&state).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn get_user_activity<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
) -> Result<Json<ApiResponse<UserActivityResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.dashboard.manage")?;
let result = stats_service::get_user_activity(&state.db, ctx.tenant_id).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn get_module_status<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
) -> Result<Json<ApiResponse<Vec<ModuleStatusResp>>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.dashboard.manage")?;
let result = stats_service::get_module_status(&state).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn get_points_recent_activity<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
) -> Result<Json<ApiResponse<Vec<PointsActivityItem>>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.dashboard.manage")?;
let result = stats_service::get_points_recent_activity(&state.db, ctx.tenant_id, 10).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn get_article_stats<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
) -> Result<Json<ApiResponse<ArticleStatsResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.dashboard.manage")?;
let result = stats_service::get_article_stats(&state.db, ctx.tenant_id).await?;
Ok(Json(ApiResponse::ok(result)))
}