use axum::extract::{Extension, Query, State}; use axum::extract::FromRef; use axum::Json; use serde::Deserialize; use erp_core::error::AppError; use erp_core::rbac::require_permission; use erp_core::types::{ApiResponse, PaginatedResponse, TenantContext}; use validator::Validate; use crate::dto::{CreateTemplateReq, MessageTemplateResp}; use crate::message_state::MessageState; use crate::service::template_service::TemplateService; #[derive(Debug, Deserialize)] pub struct TemplateQuery { pub page: Option, pub page_size: Option, } /// 查询消息模板列表。 pub async fn list_templates( State(_state): State, Extension(ctx): Extension, Query(query): Query, ) -> Result>>, AppError> where MessageState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "message:template:list")?; let page = query.page.unwrap_or(1); let page_size = query.page_size.unwrap_or(20); let (templates, total) = TemplateService::list(ctx.tenant_id, page, page_size, &_state.db).await?; let total_pages = (total + page_size - 1) / page_size; Ok(Json(ApiResponse::ok(PaginatedResponse { data: templates, total, page, page_size, total_pages, }))) } /// 创建消息模板。 pub async fn create_template( State(_state): State, Extension(ctx): Extension, Json(req): Json, ) -> Result>, AppError> where MessageState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "message:template:create")?; req.validate() .map_err(|e| AppError::Validation(e.to_string()))?; let resp = TemplateService::create(ctx.tenant_id, ctx.user_id, &req, &_state.db).await?; Ok(Json(ApiResponse::ok(resp))) }