39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
"""修改范围及后续能力需求,由需求按规则推导,不调用模型"""
|
|
|
|
from typing import Literal, Self
|
|
|
|
from pydantic import Field
|
|
|
|
from app.schemas.base import ExtensibleModel, NonBlankString
|
|
from app.schemas.operations import is_screen_wide, requires_planning
|
|
from app.schemas.requirement import Requirement
|
|
|
|
|
|
class ChangeScope(ExtensibleModel):
|
|
scope: Literal["local", "screen"] = Field(
|
|
description="local=只能改动 target_ids 中的已有组件;screen=整体调整,可涉及任意已有组件"
|
|
)
|
|
target_ids: list[NonBlankString] = Field(
|
|
default_factory=list, description="需求明确指定的已有组件 ID,新增内容和画布属性可为空"
|
|
)
|
|
needs_planning: bool = Field(description="是否需要布局、组件组合或设计规划")
|
|
|
|
@classmethod
|
|
def from_requirement(cls, requirement: Requirement) -> Self:
|
|
"""范围和是否规划都由需求变更决定,规则集中在 operations"""
|
|
changes = requirement.changes
|
|
return cls(
|
|
scope=(
|
|
"screen"
|
|
if any(is_screen_wide(c.target_scope, c.operation) for c in changes)
|
|
else "local"
|
|
),
|
|
# 保持需求中的出现顺序并去重
|
|
target_ids=list(
|
|
dict.fromkeys(node_id for c in changes for node_id in c.target_ids)
|
|
),
|
|
# 新建大屏总是先规划;修改大屏时按操作能力判断
|
|
needs_planning=requirement.intent == "create_screen"
|
|
or any(requires_planning(c.target_scope, c.operation) for c in changes),
|
|
)
|