feat:新增物料

This commit is contained in:
2026-10-13 04:16:00 -07:00
parent b117f21e3a
commit a80727b7a0
15 changed files with 174 additions and 54 deletions
+11 -1
View File
@@ -20,10 +20,11 @@ ValueType = Literal[
ItemType = Literal["string", "number", "integer", "boolean", "color", "object"]
# 值类型对应的前端属性控件;array / object 没有通用控件,只能不在面板显示
# number 可以输入小数,integer 只能输入整数
PANEL_CONTROLS: dict[str, str] = {
"string": "input",
"number": "number",
"integer": "number",
"integer": "integer",
"boolean": "checkbox",
"color": "color",
"enum": "select",
@@ -101,6 +102,10 @@ class MaterialField(ExtensibleModel):
aliases: list[NonBlankString] = Field(
default_factory=list, description="用户可能的叫法,供字段搜索使用"
)
themed: bool = Field(
default=False,
description="颜色跟随画布主题:默认配置里不写值,由前端按画布主题(亮 / 暗)取色;写入 null 恢复跟随",
)
editable: bool = Field(default=True, description="是否允许修改")
panel: bool = Field(default=True, description="是否显示在前端属性面板")
span: int | None = Field(default=None, description="属性面板栅格宽度,24 为整行")
@@ -115,10 +120,15 @@ class MaterialField(ExtensibleModel):
raise ValueError(f"只有 array 字段提供 item_type,且 array 必须提供: {self.path}")
if self.panel and self.value_type not in PANEL_CONTROLS:
raise ValueError(f"{self.value_type} 字段没有属性面板控件,panel 必须为 false: {self.path}")
if self.themed and (self.value_type != "color" or self.default is not None):
raise ValueError(f"只有 color 字段可以跟随主题,且不能声明 default: {self.path}")
return self
def value_error(self, value: JsonValue) -> str | None:
"""检查值是否符合字段类型和取值约束,符合返回 None"""
# 跟随主题的颜色写 null 表示去掉单独设置的颜色、恢复跟随
if self.themed and value is None:
return None
if self.value_type == "enum":
allowed = [option.value for option in self.options]
return None if value in allowed else f"取值必须是 {allowed} 之一"