补充监查访视问题模块内容、翻页功能UI统一
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
import uuid
|
||||
from datetime import date, datetime, timezone
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, field_validator
|
||||
|
||||
|
||||
class MonitoringVisitIssueCreate(BaseModel):
|
||||
issue_no: str | None = None
|
||||
category: str
|
||||
subject_code: str | None = None
|
||||
monitor_item: str | None = None
|
||||
monitor_type: str | None = None
|
||||
status: str = "OPEN"
|
||||
source: str | None = None
|
||||
creator_name: str | None = None
|
||||
recommendation: str | None = None
|
||||
subject_name: str | None = None
|
||||
description: str | None = None
|
||||
action_taken: str | None = None
|
||||
follow_up_progress: str | None = None
|
||||
found_date: date | None = None
|
||||
due_at: datetime | None = None
|
||||
actual_resolve_date: date | None = None
|
||||
closed_at: datetime | None = None
|
||||
responsible_name: str | None = None
|
||||
|
||||
@field_validator("category", mode="before")
|
||||
@classmethod
|
||||
def _strip_required(cls, value: str) -> str:
|
||||
text = (value or "").strip()
|
||||
if not text:
|
||||
raise ValueError("不能为空")
|
||||
return text
|
||||
|
||||
@field_validator("issue_no", mode="before")
|
||||
@classmethod
|
||||
def _strip_issue_no(cls, value: str | None) -> str | None:
|
||||
if value is None:
|
||||
return None
|
||||
text = value.strip()
|
||||
return text or None
|
||||
|
||||
@field_validator(
|
||||
"subject_code",
|
||||
"monitor_item",
|
||||
"monitor_type",
|
||||
"source",
|
||||
"creator_name",
|
||||
"recommendation",
|
||||
"subject_name",
|
||||
"description",
|
||||
"action_taken",
|
||||
"follow_up_progress",
|
||||
"responsible_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
|
||||
|
||||
@field_validator("status", mode="before")
|
||||
@classmethod
|
||||
def _normalize_status(cls, value: str | None) -> str:
|
||||
normalized = (value or "OPEN").strip().upper()
|
||||
if normalized not in {"OPEN", "CLOSED"}:
|
||||
raise ValueError("状态必须为 OPEN 或 CLOSED")
|
||||
return normalized
|
||||
|
||||
@field_validator("due_at", "closed_at")
|
||||
@classmethod
|
||||
def _normalize_due_at(cls, value: datetime | None) -> datetime | None:
|
||||
if value is None:
|
||||
return None
|
||||
return value if value.tzinfo else value.replace(tzinfo=timezone.utc)
|
||||
|
||||
|
||||
class MonitoringVisitIssueRead(BaseModel):
|
||||
id: uuid.UUID
|
||||
study_id: uuid.UUID
|
||||
issue_no: str
|
||||
open_duration: str
|
||||
category: str
|
||||
subject_code: str | None
|
||||
monitor_item: str | None
|
||||
monitor_type: str | None
|
||||
progress: str
|
||||
status: str
|
||||
source: str | None
|
||||
creator_name: str | None
|
||||
recommendation: str | None
|
||||
subject_name: str | None
|
||||
created_at: datetime
|
||||
description: str | None
|
||||
action_taken: str | None
|
||||
follow_up_progress: str | None
|
||||
found_date: date | None
|
||||
overdue: bool
|
||||
due_at: datetime | None
|
||||
actual_resolve_date: date | None
|
||||
closed_at: datetime | None
|
||||
responsible_name: str | None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class MonitoringVisitIssueImportSummary(BaseModel):
|
||||
created_count: int
|
||||
updated_count: int
|
||||
skipped_count: int
|
||||
skipped_rows: list[str]
|
||||
|
||||
|
||||
class MonitoringVisitIssueUpdate(BaseModel):
|
||||
issue_no: str | None = None
|
||||
category: str | None = None
|
||||
subject_code: str | None = None
|
||||
monitor_item: str | None = None
|
||||
monitor_type: str | None = None
|
||||
status: str | None = None
|
||||
source: str | None = None
|
||||
creator_name: str | None = None
|
||||
recommendation: str | None = None
|
||||
subject_name: str | None = None
|
||||
description: str | None = None
|
||||
action_taken: str | None = None
|
||||
follow_up_progress: str | None = None
|
||||
found_date: date | None = None
|
||||
due_at: datetime | None = None
|
||||
actual_resolve_date: date | None = None
|
||||
closed_at: datetime | None = None
|
||||
responsible_name: str | None = None
|
||||
|
||||
@field_validator("issue_no", "category", 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(
|
||||
"subject_code",
|
||||
"monitor_item",
|
||||
"monitor_type",
|
||||
"source",
|
||||
"creator_name",
|
||||
"recommendation",
|
||||
"subject_name",
|
||||
"description",
|
||||
"action_taken",
|
||||
"follow_up_progress",
|
||||
"responsible_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
|
||||
|
||||
@field_validator("status", mode="before")
|
||||
@classmethod
|
||||
def _normalize_status(cls, value: str | None) -> str | None:
|
||||
if value is None:
|
||||
return None
|
||||
normalized = value.strip().upper()
|
||||
if normalized not in {"OPEN", "CLOSED"}:
|
||||
raise ValueError("状态必须为 OPEN 或 CLOSED")
|
||||
return normalized
|
||||
|
||||
@field_validator("due_at", "closed_at")
|
||||
@classmethod
|
||||
def _normalize_due_at(cls, value: datetime | None) -> datetime | None:
|
||||
if value is None:
|
||||
return None
|
||||
return value if value.tzinfo else value.replace(tzinfo=timezone.utc)
|
||||
Reference in New Issue
Block a user