102 lines
4.0 KiB
Python
102 lines
4.0 KiB
Python
"""前端组件目录及查询结果"""
|
|
|
|
from typing import Literal, Self
|
|
|
|
from pydantic import ConfigDict, Field, model_validator
|
|
|
|
from app.schemas.base import ExtensibleModel, JsonObject, NonBlankString
|
|
from app.schemas.screen import Layout
|
|
|
|
|
|
class MaterialTemplate(ExtensibleModel):
|
|
type: NonBlankString
|
|
name: NonBlankString
|
|
layout: Layout
|
|
props: JsonObject = Field(default_factory=dict)
|
|
style: JsonObject | None = None
|
|
events: list[JsonObject] = Field(default_factory=list)
|
|
|
|
|
|
class MaterialSetter(ExtensibleModel):
|
|
type: NonBlankString = Field(description="前端属性控件类型,不是完整的值类型约束")
|
|
label: NonBlankString
|
|
key: NonBlankString = Field(
|
|
description="前端原始点路径,例如 props.option.series.0.itemStyle.color"
|
|
)
|
|
props: JsonObject = Field(default_factory=dict)
|
|
|
|
|
|
class ComponentDefinition(ExtensibleModel):
|
|
model_config = ConfigDict(serialize_by_alias=True)
|
|
key: NonBlankString = Field(description="目录中的唯一编号,不是 Screen 节点 ID")
|
|
type: NonBlankString = Field(
|
|
description="前端实际注册的节点 type,不根据图表名称猜测"
|
|
)
|
|
name: NonBlankString = Field(description="组件名称")
|
|
description: NonBlankString = Field(description="组件用途和支持的展示方式")
|
|
tags: list[NonBlankString] = Field(
|
|
default_factory=list, description="用于检索的分类和关键词"
|
|
)
|
|
renderer: NonBlankString = Field(description="渲染能力标识,当前从前端实现映射而来")
|
|
group: NonBlankString
|
|
icon: NonBlankString | None = None
|
|
schema_: MaterialTemplate = Field(
|
|
alias="schema", description="完整默认物料配置,不包含实例 ID"
|
|
)
|
|
setters: list[MaterialSetter] = Field(default_factory=list)
|
|
eventOptions: list[JsonObject] = Field(default_factory=list)
|
|
sample_data: bool = Field(
|
|
default=False, description="默认配置是否含示例数据,不能视为真实业务数据"
|
|
)
|
|
props_schema: JsonObject | None = Field(
|
|
default=None,
|
|
description="可选的 props JSON Schema,未提供表示未知,不表示无限制",
|
|
)
|
|
style_schema: JsonObject | None = Field(
|
|
default=None, description="可选的 style JSON Schema,仅保存定义,当前不执行校验"
|
|
)
|
|
usage_notes: list[NonBlankString] = Field(
|
|
default_factory=list, description="配置、数据绑定及使用限制说明"
|
|
)
|
|
|
|
@model_validator(mode="after")
|
|
def consistent_type(self) -> Self:
|
|
if self.type != self.schema_.type:
|
|
raise ValueError("目录 type 必须与 schema.type 一致")
|
|
if "id" in self.schema_.model_extra:
|
|
raise ValueError("默认物料配置不能包含实例 ID")
|
|
return self
|
|
|
|
|
|
class ComponentCatalog(ExtensibleModel):
|
|
version: NonBlankString = Field(
|
|
description="前端组件目录版本,后续用于检查是否与前端匹配"
|
|
)
|
|
source: NonBlankString = Field(description="真实定义来源,例如前端组件注册文件路径")
|
|
components: list[ComponentDefinition]
|
|
|
|
@model_validator(mode="after")
|
|
def unique_keys(self) -> Self:
|
|
keys = [component.key for component in self.components]
|
|
if len(keys) != len(set(keys)):
|
|
raise ValueError("组件目录 key 不能重复")
|
|
return self
|
|
|
|
|
|
class ComponentQuery(ExtensibleModel):
|
|
key: NonBlankString | None = Field(default=None, description="精确匹配目录编号")
|
|
type: NonBlankString | None = Field(
|
|
default=None, description="精确匹配前端节点类型,可能对应多个预设"
|
|
)
|
|
keyword: NonBlankString | None = Field(
|
|
default=None, description="按名称、说明和标签查询,多个条件同时满足"
|
|
)
|
|
|
|
|
|
class ComponentResult(ExtensibleModel):
|
|
status: Literal["resolved", "not_found", "unsupported"]
|
|
components: list[ComponentDefinition] = Field(default_factory=list)
|
|
catalog_version: NonBlankString | None = None
|
|
source: NonBlankString | None = None
|
|
message: NonBlankString
|