mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 21:52:56 +08:00
Some checks failed
检查bot是否运行正常 / bot check (push) Waiting to run
Sequential Lint and Type Check / ruff-call (push) Waiting to run
Sequential Lint and Type Check / pyright-call (push) Blocked by required conditions
Release Drafter / Update Release Draft (push) Waiting to run
Force Sync to Aliyun / sync (push) Waiting to run
Update Version / update-version (push) Waiting to run
CodeQL Code Security Analysis / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
CodeQL Code Security Analysis / Analyze (${{ matrix.language }}) (none, python) (push) Has been cancelled
* ♻️ refactor(UI): 重构UI渲染服务为组件化分层架构 ♻️ **架构重构** - UI渲染服务重构为组件化分层架构 - 解耦主题管理、HTML生成、截图功能 ✨ **新增功能** - `zhenxun.ui` 统一入口,提供 `render`、`markdown`、`vstack` 等API - `RenderableComponent` 基类和渲染协议抽象 - 新增主题管理器和截图引擎模块 ⚙️ **配置优化** - UI配置迁移至 `superuser/ui_manager.py` - 新增"重载UI主题"管理指令 🔧 **性能改进** - 优化渲染缓存,支持组件级透明缓存 - 所有UI组件适配新渲染流程 * 🚨 auto fix by pre-commit hooks --------- Co-authored-by: webjoin111 <455457521@qq.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
from abc import ABC, abstractmethod
|
|
import asyncio
|
|
from collections.abc import Awaitable, Iterator
|
|
from typing import Any
|
|
|
|
from nonebot.compat import model_dump
|
|
from pydantic import BaseModel
|
|
|
|
from zhenxun.services.renderer.protocols import Renderable
|
|
|
|
__all__ = ["ContainerComponent", "RenderableComponent"]
|
|
|
|
|
|
class RenderableComponent(BaseModel, Renderable):
|
|
"""所有可渲染UI组件的抽象基类。"""
|
|
|
|
_is_standalone_template: bool = False
|
|
|
|
@property
|
|
def template_name(self) -> str:
|
|
"""
|
|
返回用于渲染此组件的Jinja2模板的路径。
|
|
这是一个抽象属性,所有子类都必须覆盖它。
|
|
"""
|
|
raise NotImplementedError(
|
|
"Subclasses must implement the 'template_name' property."
|
|
)
|
|
|
|
async def prepare(self) -> None:
|
|
"""[可选] 生命周期钩子,默认无操作。"""
|
|
pass
|
|
|
|
def get_required_scripts(self) -> list[str]:
|
|
"""[可选] 返回此组件所需的JS脚本路径列表 (相对于assets目录)。"""
|
|
return []
|
|
|
|
def get_required_styles(self) -> list[str]:
|
|
"""[可选] 返回此组件所需的CSS样式表路径列表 (相对于assets目录)。"""
|
|
return []
|
|
|
|
def get_render_data(self) -> dict[str, Any | Awaitable[Any]]:
|
|
"""默认实现,返回模型自身的数据字典。"""
|
|
return model_dump(self)
|
|
|
|
def get_extra_css(self, theme_manager: Any) -> str | Awaitable[str]:
|
|
return ""
|
|
|
|
|
|
class ContainerComponent(RenderableComponent, ABC):
|
|
"""
|
|
一个为容器类组件设计的抽象基类,封装了预渲染子组件的通用逻辑。
|
|
"""
|
|
|
|
@abstractmethod
|
|
def _get_renderable_child_items(self) -> Iterator[Any]:
|
|
"""
|
|
一个抽象方法,子类必须实现它来返回一个可迭代的对象。
|
|
迭代器中的每个项目都必须具有 'component' 和 'html_content' 属性。
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
async def prepare(self) -> None:
|
|
"""
|
|
通用的 prepare 方法,负责预渲染所有子组件。
|
|
"""
|
|
from zhenxun.services import renderer_service
|
|
|
|
child_items = list(self._get_renderable_child_items())
|
|
if not child_items:
|
|
return
|
|
|
|
components_to_render = [
|
|
item.component for item in child_items if item.component
|
|
]
|
|
|
|
prepare_tasks = [
|
|
comp.prepare() for comp in components_to_render if hasattr(comp, "prepare")
|
|
]
|
|
if prepare_tasks:
|
|
await asyncio.gather(*prepare_tasks)
|
|
|
|
render_tasks = [
|
|
renderer_service.render_to_html(comp) for comp in components_to_render
|
|
]
|
|
rendered_htmls = await asyncio.gather(*render_tasks)
|
|
|
|
for item, html in zip(child_items, rendered_htmls):
|
|
item.html_content = html
|