ShiErFeng/shierfeng-fastapi-backend/cli/tui/actions/registry.py
2026-07-24 09:43:10 +08:00

104 lines
2.9 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from cli.tui.actions.builders import TuiActionSpecFactory, TuiActionTemplate
from cli.tui.actions.models import ActionSlot, TuiActionSpec
from cli.tui.adapters.models import BrowserRecordSnapshot
@dataclass(frozen=True)
class TuiActionRegistry:
"""
TUI 动作注册表。
该注册表负责集中维护浏览页和详情页的动作解析器,从而将
原本散落的条件分发收敛为可声明的映射关系。
:param browser_resolvers: 浏览页动作槽位解析器映射
:param detail_resolvers: 详情页动作槽位解析器映射
"""
browser_resolvers: dict[str, TuiActionSlotResolver]
detail_resolvers: dict[str, TuiActionSlotResolver]
def resolve_browser_action(
self,
*,
view_key: str,
slot: ActionSlot,
record: BrowserRecordSnapshot | None,
env: str,
) -> TuiActionSpec | None:
"""
解析浏览页动作。
:param view_key: 当前页面视图标识
:param slot: 动作槽位
:param record: 当前选中记录
:param env: 当前运行环境
:return: 动作定义
"""
resolver = self.browser_resolvers.get(view_key)
if resolver is None:
return None
return resolver.resolve(slot=slot, record=record, env=env)
def resolve_detail_action(
self,
*,
view_key: str,
slot: ActionSlot,
env: str,
) -> TuiActionSpec | None:
"""
解析详情页动作。
:param view_key: 当前页面视图标识
:param slot: 动作槽位
:param env: 当前运行环境
:return: 动作定义
"""
resolver = self.detail_resolvers.get(view_key)
if resolver is None:
return None
return resolver.resolve(slot=slot, record=None, env=env)
@dataclass(frozen=True)
class TuiActionSlotResolver:
"""
TUI 动作槽位解析器。
该对象将一个页面支持的槽位动作集中定义为映射关系,避免继续在
`resolve_*_action` 中堆叠条件分支。
:param slot_templates: 槽位到动作模板的映射
:param spec_factory: 动作规格构建器
"""
slot_templates: dict[ActionSlot, TuiActionTemplate]
spec_factory: TuiActionSpecFactory
def resolve(
self,
*,
slot: ActionSlot,
record: BrowserRecordSnapshot | None,
env: str,
) -> TuiActionSpec | None:
"""
解析指定槽位的动作定义。
:param slot: 动作槽位
:param record: 当前选中记录
:param env: 当前运行环境
:return: 动作定义
"""
template = self.slot_templates.get(slot)
if template is None:
return None
return template.build(record=record, env=env, spec_factory=self.spec_factory)