feat: 工作目录支持页面内目录浏览器

This commit is contained in:
2026-10-24 23:20:20 +08:00
parent dd7612bc74
commit e555610037
15 changed files with 1154 additions and 16 deletions
+38 -1
View File
@@ -13,7 +13,10 @@ use utoipa::{OpenApi, ToSchema};
use crate::{
cron::{self, CronPreviewRequest, CronPreviewResponse},
error::{ApiError, ApiJson, ApiResult, ErrorResponse},
directory_browser::{
self, DirectoryEntry, DirectoryError, DirectoryListingResponse, ListDirectoriesQuery,
},
error::{ApiError, ApiJson, ApiQuery, ApiResult, ErrorResponse},
python_env::{
self, InterpreterKind, VenvProbeRequest, VenvProbeResponse, VenvProbeStatus, VenvSource,
},
@@ -129,6 +132,36 @@ pub async fn probe_python_venv(
.map_err(ApiError::internal)
}
#[utoipa::path(
get,
path = "/api/v1/system/directories",
tag = "system",
params(ListDirectoriesQuery),
responses(
(status = 200, description = "Subdirectories of the requested path, or the drive list", body = DirectoryListingResponse),
(status = 400, description = "The path is not an existing absolute directory", body = ErrorResponse)
)
)]
pub async fn list_directories(
ApiQuery(query): ApiQuery<ListDirectoriesQuery>,
) -> ApiResult<Json<DirectoryListingResponse>> {
tokio::task::spawn_blocking(move || directory_browser::list_directories(&query))
.await
.map_err(ApiError::internal)?
.map(Json)
.map_err(|error| match error {
DirectoryError::RelativePath(message) => {
ApiError::bad_request("DIRECTORY_PATH_INVALID", message)
}
DirectoryError::NotFound(message) => {
ApiError::bad_request("DIRECTORY_NOT_FOUND", message)
}
DirectoryError::Unreadable(message) => {
ApiError::bad_request("DIRECTORY_UNREADABLE", message)
}
})
}
#[derive(OpenApi)]
#[openapi(
info(
@@ -141,6 +174,7 @@ pub async fn probe_python_venv(
session,
preview_cron,
probe_python_venv,
list_directories,
list_tasks,
create_task,
get_task,
@@ -166,6 +200,8 @@ pub async fn probe_python_venv(
VenvProbeStatus,
VenvSource,
InterpreterKind,
DirectoryEntry,
DirectoryListingResponse,
ErrorResponse,
TaskActionType,
HttpMethod,
@@ -215,6 +251,7 @@ pub fn router(state: AppState) -> Router {
"/api/v1/python/venv",
axum::routing::post(probe_python_venv),
)
.route("/api/v1/system/directories", get(list_directories))
.route("/api/v1/openapi.json", get(openapi_json))
.merge(crate::tasks::routes::router())
.merge(crate::runs::routes::router())