立项配置数据入库、审计日志数据入库、编辑页UI界面美化、设备管理内容补充、审计日志显示优化

This commit is contained in:
Cheng Zhou
2026-02-27 16:16:26 +08:00
parent fd7e3fc948
commit db2d38edbc
48 changed files with 2936 additions and 909 deletions
+7
View File
@@ -14,3 +14,10 @@ class AuditLogRead(BaseModel):
created_at: datetime
model_config = ConfigDict(from_attributes=True)
class AuditEventCreate(BaseModel):
action: str
detail: Optional[str] = None
entity_type: Optional[str] = None
entity_id: Optional[uuid.UUID] = None
+81
View File
@@ -0,0 +1,81 @@
import uuid
from datetime import datetime
from pydantic import BaseModel, ConfigDict, field_validator
class MaterialEquipmentCreate(BaseModel):
name: str
spec_model: str
unit: str | None = None
brand: str
origin: str | None = None
production_permit_file_name: str | None = None
tech_index_file_name: str | None = None
need_calibration: bool
calibration_cycle_days: int | None = None
@field_validator("name", "spec_model", "brand", mode="before")
@classmethod
def _strip_required(cls, value: str) -> str:
text = (value or "").strip()
if not text:
raise ValueError("不能为空")
return text
@field_validator("unit", "origin", "production_permit_file_name", "tech_index_file_name", mode="before")
@classmethod
def _strip_optional(cls, value: str | None) -> str | None:
if value is None:
return None
text = value.strip()
return text or None
class MaterialEquipmentUpdate(BaseModel):
name: str | None = None
spec_model: str | None = None
unit: str | None = None
brand: str | None = None
origin: str | None = None
production_permit_file_name: str | None = None
tech_index_file_name: str | None = None
need_calibration: bool | None = None
calibration_cycle_days: int | None = None
@field_validator("name", "spec_model", "brand", mode="before")
@classmethod
def _strip_required(cls, value: str | None) -> str | None:
if value is None:
return None
text = value.strip()
if not text:
raise ValueError("不能为空")
return text
@field_validator("unit", "origin", "production_permit_file_name", "tech_index_file_name", mode="before")
@classmethod
def _strip_optional(cls, value: str | None) -> str | None:
if value is None:
return None
text = value.strip()
return text or None
class MaterialEquipmentRead(BaseModel):
id: uuid.UUID
study_id: uuid.UUID
name: str
spec_model: str
unit: str | None
brand: str
origin: str | None
production_permit_file_name: str | None
tech_index_file_name: str | None
need_calibration: bool
calibration_cycle_days: int | None
created_by: uuid.UUID | None
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
+29
View File
@@ -0,0 +1,29 @@
import uuid
from datetime import date, datetime
from pydantic import BaseModel, ConfigDict
class ProjectMilestoneRead(BaseModel):
id: uuid.UUID
study_id: uuid.UUID
name: str
planned_date: date | None
adjusted_start_date: date | None
adjusted_end_date: date | None
actual_start_date: date | None
actual_end_date: date | None
status: str
notes: str | None
owner_name: str | None
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class ProjectMilestoneUpdate(BaseModel):
adjusted_start_date: date | None = None
adjusted_end_date: date | None = None
actual_start_date: date | None = None
actual_end_date: date | None = None
notes: str | None = None
+30
View File
@@ -80,6 +80,7 @@ class StudySetupConfigData(BaseModel):
class StudySetupConfigUpsert(BaseModel):
expected_version: int | None = None
data: StudySetupConfigData
force_draft: bool = False
class StudySetupConfigPublish(BaseModel):
@@ -120,6 +121,34 @@ class SetupProjectionSummary(BaseModel):
skipped_items: list[SetupProjectionSkippedItem] = Field(default_factory=list)
class ProjectPublishSnapshot(BaseModel):
code: str = ""
name: str = ""
project_full_name: str = ""
sponsor: str = ""
protocol_no: str = ""
lead_unit: str = ""
principal_investigator: str = ""
main_pm: str = ""
research_analysis: str = ""
research_product: str = ""
control_product: str = ""
indication: str = ""
research_population: str = ""
research_design: str = ""
plan_start_date: str = ""
plan_end_date: str = ""
planned_site_count: int | None = None
planned_enrollment_count: int | None = None
summary_note: str = ""
objective_note: str = ""
status: str = ""
visit_interval_days: int | None = None
visit_total: int | None = None
visit_window_start_offset: int | None = None
visit_window_end_offset: int | None = None
class StudySetupConfigRead(BaseModel):
id: uuid.UUID
study_id: uuid.UUID
@@ -127,6 +156,7 @@ class StudySetupConfigRead(BaseModel):
data: StudySetupConfigData
publish_status: str
published_data: StudySetupConfigData | None = None
published_project_snapshot: ProjectPublishSnapshot | None = None
published_by: uuid.UUID | None = None
published_by_name: str | None = None
published_at: datetime | None = None