use crate::{ admin::AuthenticatedAdmin, api_response::json_success_body, http_error::AppError, request_context::RequestContext, state::AppState, }; use axum::{ Json, extract::{Extension, State}, http::StatusCode, }; use module_runtime::AgcModelCatalog; use shared_contracts::admin::{AdminAgcModel, AdminAgcModelCatalog}; pub(crate) async fn load_catalog(state: &AppState) -> Result { let json = state .spacetime_client() .read_agc_model_catalog() .await .map_err(|_| { AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("模型目录暂不可用") })?; let catalog: AgcModelCatalog = serde_json::from_str(&json).map_err(|_| { AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("模型目录格式无效") })?; catalog.validate().map_err(|message| { AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message(message) })?; Ok(catalog) } pub async fn admin_get_agc_models( State(state): State, Extension(context): Extension, Extension(_admin): Extension, ) -> Result, AppError> { Ok(json_success_body( Some(&context), catalog_dto(load_catalog(&state).await?), )) } pub async fn admin_save_agc_models( State(state): State, Extension(context): Extension, Extension(_admin): Extension, Json(payload): Json, ) -> Result, AppError> { let catalog = AgcModelCatalog { revision: payload.revision, default_model_id: payload.default_model_id, models: payload .models .into_iter() .map(|m| module_runtime::AgcModel { id: m.id, alias: m.alias, model_id: m.model_id, enabled: m.enabled, }) .collect(), }; catalog .validate() .map_err(|message| AppError::from_status(StatusCode::BAD_REQUEST).with_message(message))?; let payload = serde_json::to_string(&catalog) .map_err(|_| AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR))?; let saved = state .spacetime_client() .save_agc_model_catalog(payload) .await .map_err(|error| { if matches!(error, spacetime_client::SpacetimeClientError::Procedure(ref message) if message == module_runtime::AGC_MODEL_CATALOG_CONFLICT) { AppError::from_status(StatusCode::CONFLICT).with_message("模型目录已被更新,请重新读取") } else { AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("保存模型目录失败,请稍后重试") } })?; let catalog: AgcModelCatalog = serde_json::from_str(&saved) .map_err(|_| AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR))?; Ok(json_success_body(Some(&context), catalog_dto(catalog))) } fn catalog_dto(catalog: AgcModelCatalog) -> AdminAgcModelCatalog { AdminAgcModelCatalog { revision: catalog.revision, default_model_id: catalog.default_model_id, models: catalog .models .into_iter() .map(|m| AdminAgcModel { id: m.id, alias: m.alias, model_id: m.model_id, enabled: m.enabled, }) .collect(), } }