50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
"""在大屏 JSON 副本上移动组件,用于后端校验动作能否执行"""
|
|
|
|
from app.actions.base import BaseActionHandler
|
|
from app.schemas.actions import MoveAction
|
|
from app.schemas.screen import Layout, Screen
|
|
|
|
|
|
class MoveHandler(BaseActionHandler[MoveAction]):
|
|
def apply(self, screen: Screen, action: MoveAction) -> Screen:
|
|
# 确认移动目标存在,并取得大屏副本及副本中的目标节点
|
|
result, target = self.copy_target(screen, action.target_id)
|
|
|
|
# 将现有布局转成字典,保留尺寸和其他布局字段
|
|
layout = target.layout.model_dump()
|
|
|
|
# 在原坐标上叠加相对位移,不将 delta_x 和 delta_y 当作绝对坐标
|
|
layout["x"] += action.delta_x
|
|
layout["y"] += action.delta_y
|
|
|
|
# 重新校验计算结果,防止浮点溢出产生无效坐标
|
|
target.layout = Layout.model_validate(layout)
|
|
|
|
# 返回移动后的大屏副本,供下一条动作继续使用
|
|
return result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
screen = Screen.model_validate(
|
|
{
|
|
"canvas": {"width": 1920, "height": 1080},
|
|
"nodes": [
|
|
{
|
|
"id": "sales-chart",
|
|
"type": "chart",
|
|
"layout": {"x": 100, "y": 200, "width": 400, "height": 300},
|
|
}
|
|
],
|
|
}
|
|
)
|
|
action = MoveAction(target_id="sales-chart", delta_x=50)
|
|
handler = MoveHandler()
|
|
final_screen = handler.apply(screen, action)
|
|
print(final_screen.model_dump_json(indent=2))
|
|
print("原始坐标:", screen.nodes[0].layout.x, screen.nodes[0].layout.y)
|
|
|
|
try:
|
|
handler.apply(screen, MoveAction(target_id="missing", delta_x=50))
|
|
except ValueError as error:
|
|
print("无效目标:", error)
|