Update entity attribute API to support flexible attribute creation

This commit is contained in:
OpenClaw Bot
2026-02-20 00:17:33 +08:00
parent f5c859b850
commit bd5f497ccb

View File

@@ -1530,8 +1530,11 @@ class AttributeTemplateUpdate(BaseModel):
class EntityAttributeSet(BaseModel): class EntityAttributeSet(BaseModel):
template_id: str name: str
value: str type: str
value: Optional[Union[str, int, float, List[str]]] = None
template_id: Optional[str] = None
options: Optional[List[str]] = None
change_reason: Optional[str] = "" change_reason: Optional[str] = ""
@@ -1665,31 +1668,82 @@ async def set_entity_attribute_endpoint(entity_id: str, attr: EntityAttributeSet
if not DB_AVAILABLE: if not DB_AVAILABLE:
raise HTTPException(status_code=500, detail="Database not available") raise HTTPException(status_code=500, detail="Database not available")
from db_manager import EntityAttribute
db = get_db_manager() db = get_db_manager()
entity = db.get_entity(entity_id) entity = db.get_entity(entity_id)
if not entity: if not entity:
raise HTTPException(status_code=404, detail="Entity not found") raise HTTPException(status_code=404, detail="Entity not found")
# 验证模板存在 # 验证类型
template = db.get_attribute_template(attr.template_id) valid_types = ['text', 'number', 'date', 'select', 'multiselect']
if not template: if attr.type not in valid_types:
raise HTTPException(status_code=404, detail="Attribute template not found") raise HTTPException(status_code=400, detail=f"Invalid type. Must be one of: {valid_types}")
new_attr = EntityAttribute( # 处理 value
id=str(uuid.uuid4())[:8],
entity_id=entity_id,
template_id=attr.template_id,
value = attr.value value = attr.value
if attr.type == 'multiselect' and isinstance(value, list):
value = json.dumps(value)
elif value is not None:
value = str(value)
# 处理 options
options = attr.options
if options:
options = json.dumps(options)
# 检查是否已存在
conn = db.get_conn()
existing = conn.execute(
"SELECT * FROM entity_attributes WHERE entity_id = ? AND name = ?",
(entity_id, attr.name)
).fetchone()
now = datetime.now().isoformat()
if existing:
# 记录历史
conn.execute(
"""INSERT INTO attribute_history
(id, entity_id, attribute_name, old_value, new_value, changed_by, changed_at, change_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(str(uuid.uuid4())[:8], entity_id, attr.name, existing['value'], value,
"user", now, attr.change_reason or "")
) )
db.set_entity_attribute(new_attr, changed_by="user", change_reason=attr.change_reason) # 更新
conn.execute(
"""UPDATE entity_attributes
SET value = ?, type = ?, options = ?, updated_at = ?
WHERE id = ?""",
(value, attr.type, options, now, existing['id'])
)
attr_id = existing['id']
else:
# 创建
attr_id = str(uuid.uuid4())[:8]
conn.execute(
"""INSERT INTO entity_attributes
(id, entity_id, template_id, name, type, value, options, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(attr_id, entity_id, attr.template_id, attr.name, attr.type, value, options, now, now)
)
# 记录历史
conn.execute(
"""INSERT INTO attribute_history
(id, entity_id, attribute_name, old_value, new_value, changed_by, changed_at, change_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(str(uuid.uuid4())[:8], entity_id, attr.name, None, value,
"user", now, attr.change_reason or "创建属性")
)
conn.commit()
conn.close()
return { return {
"id": attr_id,
"entity_id": entity_id, "entity_id": entity_id,
"template_id": attr.template_id, "name": attr.name,
"template_name": template.name, "type": attr.type,
"value": attr.value, "value": attr.value,
"success": True "success": True
} }