初始提交
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from cli.tui.copy import TUI_COPY
|
||||
from cli.tui.search import PageFilterOption, PageSearchContext
|
||||
from cli.utils import SHELL_TEXT_FORMATTER
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DetailSectionSnapshot:
|
||||
"""
|
||||
TUI 详情页单个分区快照。
|
||||
|
||||
:param title: 分区标题
|
||||
:param status: 分区状态
|
||||
:param lines: 分区正文文本行
|
||||
"""
|
||||
|
||||
title: str
|
||||
status: str
|
||||
lines: list[str]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DetailPageSnapshot:
|
||||
"""
|
||||
TUI 详情页聚合快照。
|
||||
|
||||
:param title: 页面标题
|
||||
:param subtitle: 页面副标题
|
||||
:param sections: 页面分区列表
|
||||
:param search: 当前页面搜索上下文
|
||||
"""
|
||||
|
||||
title: str
|
||||
subtitle: str
|
||||
sections: list[DetailSectionSnapshot]
|
||||
search: PageSearchContext | None = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BrowserRecordSnapshot:
|
||||
"""
|
||||
TUI 浏览页单条记录快照。
|
||||
|
||||
:param key: 记录唯一标识
|
||||
:param title: 记录标题
|
||||
:param status: 记录状态
|
||||
:param summary: 记录摘要
|
||||
:param metadata_lines: 记录元信息文本行
|
||||
:param detail_sections: 记录联动详情分区列表
|
||||
"""
|
||||
|
||||
key: str
|
||||
title: str
|
||||
status: str
|
||||
summary: str
|
||||
metadata_lines: list[str]
|
||||
detail_sections: list[DetailSectionSnapshot]
|
||||
detail_loader: Callable[[], list[DetailSectionSnapshot]] | None = None
|
||||
_cached_detail_sections: tuple[DetailSectionSnapshot, ...] | None = field(
|
||||
default=None,
|
||||
init=False,
|
||||
repr=False,
|
||||
compare=False,
|
||||
)
|
||||
|
||||
def resolve_detail_sections(self) -> list[DetailSectionSnapshot]:
|
||||
"""
|
||||
获取当前记录详情分区,必要时按需加载并缓存。
|
||||
|
||||
:return: 详情分区列表
|
||||
"""
|
||||
if self.detail_loader is None:
|
||||
return self.detail_sections
|
||||
if self._cached_detail_sections is None:
|
||||
object.__setattr__(self, '_cached_detail_sections', tuple(self.detail_loader()))
|
||||
return list(self._cached_detail_sections)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BrowserPageSnapshot:
|
||||
"""
|
||||
TUI 浏览页聚合快照。
|
||||
|
||||
:param title: 页面标题
|
||||
:param subtitle: 页面副标题
|
||||
:param records: 可浏览记录列表
|
||||
:param shared_sections: 全局共享分区列表
|
||||
:param filters: 页面可用筛选项
|
||||
:param active_filter_key: 当前激活筛选键
|
||||
:param search: 当前页面搜索上下文
|
||||
"""
|
||||
|
||||
title: str
|
||||
subtitle: str
|
||||
records: list[BrowserRecordSnapshot]
|
||||
shared_sections: list[DetailSectionSnapshot]
|
||||
filters: list[PageFilterOption] = field(default_factory=list)
|
||||
active_filter_key: str | None = None
|
||||
search: PageSearchContext | None = None
|
||||
|
||||
|
||||
class TuiAdapterModelRenderService:
|
||||
"""
|
||||
TUI 适配层模型渲染服务。
|
||||
|
||||
该对象集中封装结果负载摘要提取,以及空态、加载态、失败态文本行
|
||||
的统一构建逻辑,避免这些模块级辅助函数继续散落扩张。
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def extract_payload_message(payload: dict[str, object] | None) -> str:
|
||||
"""
|
||||
提取结果负载中的可读消息。
|
||||
|
||||
:param payload: 标准结果负载
|
||||
:return: 摘要消息文本
|
||||
"""
|
||||
if not isinstance(payload, dict):
|
||||
return '-'
|
||||
if payload.get('message'):
|
||||
return SHELL_TEXT_FORMATTER.truncate_text(payload.get('message', '-'), 120)
|
||||
if payload.get('error'):
|
||||
return SHELL_TEXT_FORMATTER.truncate_text(payload.get('error', '-'), 120)
|
||||
return '-'
|
||||
|
||||
@staticmethod
|
||||
def build_empty_lines(
|
||||
*,
|
||||
empty_label: str,
|
||||
empty_value: str,
|
||||
detail: str,
|
||||
suggestion: str = TUI_COPY.build_empty_state_suggestion(),
|
||||
) -> list[str]:
|
||||
"""
|
||||
构建统一的空态文本行。
|
||||
|
||||
:param empty_label: 空态主字段名称
|
||||
:param empty_value: 空态主字段值
|
||||
:param detail: 空态说明
|
||||
:param suggestion: 建议操作
|
||||
:return: 空态文本行列表
|
||||
"""
|
||||
return [
|
||||
TUI_COPY.build_state_section_title('status'),
|
||||
f'{empty_label}: {empty_value}',
|
||||
'',
|
||||
TUI_COPY.build_state_section_title('detail'),
|
||||
detail,
|
||||
'',
|
||||
TUI_COPY.build_state_section_title('suggestion'),
|
||||
suggestion,
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def build_loading_lines(
|
||||
*,
|
||||
loading_label: str,
|
||||
loading_value: str,
|
||||
detail: str,
|
||||
suggestion: str = TUI_COPY.build_loading_state_suggestion(),
|
||||
) -> list[str]:
|
||||
"""
|
||||
构建统一的加载中文本行。
|
||||
|
||||
:param loading_label: 加载态主字段名称
|
||||
:param loading_value: 加载态主字段值
|
||||
:param detail: 加载说明
|
||||
:param suggestion: 建议操作
|
||||
:return: 加载态文本行列表
|
||||
"""
|
||||
return [
|
||||
TUI_COPY.build_state_section_title('status'),
|
||||
f'{loading_label}: {loading_value}',
|
||||
'',
|
||||
TUI_COPY.build_state_section_title('detail'),
|
||||
detail,
|
||||
'',
|
||||
TUI_COPY.build_state_section_title('suggestion'),
|
||||
suggestion,
|
||||
]
|
||||
|
||||
def build_failure_lines(
|
||||
self,
|
||||
payload: dict[str, object] | None,
|
||||
*,
|
||||
empty_label: str,
|
||||
empty_value: str,
|
||||
) -> list[str]:
|
||||
"""
|
||||
为失败状态构建统一的可读文本行。
|
||||
|
||||
:param payload: 标准结果负载
|
||||
:param empty_label: 主字段标签
|
||||
:param empty_value: 主字段兜底值
|
||||
:return: 失败状态文本行列表
|
||||
"""
|
||||
lines = [
|
||||
TUI_COPY.build_state_section_title('status'),
|
||||
f'{empty_label}: {empty_value}',
|
||||
'',
|
||||
TUI_COPY.build_state_section_title('error'),
|
||||
]
|
||||
if not isinstance(payload, dict):
|
||||
lines.append('结果消息: -')
|
||||
lines.extend(
|
||||
['', TUI_COPY.build_state_section_title('suggestion'), TUI_COPY.build_failure_state_suggestion()]
|
||||
)
|
||||
return lines
|
||||
lines.append(f'结果消息: {self.extract_payload_message(payload)}')
|
||||
detail_lines: list[str] = []
|
||||
if payload.get('hint'):
|
||||
detail_lines.append(f'建议提示: {SHELL_TEXT_FORMATTER.truncate_text(payload.get("hint", "-"), 120)}')
|
||||
if payload.get('error'):
|
||||
detail_lines.append(f'错误信息: {SHELL_TEXT_FORMATTER.truncate_text(payload.get("error", "-"), 120)}')
|
||||
if payload.get('stderr'):
|
||||
detail_lines.append(f'标准错误: {SHELL_TEXT_FORMATTER.truncate_text(payload.get("stderr", "-"), 120)}')
|
||||
if payload.get('stdout'):
|
||||
detail_lines.append(f'标准输出: {SHELL_TEXT_FORMATTER.truncate_text(payload.get("stdout", "-"), 120)}')
|
||||
if detail_lines:
|
||||
lines.extend(['', TUI_COPY.build_state_section_title('diagnostic'), *detail_lines])
|
||||
lines.extend(['', TUI_COPY.build_state_section_title('suggestion'), TUI_COPY.build_failure_state_suggestion()])
|
||||
return lines
|
||||
|
||||
|
||||
TUI_ADAPTER_MODEL_RENDERER = TuiAdapterModelRenderService()
|
||||
Reference in New Issue
Block a user