feat: ship end-to-end interior design MVP
This commit is contained in:
@@ -2,8 +2,11 @@ from copy import deepcopy
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from app.domain.models import (
|
||||
CameraView,
|
||||
CommandRequest,
|
||||
DesignBrief,
|
||||
ProjectSnapshot,
|
||||
RoomProfile,
|
||||
WorkflowCommand,
|
||||
WorkflowDefinition,
|
||||
WorkflowStage,
|
||||
@@ -91,13 +94,51 @@ def apply_command(project: ProjectSnapshot, request: CommandRequest) -> ProjectS
|
||||
updated.plan.ceiling_height_mm = int(
|
||||
request.payload.get("ceiling_height_mm", updated.plan.ceiling_height_mm)
|
||||
)
|
||||
if request.payload.get("gross_area_sqm") is not None:
|
||||
updated.plan.gross_area_sqm = float(request.payload["gross_area_sqm"])
|
||||
if request.payload.get("room_names"):
|
||||
existing = {room.name: room for room in updated.plan.structure.rooms}
|
||||
updated.plan.structure.rooms = [
|
||||
existing.get(name)
|
||||
or RoomProfile(
|
||||
id=f"room-{index + 1}",
|
||||
name=name,
|
||||
kind="other",
|
||||
confidence=1,
|
||||
notes="用户确认",
|
||||
)
|
||||
for index, raw_name in enumerate(request.payload["room_names"])
|
||||
if (name := str(raw_name).strip())
|
||||
]
|
||||
for issue in updated.plan.issues:
|
||||
if issue.kind in {"scale", "ocr"}:
|
||||
issue.resolved = True
|
||||
elif request.command == WorkflowCommand.BUILD_BLOCKOUT:
|
||||
room_names = [room.name for room in updated.plan.structure.rooms]
|
||||
focus = room_names[:3] or ["客餐厅", "主卧", "入口"]
|
||||
updated.scene.cameras = [
|
||||
CameraView(id=f"camera-{index + 1}", label=f"{room}主视角", room=room)
|
||||
for index, room in enumerate(focus)
|
||||
]
|
||||
elif request.command == WorkflowCommand.SUBMIT_STYLE_BRIEF:
|
||||
updated.brief = DesignBrief.model_validate({**updated.brief.model_dump(), **request.payload, "completed": True})
|
||||
for field in ("concept", "lighting", "forms", "density"):
|
||||
if field in request.payload:
|
||||
setattr(updated.style, field, request.payload[field])
|
||||
for field in ("keywords", "materials", "avoid", "locked_decisions"):
|
||||
if field in request.payload:
|
||||
setattr(updated.style, field, list(request.payload[field]))
|
||||
elif request.command == WorkflowCommand.SELECT_DIRECTION:
|
||||
direction_id = str(request.payload.get("direction_id", ""))
|
||||
direction = next((item for item in updated.directions if item.id == direction_id), None)
|
||||
if direction is None:
|
||||
raise InvalidTransitionError(f"Direction '{direction_id}' does not exist in this project.")
|
||||
updated.style.selected_direction_id = direction_id
|
||||
updated.style.concept = direction.thesis
|
||||
updated.style.keywords = direction.keywords
|
||||
updated.style.palette = direction.palette
|
||||
updated.style.materials = direction.materials
|
||||
updated.style.lighting = direction.lighting
|
||||
|
||||
updated.available_commands = available_commands(updated.stage)
|
||||
return updated
|
||||
|
||||
Reference in New Issue
Block a user