小优化-立项配置-预览模式下“更新”显示

This commit is contained in:
Cheng Zhou
2026-02-28 16:41:20 +08:00
parent 9b36a42e6f
commit 6c5e5770c6
2 changed files with 697 additions and 89 deletions
+34 -19
View File
@@ -1,4 +1,5 @@
import uuid
from copy import deepcopy
from datetime import datetime
from sqlalchemy import delete as sa_delete, select
@@ -13,7 +14,7 @@ from app.schemas.study_setup_config import StudySetupConfigData
def _to_storage(data: StudySetupConfigData | dict) -> dict:
if isinstance(data, StudySetupConfigData):
return data.model_dump(mode="json")
return data
return deepcopy(data)
async def get_by_study(db: AsyncSession, study_id: uuid.UUID) -> StudySetupConfig | None:
@@ -76,31 +77,45 @@ async def publish(
return None, False
if expected_version is not None and expected_version != existing.version:
return None, True
publish_payload = _to_storage(existing.config or {})
next_version = existing.version + 1
next_display_version_stmt = select(func.max(StudySetupConfigVersion.display_version)).where(
StudySetupConfigVersion.study_id == study_id
latest_snapshot_stmt = (
select(StudySetupConfigVersion)
.where(StudySetupConfigVersion.study_id == study_id)
.order_by(StudySetupConfigVersion.version.desc(), StudySetupConfigVersion.published_at.desc())
.limit(1)
)
display_version_result = await db.execute(next_display_version_stmt)
current_max_display_version = display_version_result.scalar_one_or_none() or 0
next_display_version = current_max_display_version + 1
latest_snapshot_result = await db.execute(latest_snapshot_stmt)
latest_snapshot = latest_snapshot_result.scalar_one_or_none()
should_create_snapshot = not latest_snapshot or (latest_snapshot.config or {}) != publish_payload
existing.version = next_version
existing.publish_status = "PUBLISHED"
existing.published_config = existing.config
existing.published_config = _to_storage(publish_payload)
existing.published_by = published_by
existing.published_at = datetime.utcnow()
existing.saved_by = published_by
existing.updated_at = datetime.utcnow()
snapshot = StudySetupConfigVersion(
study_setup_config_id=existing.id,
study_id=study_id,
version=next_version,
display_version=next_display_version,
source_version=next_version - 1,
config=existing.config,
published_by=published_by,
published_at=existing.published_at,
)
db.add(snapshot)
if should_create_snapshot:
next_display_version_stmt = select(func.max(StudySetupConfigVersion.display_version)).where(
StudySetupConfigVersion.study_id == study_id
)
display_version_result = await db.execute(next_display_version_stmt)
current_max_display_version = display_version_result.scalar_one_or_none() or 0
next_display_version = current_max_display_version + 1
snapshot = StudySetupConfigVersion(
study_setup_config_id=existing.id,
study_id=study_id,
version=next_version,
display_version=next_display_version,
source_version=next_version - 1,
config=_to_storage(publish_payload),
published_by=published_by,
published_at=existing.published_at,
)
db.add(snapshot)
if auto_commit:
await db.commit()
await db.refresh(existing)
@@ -143,7 +158,7 @@ async def rollback_to_version(
return None, False, True
existing.version = existing.version + 1
existing.config = target.config
existing.config = _to_storage(target.config or {})
existing.saved_by = saved_by
existing.publish_status = "DRAFT"
existing.updated_at = datetime.utcnow()