Phase 5: 实体属性扩展功能

- 数据库层:
  - 新增 entity_attributes 表存储自定义属性
  - 新增 attribute_templates 表管理属性模板
  - 新增 attribute_history 表记录属性变更历史

- 后端 API:
  - GET/POST /api/v1/projects/{id}/attribute-templates - 属性模板管理
  - GET/POST/PUT/DELETE /api/v1/entities/{id}/attributes - 实体属性 CRUD
  - GET /api/v1/entities/{id}/attributes/history - 属性变更历史
  - GET /api/v1/projects/{id}/entities/search-by-attributes - 属性筛选搜索

- 前端 UI:
  - 实体详情面板添加属性展示
  - 属性编辑表单(支持文本、数字、日期、单选、多选)
  - 属性模板管理界面
  - 属性变更历史查看
  - 知识库实体卡片显示属性预览
  - 属性筛选搜索栏
This commit is contained in:
OpenClaw Bot
2026-02-20 00:10:49 +08:00
parent 626fa7e1c0
commit 7b67f3756e
7 changed files with 2209 additions and 27 deletions

View File

@@ -75,6 +75,94 @@ CREATE TABLE IF NOT EXISTS glossary (
FOREIGN KEY (project_id) REFERENCES projects(id)
);
-- Phase 5: 属性模板表
CREATE TABLE IF NOT EXISTS attribute_templates (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL,
name TEXT NOT NULL,
type TEXT NOT NULL, -- text/number/date/select/multiselect
description TEXT,
options TEXT, -- JSON 数组,用于 select/multiselect 类型
is_required INTEGER DEFAULT 0,
default_value TEXT,
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id)
);
-- Phase 5: 实体属性值表
CREATE TABLE IF NOT EXISTS entity_attributes (
id TEXT PRIMARY KEY,
entity_id TEXT NOT NULL,
template_id TEXT,
name TEXT NOT NULL,
type TEXT NOT NULL, -- text/number/date/select/multiselect
value TEXT, -- 存储实际值
options TEXT, -- JSON 数组,用于 select/multiselect
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
FOREIGN KEY (template_id) REFERENCES attribute_templates(id) ON DELETE SET NULL,
UNIQUE(entity_id, name)
);
-- Phase 5: 属性变更历史表
CREATE TABLE IF NOT EXISTS attribute_history (
id TEXT PRIMARY KEY,
entity_id TEXT NOT NULL,
attribute_name TEXT NOT NULL,
old_value TEXT,
new_value TEXT,
changed_by TEXT, -- 用户ID或系统
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
change_reason TEXT,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
-- Phase 5: 属性模板表(项目级自定义属性定义)
CREATE TABLE IF NOT EXISTS attribute_templates (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL,
name TEXT NOT NULL, -- 属性名称,如"年龄"、"职位"
type TEXT NOT NULL, -- 属性类型: text, number, date, select, multiselect, boolean
options TEXT, -- JSON 数组,用于 select/multiselect 类型
default_value TEXT, -- 默认值
description TEXT, -- 属性描述
is_required BOOLEAN DEFAULT 0, -- 是否必填
display_order INTEGER DEFAULT 0, -- 显示顺序
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id)
);
-- Phase 5: 实体属性值表
CREATE TABLE IF NOT EXISTS entity_attributes (
id TEXT PRIMARY KEY,
entity_id TEXT NOT NULL,
template_id TEXT NOT NULL,
value TEXT, -- 属性值以JSON或字符串形式存储
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
FOREIGN KEY (template_id) REFERENCES attribute_templates(id) ON DELETE CASCADE,
UNIQUE(entity_id, template_id) -- 每个实体每个属性只能有一个值
);
-- Phase 5: 属性变更历史表
CREATE TABLE IF NOT EXISTS attribute_history (
id TEXT PRIMARY KEY,
entity_id TEXT NOT NULL,
template_id TEXT NOT NULL,
old_value TEXT,
new_value TEXT,
changed_by TEXT, -- 用户ID或"system"
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
change_reason TEXT, -- 变更原因
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
FOREIGN KEY (template_id) REFERENCES attribute_templates(id) ON DELETE CASCADE
);
-- 创建索引以提高查询性能
CREATE INDEX IF NOT EXISTS idx_entities_project ON entities(project_id);
CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
@@ -83,3 +171,15 @@ CREATE INDEX IF NOT EXISTS idx_mentions_entity ON entity_mentions(entity_id);
CREATE INDEX IF NOT EXISTS idx_mentions_transcript ON entity_mentions(transcript_id);
CREATE INDEX IF NOT EXISTS idx_relations_project ON entity_relations(project_id);
CREATE INDEX IF NOT EXISTS idx_glossary_project ON glossary(project_id);
-- Phase 5: 属性相关索引
CREATE INDEX IF NOT EXISTS idx_attr_templates_project ON attribute_templates(project_id);
CREATE INDEX IF NOT EXISTS idx_entity_attributes_entity ON entity_attributes(entity_id);
CREATE INDEX IF NOT EXISTS idx_entity_attributes_template ON entity_attributes(template_id);
CREATE INDEX IF NOT EXISTS idx_attr_history_entity ON attribute_history(entity_id);
-- Phase 5: 属性相关索引
CREATE INDEX IF NOT EXISTS idx_attr_templates_project ON attribute_templates(project_id);
CREATE INDEX IF NOT EXISTS idx_entity_attributes_entity ON entity_attributes(entity_id);
CREATE INDEX IF NOT EXISTS idx_entity_attributes_template ON entity_attributes(template_id);
CREATE INDEX IF NOT EXISTS idx_attr_history_entity ON attribute_history(entity_id);