From 3fb4d5f170ba3ba187c23f8bacb3f37130c72d35 Mon Sep 17 00:00:00 2001 From: chengkai3 Date: Sun, 21 Jun 2026 13:15:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:[FL-172][=E9=AB=98=E7=A8=8B=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=8F=90=E4=BA=A4=E8=A1=A8=E5=8D=95=E6=8A=A5?= =?UTF-8?q?=E9=94=99]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复高程文件上传接口的422错误。 问题原因: ElevationFileRecordCreateRequest schema 的 mount_code 字段设置了 min_length=2 约束, 当前端传递空字符串时,Pydantic 验证失败导致 422 Unprocessable Entity 错误。 解决方案: 1. 添加 field_validator,将空字符串转换为 None 2. 应用到以下 Request schemas 的可选字符串字段: - ElevationFileRecordCreateRequest: source, mount_code, notes - ElevationFileRecordUpdateRequest: source, notes - ElevationDatasetCreateRequest: source, mount_code, file_name, notes - ElevationDatasetUpdateRequest: name, source, notes 这样可以确保: - 空字符串被规范化为 None - 保持向后兼容性 - 后端逻辑可以正确使用默认 mount_code(第一个可用挂载点) Co-authored-by: multica-agent --- api/app/schemas/elevation.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/api/app/schemas/elevation.py b/api/app/schemas/elevation.py index 66aadbc..8638fb8 100644 --- a/api/app/schemas/elevation.py +++ b/api/app/schemas/elevation.py @@ -3,7 +3,7 @@ from __future__ import annotations from datetime import datetime from typing import Any, Literal -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, field_validator ElevationDatasetStatus = Literal["active", "disabled"] @@ -62,6 +62,13 @@ class ElevationFileRecordCreateRequest(BaseModel): notes: str | None = Field(default=None, max_length=2000) trigger_analysis: bool = Field(default=True) + @field_validator("source", "mount_code", "notes", mode="before") + @classmethod + def empty_str_to_none(cls, v: Any) -> Any: + if isinstance(v, str) and v.strip() == "": + return None + return v + class ElevationFileRecordUpdateRequest(BaseModel): source: str | None = Field(default=None, max_length=512) @@ -69,6 +76,13 @@ class ElevationFileRecordUpdateRequest(BaseModel): status: ElevationDatasetStatus | None = None notes: str | None = Field(default=None, max_length=2000) + @field_validator("source", "notes", mode="before") + @classmethod + def empty_str_to_none(cls, v: Any) -> Any: + if isinstance(v, str) and v.strip() == "": + return None + return v + class ElevationFileRecordAnalyzeResponse(BaseModel): record: ElevationFileRecordSummary @@ -165,6 +179,13 @@ class ElevationDatasetCreateRequest(BaseModel): resolution_m: float | None = Field(default=None, gt=0) notes: str | None = Field(default=None, max_length=2000) + @field_validator("source", "mount_code", "file_name", "notes", mode="before") + @classmethod + def empty_str_to_none(cls, v: Any) -> Any: + if isinstance(v, str) and v.strip() == "": + return None + return v + class ElevationDatasetUpdateRequest(BaseModel): name: str | None = Field(default=None, min_length=2, max_length=255) @@ -173,6 +194,13 @@ class ElevationDatasetUpdateRequest(BaseModel): status: ElevationDatasetStatus | None = None notes: str | None = Field(default=None, max_length=2000) + @field_validator("name", "source", "notes", mode="before") + @classmethod + def empty_str_to_none(cls, v: Any) -> Any: + if isinstance(v, str) and v.strip() == "": + return None + return v + class ElevationDatasetAnalyzeResponse(BaseModel): dataset: ElevationDatasetSummary