调整部分前端布局和后端增删改逻辑
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
from dataclasses import dataclass
|
||||
from importlib import import_module
|
||||
from types import ModuleType
|
||||
|
||||
import typer
|
||||
|
||||
from cli.context import EnvOption
|
||||
from cli.core import DEFAULT_CORE_SERVICES, CliContextFactory, CliExecutionService
|
||||
from cli.exit_codes import DEPENDENCY_ERROR
|
||||
from cli.output import CommandResult
|
||||
from cli.tui.copy import TUI_COPY
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TuiDependencyResultFactory:
|
||||
"""
|
||||
TUI 依赖结果构建器。
|
||||
|
||||
该对象负责统一构建 Textual/Rich 缺失时的降级结果,
|
||||
避免命令注册层继续直接拼接错误负载。
|
||||
"""
|
||||
|
||||
def build_missing_dependency_result(self) -> CommandResult:
|
||||
"""
|
||||
构建 TUI 可选依赖缺失时的提示结果。
|
||||
|
||||
:return: 命令结果对象
|
||||
"""
|
||||
return CommandResult(
|
||||
data={
|
||||
'ok': False,
|
||||
'message': TUI_COPY.build_missing_dependency_message(),
|
||||
'hint': TUI_COPY.build_missing_dependency_hint(),
|
||||
},
|
||||
exit_code=DEPENDENCY_ERROR,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TuiAppModuleLoader:
|
||||
"""
|
||||
TUI 应用模块加载器。
|
||||
|
||||
该对象负责识别缺失的可选依赖,并在命令执行阶段按需导入
|
||||
`cli.tui.app` 模块。
|
||||
"""
|
||||
|
||||
def is_missing_dependency_error(self, exc: ModuleNotFoundError) -> bool:
|
||||
"""
|
||||
判断模块导入异常是否由 TUI 可选依赖缺失触发。
|
||||
|
||||
:param exc: 模块导入异常
|
||||
:return: 是否为 TUI 依赖缺失
|
||||
"""
|
||||
missing_module_name = (exc.name or '').split('.', 1)[0]
|
||||
return missing_module_name in {'textual', 'rich'}
|
||||
|
||||
def load(self) -> ModuleType:
|
||||
"""
|
||||
惰性导入 TUI 应用模块。
|
||||
|
||||
:return: `cli.tui.app` 模块对象
|
||||
"""
|
||||
return import_module('cli.tui.app')
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TuiCommandRegistration:
|
||||
"""
|
||||
TUI 命令注册器。
|
||||
|
||||
:param context_factory: CLI 上下文工厂
|
||||
:param execution_service: CLI 执行服务
|
||||
:param dependency_result_factory: TUI 缺失依赖结果构建器
|
||||
:param module_loader: TUI 应用模块加载器
|
||||
"""
|
||||
|
||||
context_factory: CliContextFactory
|
||||
execution_service: CliExecutionService
|
||||
dependency_result_factory: TuiDependencyResultFactory
|
||||
module_loader: TuiAppModuleLoader
|
||||
|
||||
def handle_tui_command(self, env: str) -> None:
|
||||
"""
|
||||
执行 `shierfeng tui` 命令。
|
||||
|
||||
:param env: 当前命令运行环境
|
||||
:return: None
|
||||
"""
|
||||
ctx = self.context_factory.build_readonly(env, 'text')
|
||||
try:
|
||||
tui_app_module = self.module_loader.load()
|
||||
except ModuleNotFoundError as exc:
|
||||
if self.module_loader.is_missing_dependency_error(exc):
|
||||
self.execution_service.complete_result(
|
||||
ctx,
|
||||
self.dependency_result_factory.build_missing_dependency_result(),
|
||||
)
|
||||
return
|
||||
raise
|
||||
tui_app_module.TUI_APP_RUNNER.run(env)
|
||||
|
||||
def build(self) -> typer.Typer:
|
||||
"""
|
||||
构建 `tui` 子应用。
|
||||
|
||||
:return: `tui` 子应用
|
||||
"""
|
||||
app = typer.Typer(
|
||||
help=TUI_COPY.build_tui_command_help(),
|
||||
no_args_is_help=False,
|
||||
invoke_without_command=True,
|
||||
context_settings={'help_option_names': ['-h', '--help']},
|
||||
)
|
||||
|
||||
@app.callback()
|
||||
def tui(
|
||||
env: EnvOption = 'dev',
|
||||
) -> None:
|
||||
"""
|
||||
进入只读巡检工作台。
|
||||
|
||||
:param env: 当前命令运行环境
|
||||
:return: None
|
||||
"""
|
||||
self.handle_tui_command(env)
|
||||
|
||||
return app
|
||||
|
||||
def register(self, root_cli: typer.Typer) -> None:
|
||||
"""
|
||||
向根 Typer 应用注册 `tui` 命令。
|
||||
|
||||
:param root_cli: 根 Typer 应用
|
||||
:return: None
|
||||
"""
|
||||
root_cli.add_typer(self.build(), name='tui')
|
||||
|
||||
|
||||
TUI_COMMAND_REGISTRATION = TuiCommandRegistration(
|
||||
context_factory=DEFAULT_CORE_SERVICES.context_factory,
|
||||
execution_service=DEFAULT_CORE_SERVICES.execution_service,
|
||||
dependency_result_factory=TuiDependencyResultFactory(),
|
||||
module_loader=TuiAppModuleLoader(),
|
||||
)
|
||||
Reference in New Issue
Block a user