ai模块修改
This commit is contained in:
51
docker/nginx/conf.d/dify.conf
Normal file
51
docker/nginx/conf.d/dify.conf
Normal file
@@ -0,0 +1,51 @@
|
||||
# Dify 服务代理配置
|
||||
|
||||
# Dify Web 前端
|
||||
location /dify/ {
|
||||
proxy_pass http://dify-web:3000/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 支持 WebSocket
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Dify API
|
||||
location /dify/api/ {
|
||||
proxy_pass http://dify-api:5001/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 支持 WebSocket (SSE)
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 超时配置(AI 响应可能较慢)
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
# 禁用缓冲(支持流式响应)
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# Dify App (公开应用)
|
||||
location /dify/app/ {
|
||||
proxy_pass http://dify-web:3000/app/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
166
urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql
Normal file
166
urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql
Normal file
@@ -0,0 +1,166 @@
|
||||
CREATE SCHEMA IF NOT EXISTS ai;
|
||||
|
||||
-- AI智能体配置
|
||||
DROP TABLE IF EXISTS ai.tb_agent CASCADE;
|
||||
CREATE TABLE ai.tb_agent(
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
name VARCHAR(50) NOT NULL, -- 智能体名称
|
||||
description VARCHAR(500) DEFAULT NULL, -- 智能体描述
|
||||
link VARCHAR(500) DEFAULT NULL, -- 智能体url
|
||||
api_key VARCHAR(500) NOT NULL, -- dify智能体APIKEY
|
||||
introduce VARCHAR(500) NOT NULL, -- 引导词
|
||||
prompt_cards JSONB DEFAULT '[]'::jsonb, -- 提示卡片数组 [{file_id:'', prompt:''}]
|
||||
category VARCHAR(50) NOT NULL, -- 分类
|
||||
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (agent_id),
|
||||
UNIQUE (optsn),
|
||||
UNIQUE (api_key)
|
||||
);
|
||||
|
||||
-- AI智能体对话
|
||||
DROP TABLE IF EXISTS ai.tb_chat CASCADE;
|
||||
CREATE TABLE ai.tb_chat(
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
chat_id VARCHAR(50) NOT NULL, -- 对话ID
|
||||
agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||
title VARCHAR(500) NOT NULL, -- 对话标题
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (chat_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
-- AI智能体对话消息
|
||||
DROP TABLE IF EXISTS ai.tb_chat_message CASCADE;
|
||||
CREATE TABLE ai.tb_chat_message(
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||
chat_id VARCHAR(50) NOT NULL, -- 对话ID
|
||||
role VARCHAR(50) NOT NULL, -- 角色:user-用户/assistant-智能体/recipient-客服
|
||||
content TEXT NOT NULL, -- 消息内容
|
||||
files VARCHAR(50)[] DEFAULT NULL, -- 文件id数组
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (message_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
|
||||
-- 知识库配置 bidding和workcase2个服务使用
|
||||
DROP TABLE IF EXISTS ai.tb_knowledge CASCADE;
|
||||
CREATE TABLE ai.tb_knowledge(
|
||||
-- 知识库dify相关配置
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||
title VARCHAR(255) NOT NULL, -- 知识库标题
|
||||
avatar VARCHAR(255) DEFAULT NULL, -- 知识库头像
|
||||
description VARCHAR(500) DEFAULT NULL, -- 知识库描述
|
||||
dify_dataset_id VARCHAR(100) DEFAULT NULL, -- Dify知识库ID(Dataset ID)
|
||||
dify_indexing_technique VARCHAR(50) DEFAULT 'high_quality', -- Dify索引方式(high_quality/economy)
|
||||
embedding_model VARCHAR(100) DEFAULT NULL, -- 向量模型名称
|
||||
embedding_model_provider VARCHAR(100) DEFAULT NULL, -- 向量模型提供商
|
||||
rerank_model VARCHAR(100) DEFAULT NULL, -- Rerank模型名称
|
||||
rerank_model_provider VARCHAR(100) DEFAULT NULL, -- Rerank模型提供商
|
||||
reranking_enable BOOLEAN DEFAULT false, -- 是否启用Rerank
|
||||
retrieval_top_k INTEGER DEFAULT 2, -- 检索Top K(返回前K个结果)
|
||||
retrieval_score_threshold DECIMAL(3,2) DEFAULT 0.00, -- 检索分数阈值(0.00-1.00)
|
||||
document_count INTEGER DEFAULT 0, -- 文档数量
|
||||
total_chunks INTEGER DEFAULT 0, -- 总分段数
|
||||
-- 下面是服务使用
|
||||
service VARCHAR(50) DEFAULT NULL, -- 所属服务 workcase、bidding
|
||||
project_id VARCHAR(50) DEFAULT NULL, -- bidding所属项目ID
|
||||
category VARCHAR(50) DEFAULT NULL, -- 所属分类 workcase 内部知识库、外部知识库
|
||||
creator VARCHAR(50) NOT NULL, -- 创建者(用户ID)
|
||||
dept_path VARCHAR(50) DEFAULT NULL, -- 创建者部门路径
|
||||
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (optsn),
|
||||
UNIQUE (knowledge_id),
|
||||
UNIQUE (dify_dataset_id)
|
||||
);
|
||||
|
||||
-- 知识库配置表字段注释
|
||||
COMMENT ON TABLE ai.tb_knowledge IS '知识库配置表';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.optsn IS '流水号';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.knowledge_id IS '知识库ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.title IS '知识库标题';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.avatar IS '知识库头像';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.description IS '知识库描述';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.dify_dataset_id IS 'Dify知识库ID(Dataset ID)';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.dify_indexing_technique IS 'Dify索引方式(high_quality/economy)';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.embedding_model IS '向量模型名称';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.embedding_model_provider IS '向量模型提供商';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.rerank_model IS 'Rerank模型名称';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.rerank_model_provider IS 'Rerank模型提供商';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.reranking_enable IS '是否启用Rerank';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.retrieval_top_k IS '检索Top K(返回前K个结果)';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.retrieval_score_threshold IS '检索分数阈值(0.00-1.00)';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.document_count IS '文档数量';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.total_chunks IS '总分段数';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.service IS '所属服务 workcase、bidding';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.project_id IS 'bidding所属项目ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.category IS '所属分类 workcase 内部知识库、外部知识库';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.creator IS '创建者(用户ID)';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.dept_path IS '创建者部门路径';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.updater IS '更新者';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.create_time IS '创建时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.update_time IS '更新时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.delete_time IS '删除时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge.deleted IS '是否删除';
|
||||
-- bidding知识库根据project等变化
|
||||
-- workcase知识库固定8个
|
||||
-- workcase外部知识库:4个知识库:
|
||||
-- 1. 设备操作指南
|
||||
-- 2. 常见故障解决方案
|
||||
-- 3. 三包外服务政策
|
||||
-- 4. 配件咨询话术
|
||||
-- workcase内部知识库:4个知识库:
|
||||
-- 1. 技术维修手册
|
||||
-- 2. 产品参数明细
|
||||
-- 3. 内部服务流程规范
|
||||
-- 4. 客户服务话术模板
|
||||
|
||||
-- 知识库文件 文件上传dify知识库,对dify内的文件修改不生成新版本, 只有重新上传才生成新版本
|
||||
DROP TABLE IF EXISTS ai.tb_knowledge_file CASCADE;
|
||||
CREATE TABLE ai.tb_knowledge_file(
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||
file_root_id VARCHAR(50) NOT NULL, -- 文件根ID
|
||||
file_id VARCHAR(50) NOT NULL, -- 文件ID
|
||||
dify_file_id VARCHAR(50) NOT NULL, -- dify文件ID
|
||||
version VARCHAR(50) NOT NULL, -- 文件版本
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (optsn),
|
||||
UNIQUE (knowledge_id, file_id)
|
||||
);
|
||||
|
||||
-- 知识库文件表字段注释
|
||||
COMMENT ON TABLE ai.tb_knowledge_file IS '知识库文件表';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.optsn IS '流水号';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.knowledge_id IS '知识库ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.file_root_id IS '文件根ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.file_id IS '文件ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.dify_file_id IS 'dify文件ID';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.version IS '文件版本';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.create_time IS '创建时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.update_time IS '更新时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.delete_time IS '删除时间';
|
||||
COMMENT ON COLUMN ai.tb_knowledge_file.deleted IS '是否删除';
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
-- -- =============================
|
||||
-- -- 智能体管理和平台基础设施模块
|
||||
-- -- 支持:智能体广场、API集成管理、智能体运维监控
|
||||
-- -- =============================
|
||||
-- CREATE SCHEMA IF NOT EXISTS agent;
|
||||
|
||||
-- -- 智能体定义表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- agent_code VARCHAR(100) NOT NULL, -- 智能体编码(唯一标识)
|
||||
-- agent_name VARCHAR(255) NOT NULL, -- 智能体名称
|
||||
-- agent_type VARCHAR(50) NOT NULL, -- 智能体类型:bidding-招投标/customer_service-客服/knowledge_assistant-知识助手/custom-自定义
|
||||
-- display_name VARCHAR(255) NOT NULL, -- 展示名称
|
||||
-- description TEXT, -- 智能体描述
|
||||
-- icon VARCHAR(500), -- 图标URL
|
||||
-- banner VARCHAR(500), -- Banner图URL
|
||||
-- version VARCHAR(20) DEFAULT '1.0.0', -- 版本号
|
||||
-- model_provider VARCHAR(50), -- 模型提供商:openai/anthropic/baidu/aliyun/custom
|
||||
-- model_name VARCHAR(100), -- 模型名称
|
||||
-- model_config JSONB, -- 模型配置(温度、最大tokens等)
|
||||
-- prompt_template TEXT, -- 提示词模板
|
||||
-- system_prompt TEXT, -- 系统提示词
|
||||
-- capabilities TEXT[], -- 能力列表
|
||||
-- access_level VARCHAR(20) DEFAULT 'private', -- 访问级别:public-公开/private-私有/internal-内部
|
||||
-- is_published BOOLEAN DEFAULT false, -- 是否发布到智能体广场
|
||||
-- usage_count INTEGER DEFAULT 0, -- 使用次数
|
||||
-- rating DECIMAL(3,2) DEFAULT 0, -- 评分(0-5)
|
||||
-- rating_count INTEGER DEFAULT 0, -- 评分人数
|
||||
-- tags TEXT[], -- 标签数组
|
||||
-- category VARCHAR(100), -- 分类
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- owner_user_id VARCHAR(50), -- 所有者用户ID
|
||||
-- status VARCHAR(20) DEFAULT 'active', -- 状态:active-激活/inactive-停用/under_maintenance-维护中
|
||||
-- creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
-- updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
-- delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (agent_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- UNIQUE (agent_code)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_agent_type ON agent.tb_agent(agent_type) WHERE deleted = false;
|
||||
-- CREATE INDEX idx_agent_published ON agent.tb_agent(is_published) WHERE deleted = false AND is_published = true;
|
||||
-- CREATE INDEX idx_agent_category ON agent.tb_agent(category) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent IS '智能体定义表';
|
||||
-- COMMENT ON COLUMN agent.tb_agent.agent_type IS '智能体类型:bidding/customer_service/knowledge_assistant/custom';
|
||||
|
||||
-- -- 智能体会话表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_session CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_session (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- session_id VARCHAR(50) NOT NULL, -- 会话ID
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||
-- session_type VARCHAR(30) DEFAULT 'chat', -- 会话类型:chat-对话/task-任务/workflow-工作流
|
||||
-- session_name VARCHAR(255), -- 会话名称
|
||||
-- context JSONB, -- 会话上下文
|
||||
-- session_status VARCHAR(20) DEFAULT 'active', -- 会话状态:active-活跃/paused-暂停/ended-结束
|
||||
-- start_time TIMESTAMPTZ DEFAULT now(), -- 开始时间
|
||||
-- end_time TIMESTAMPTZ, -- 结束时间
|
||||
-- message_count INTEGER DEFAULT 0, -- 消息数量
|
||||
-- token_usage INTEGER DEFAULT 0, -- Token使用量
|
||||
-- cost DECIMAL(10,4) DEFAULT 0, -- 成本
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (session_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- FOREIGN KEY (agent_id) REFERENCES agent.tb_agent(agent_id)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_session_agent ON agent.tb_agent_session(agent_id) WHERE deleted = false;
|
||||
-- CREATE INDEX idx_session_user ON agent.tb_agent_session(user_id) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_session IS '智能体会话表';
|
||||
|
||||
-- -- 智能体消息表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_message CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_message (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- message_id VARCHAR(50) NOT NULL, -- 消息ID
|
||||
-- session_id VARCHAR(50) NOT NULL, -- 会话ID
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- role VARCHAR(20) NOT NULL, -- 角色:user-用户/assistant-助手/system-系统/function-函数
|
||||
-- content TEXT, -- 消息内容
|
||||
-- content_type VARCHAR(30) DEFAULT 'text', -- 内容类型:text-文本/image-图片/file-文件/structured-结构化数据
|
||||
-- function_call JSONB, -- 函数调用(JSON格式)
|
||||
-- function_response JSONB, -- 函数响应
|
||||
-- token_count INTEGER, -- Token数量
|
||||
-- model_name VARCHAR(100), -- 使用的模型
|
||||
-- kb_references JSONB, -- 知识库引用(JSON数组)
|
||||
-- metadata JSONB, -- 消息元数据
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (message_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- FOREIGN KEY (session_id) REFERENCES agent.tb_agent_session(session_id),
|
||||
-- FOREIGN KEY (agent_id) REFERENCES agent.tb_agent(agent_id)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_msg_session ON agent.tb_agent_message(session_id, create_time) WHERE deleted = false;
|
||||
-- CREATE INDEX idx_msg_agent ON agent.tb_agent_message(agent_id) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_message IS '智能体消息表';
|
||||
|
||||
-- -- 智能体工具表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_tool CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_tool (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- tool_id VARCHAR(50) NOT NULL, -- 工具ID
|
||||
-- tool_code VARCHAR(100) NOT NULL, -- 工具编码
|
||||
-- tool_name VARCHAR(255) NOT NULL, -- 工具名称
|
||||
-- tool_type VARCHAR(50) NOT NULL, -- 工具类型:api-API调用/function-函数/plugin-插件/integration-集成
|
||||
-- description TEXT, -- 工具描述
|
||||
-- function_schema JSONB, -- 函数Schema(OpenAI function calling格式)
|
||||
-- api_endpoint VARCHAR(500), -- API端点
|
||||
-- api_method VARCHAR(10), -- API方法:GET/POST/PUT/DELETE
|
||||
-- api_headers JSONB, -- API请求头
|
||||
-- auth_type VARCHAR(30), -- 认证类型:none/api_key/oauth2/bearer
|
||||
-- auth_config JSONB, -- 认证配置(加密存储)
|
||||
-- request_template TEXT, -- 请求模板
|
||||
-- response_template TEXT, -- 响应模板
|
||||
-- timeout_seconds INTEGER DEFAULT 30, -- 超时时间(秒)
|
||||
-- retry_count INTEGER DEFAULT 3, -- 重试次数
|
||||
-- is_enabled BOOLEAN DEFAULT true, -- 是否启用
|
||||
-- usage_count INTEGER DEFAULT 0, -- 使用次数
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
-- updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
-- delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (tool_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- UNIQUE (tool_code)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_tool_type ON agent.tb_agent_tool(tool_type) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_tool IS '智能体工具表';
|
||||
|
||||
-- -- API集成注册表
|
||||
-- DROP TABLE IF EXISTS agent.tb_api_integration CASCADE;
|
||||
-- CREATE TABLE agent.tb_api_integration (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- integration_id VARCHAR(50) NOT NULL, -- 集成ID
|
||||
-- integration_name VARCHAR(255) NOT NULL, -- 集成名称
|
||||
-- integration_type VARCHAR(50) NOT NULL, -- 集成类型:rest_api/soap/graphql/webhook/mq
|
||||
-- provider VARCHAR(100), -- 提供商
|
||||
-- base_url VARCHAR(500), -- 基础URL
|
||||
-- version VARCHAR(20), -- API版本
|
||||
-- auth_type VARCHAR(30) DEFAULT 'none', -- 认证类型
|
||||
-- auth_config JSONB, -- 认证配置(加密存储)
|
||||
-- endpoints JSONB, -- 端点列表(JSON数组)
|
||||
-- rate_limit INTEGER, -- 速率限制(请求/秒)
|
||||
-- timeout_seconds INTEGER DEFAULT 30, -- 超时时间
|
||||
-- retry_config JSONB, -- 重试配置
|
||||
-- health_check_url VARCHAR(500), -- 健康检查URL
|
||||
-- health_status VARCHAR(20) DEFAULT 'unknown', -- 健康状态:healthy-健康/unhealthy-不健康/unknown-未知
|
||||
-- last_health_check TIMESTAMPTZ, -- 最后健康检查时间
|
||||
-- documentation_url VARCHAR(500), -- 文档URL
|
||||
-- is_enabled BOOLEAN DEFAULT true, -- 是否启用
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
-- updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
-- delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (integration_id),
|
||||
-- UNIQUE (optsn)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_integration_type ON agent.tb_api_integration(integration_type) WHERE deleted = false;
|
||||
-- CREATE INDEX idx_integration_health ON agent.tb_api_integration(health_status) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_api_integration IS 'API集成注册表';
|
||||
|
||||
-- -- API调用日志表
|
||||
-- DROP TABLE IF EXISTS agent.tb_api_call_log CASCADE;
|
||||
-- CREATE TABLE agent.tb_api_call_log (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- log_id VARCHAR(50) NOT NULL, -- 日志ID
|
||||
-- integration_id VARCHAR(50), -- 集成ID
|
||||
-- tool_id VARCHAR(50), -- 工具ID
|
||||
-- agent_id VARCHAR(50), -- 智能体ID
|
||||
-- session_id VARCHAR(50), -- 会话ID
|
||||
-- user_id VARCHAR(50), -- 用户ID
|
||||
-- endpoint VARCHAR(500) NOT NULL, -- 请求端点
|
||||
-- method VARCHAR(10) NOT NULL, -- 请求方法
|
||||
-- request_headers JSONB, -- 请求头
|
||||
-- request_body TEXT, -- 请求体
|
||||
-- response_status INTEGER, -- 响应状态码
|
||||
-- response_headers JSONB, -- 响应头
|
||||
-- response_body TEXT, -- 响应体
|
||||
-- duration_ms INTEGER, -- 请求耗时(毫秒)
|
||||
-- is_success BOOLEAN, -- 是否成功
|
||||
-- error_message TEXT, -- 错误信息
|
||||
-- retry_count INTEGER DEFAULT 0, -- 重试次数
|
||||
-- ip_address VARCHAR(45), -- IP地址
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- PRIMARY KEY (log_id),
|
||||
-- UNIQUE (optsn)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_api_log_integration ON agent.tb_api_call_log(integration_id, create_time DESC);
|
||||
-- CREATE INDEX idx_api_log_agent ON agent.tb_api_call_log(agent_id, create_time DESC);
|
||||
-- CREATE INDEX idx_api_log_status ON agent.tb_api_call_log(is_success, create_time DESC);
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_api_call_log IS 'API调用日志表';
|
||||
|
||||
-- -- 智能体监控指标表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_metrics CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_metrics (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- metric_id VARCHAR(50) NOT NULL, -- 指标ID
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- metric_date DATE NOT NULL, -- 指标日期
|
||||
-- metric_hour INTEGER, -- 指标小时(0-23)
|
||||
-- total_sessions INTEGER DEFAULT 0, -- 总会话数
|
||||
-- active_sessions INTEGER DEFAULT 0, -- 活跃会话数
|
||||
-- total_messages INTEGER DEFAULT 0, -- 总消息数
|
||||
-- total_tokens BIGINT DEFAULT 0, -- 总Token数
|
||||
-- total_cost DECIMAL(10,4) DEFAULT 0, -- 总成本
|
||||
-- avg_response_time INTEGER, -- 平均响应时间(毫秒)
|
||||
-- success_rate DECIMAL(5,4), -- 成功率
|
||||
-- error_count INTEGER DEFAULT 0, -- 错误次数
|
||||
-- api_call_count INTEGER DEFAULT 0, -- API调用次数
|
||||
-- avg_rating DECIMAL(3,2), -- 平均评分
|
||||
-- rating_count INTEGER DEFAULT 0, -- 评分数量
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
-- PRIMARY KEY (metric_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- UNIQUE (agent_id, metric_date, metric_hour),
|
||||
-- FOREIGN KEY (agent_id) REFERENCES agent.tb_agent(agent_id)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_metrics_agent_date ON agent.tb_agent_metrics(agent_id, metric_date DESC);
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_metrics IS '智能体监控指标表';
|
||||
|
||||
-- -- 智能体异常日志表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_error_log CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_error_log (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- log_id VARCHAR(50) NOT NULL, -- 日志ID
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- session_id VARCHAR(50), -- 会话ID
|
||||
-- error_type VARCHAR(50) NOT NULL, -- 错误类型:model_error-模型错误/api_error-API错误/timeout-超时/rate_limit-限流/other-其他
|
||||
-- error_code VARCHAR(50), -- 错误代码
|
||||
-- error_message TEXT NOT NULL, -- 错误信息
|
||||
-- stack_trace TEXT, -- 堆栈跟踪
|
||||
-- request_context JSONB, -- 请求上下文
|
||||
-- severity VARCHAR(20) DEFAULT 'error', -- 严重级别:critical-致命/error-错误/warning-警告
|
||||
-- is_resolved BOOLEAN DEFAULT false, -- 是否已解决
|
||||
-- resolution_notes TEXT, -- 解决方案备注
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- resolve_time TIMESTAMPTZ, -- 解决时间
|
||||
-- PRIMARY KEY (log_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- FOREIGN KEY (agent_id) REFERENCES agent.tb_agent(agent_id)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_error_agent ON agent.tb_agent_error_log(agent_id, create_time DESC);
|
||||
-- CREATE INDEX idx_error_severity ON agent.tb_agent_error_log(severity) WHERE is_resolved = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_error_log IS '智能体异常日志表';
|
||||
|
||||
-- -- 智能体评价表
|
||||
-- DROP TABLE IF EXISTS agent.tb_agent_rating CASCADE;
|
||||
-- CREATE TABLE agent.tb_agent_rating (
|
||||
-- optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
-- rating_id VARCHAR(50) NOT NULL, -- 评价ID
|
||||
-- agent_id VARCHAR(50) NOT NULL, -- 智能体ID
|
||||
-- session_id VARCHAR(50), -- 会话ID
|
||||
-- user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||
-- rating INTEGER NOT NULL, -- 评分(1-5星)
|
||||
-- dimensions JSONB, -- 分维度评分(准确性、速度、友好度等)
|
||||
-- feedback TEXT, -- 评价反馈
|
||||
-- tags TEXT[], -- 标签
|
||||
-- is_anonymous BOOLEAN DEFAULT false, -- 是否匿名
|
||||
-- dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
-- create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
-- deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
-- PRIMARY KEY (rating_id),
|
||||
-- UNIQUE (optsn),
|
||||
-- FOREIGN KEY (agent_id) REFERENCES agent.tb_agent(agent_id)
|
||||
-- );
|
||||
|
||||
-- CREATE INDEX idx_rating_agent ON agent.tb_agent_rating(agent_id) WHERE deleted = false;
|
||||
|
||||
-- COMMENT ON TABLE agent.tb_agent_rating IS '智能体评价表';
|
||||
@@ -1,156 +0,0 @@
|
||||
-- =============================
|
||||
-- 泰豪电源AI数智化平台 - 完整数据库初始化脚本
|
||||
-- 包含所有业务模块的表结构
|
||||
-- =============================
|
||||
|
||||
-- 安装必要的扩展
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID生成
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- 全文搜索
|
||||
CREATE EXTENSION IF NOT EXISTS "btree_gin"; -- GIN索引支持
|
||||
-- CREATE EXTENSION IF NOT EXISTS "vector"; -- pgvector向量检索(需要单独安装)
|
||||
|
||||
-- =============================
|
||||
-- 1. 系统基础模块(权限、用户、部门、角色)
|
||||
-- =============================
|
||||
\i createTablePermission.sql
|
||||
\i createTableUser.sql
|
||||
|
||||
-- =============================
|
||||
-- 2. 文件管理模块
|
||||
-- =============================
|
||||
\i createTableFile.sql
|
||||
|
||||
-- =============================
|
||||
-- 3. 消息通知模块
|
||||
-- =============================
|
||||
\i createTableMessage.sql
|
||||
|
||||
-- =============================
|
||||
-- 4. 日志模块
|
||||
-- =============================
|
||||
\i createTableLog.sql
|
||||
|
||||
-- =============================
|
||||
-- 5. 配置管理模块
|
||||
-- =============================
|
||||
\i createTableConfig.sql
|
||||
|
||||
-- =============================
|
||||
-- 6. 知识库管理模块
|
||||
-- =============================
|
||||
\i createTableKnowledge.sql
|
||||
|
||||
-- =============================
|
||||
-- 7. 招投标智能体业务模块
|
||||
-- =============================
|
||||
\i createTableBidding.sql
|
||||
|
||||
-- =============================
|
||||
-- 8. 智能客服系统业务模块
|
||||
-- =============================
|
||||
\i createTableCustomerService.sql
|
||||
|
||||
-- =============================
|
||||
-- 9. 智能体管理和平台基础设施模块
|
||||
-- =============================
|
||||
\i createTableAgent.sql
|
||||
|
||||
-- =============================
|
||||
-- 创建视图
|
||||
-- =============================
|
||||
|
||||
-- 用户完整信息视图
|
||||
CREATE OR REPLACE VIEW sys.v_user_full_info AS
|
||||
SELECT
|
||||
u.user_id,
|
||||
u.email,
|
||||
u.phone,
|
||||
u.wechat_id,
|
||||
u.status,
|
||||
ui.avatar,
|
||||
ui.full_name,
|
||||
ui.gender,
|
||||
ui.level,
|
||||
u.create_time,
|
||||
u.update_time
|
||||
FROM sys.tb_sys_user u
|
||||
LEFT JOIN sys.tb_sys_user_info ui ON u.user_id = ui.user_id
|
||||
WHERE u.deleted = false AND (ui.deleted = false OR ui.deleted IS NULL);
|
||||
|
||||
-- 用户角色权限视图
|
||||
CREATE OR REPLACE VIEW sys.v_user_role_permission AS
|
||||
SELECT DISTINCT
|
||||
ur.user_id,
|
||||
r.role_id,
|
||||
r.name AS role_name,
|
||||
p.permission_id,
|
||||
p.code AS permission_code,
|
||||
p.name AS permission_name,
|
||||
m.module_id,
|
||||
m.name AS module_name
|
||||
FROM sys.tb_sys_user_role ur
|
||||
JOIN sys.tb_sys_role r ON ur.role_id = r.role_id
|
||||
JOIN sys.tb_sys_role_permission rp ON r.role_id = rp.role_id
|
||||
JOIN sys.tb_sys_permission p ON rp.permission_id = p.permission_id
|
||||
LEFT JOIN sys.tb_sys_module m ON p.module_id = m.module_id
|
||||
WHERE ur.deleted = false
|
||||
AND r.deleted = false
|
||||
AND rp.deleted = false
|
||||
AND p.deleted = false;
|
||||
|
||||
-- 智能体使用统计视图
|
||||
CREATE OR REPLACE VIEW agent.v_agent_usage_stats AS
|
||||
SELECT
|
||||
a.agent_id,
|
||||
a.agent_name,
|
||||
a.agent_type,
|
||||
COUNT(DISTINCT s.session_id) AS total_sessions,
|
||||
COUNT(DISTINCT s.user_id) AS unique_users,
|
||||
SUM(s.message_count) AS total_messages,
|
||||
AVG(s.token_usage) AS avg_token_usage,
|
||||
AVG(r.rating) AS avg_rating,
|
||||
COUNT(r.rating_id) AS rating_count,
|
||||
MAX(s.start_time) AS last_used_time
|
||||
FROM agent.tb_agent a
|
||||
LEFT JOIN agent.tb_agent_session s ON a.agent_id = s.agent_id AND s.deleted = false
|
||||
LEFT JOIN agent.tb_agent_rating r ON a.agent_id = r.agent_id AND r.deleted = false
|
||||
WHERE a.deleted = false
|
||||
GROUP BY a.agent_id, a.agent_name, a.agent_type;
|
||||
|
||||
-- 客服工单统计视图
|
||||
CREATE OR REPLACE VIEW customer_service.v_ticket_stats AS
|
||||
SELECT
|
||||
t.ticket_status,
|
||||
t.priority,
|
||||
t.ticket_type,
|
||||
COUNT(*) AS ticket_count,
|
||||
AVG(EXTRACT(EPOCH FROM (t.resolution_time - t.create_time))/3600) AS avg_resolution_hours,
|
||||
AVG(t.customer_rating) AS avg_rating,
|
||||
COUNT(CASE WHEN t.is_overdue THEN 1 END) AS overdue_count
|
||||
FROM customer_service.tb_ticket t
|
||||
WHERE t.deleted = false
|
||||
GROUP BY t.ticket_status, t.priority, t.ticket_type;
|
||||
|
||||
-- 招投标项目统计视图
|
||||
CREATE OR REPLACE VIEW bidding.v_project_stats AS
|
||||
SELECT
|
||||
p.project_status,
|
||||
p.project_type,
|
||||
COUNT(*) AS project_count,
|
||||
SUM(p.budget_amount) AS total_budget,
|
||||
SUM(CASE WHEN p.winning_status = 'won' THEN 1 ELSE 0 END) AS won_count,
|
||||
SUM(CASE WHEN p.winning_status = 'won' THEN p.winning_amount ELSE 0 END) AS total_won_amount,
|
||||
AVG(CASE WHEN p.winning_status = 'won' THEN p.winning_amount / NULLIF(p.budget_amount, 0) ELSE NULL END) AS avg_win_rate
|
||||
FROM bidding.tb_bidding_project p
|
||||
WHERE p.deleted = false
|
||||
GROUP BY p.project_status, p.project_type;
|
||||
|
||||
COMMENT ON VIEW sys.v_user_full_info IS '用户完整信息视图';
|
||||
COMMENT ON VIEW sys.v_user_role_permission IS '用户角色权限视图';
|
||||
COMMENT ON VIEW agent.v_agent_usage_stats IS '智能体使用统计视图';
|
||||
COMMENT ON VIEW customer_service.v_ticket_stats IS '客服工单统计视图';
|
||||
COMMENT ON VIEW bidding.v_project_stats IS '招投标项目统计视图';
|
||||
|
||||
-- =============================
|
||||
-- 数据库初始化完成
|
||||
-- =============================
|
||||
@@ -15,6 +15,8 @@ CREATE TABLE file.tb_sys_file (
|
||||
|
||||
-- TbSysFileDTO 特有字段
|
||||
file_id VARCHAR(50) NOT NULL, -- 文件ID (主键)
|
||||
file_root_id VARCHAR(50) DEFAULT NULL, -- 文件根ID
|
||||
version VARCHAR(50) DEFAULT NULL, -- 文件版本
|
||||
name VARCHAR(255) NOT NULL, -- 文件名
|
||||
path VARCHAR(500) NOT NULL, -- 文件路径
|
||||
size BIGINT NOT NULL, -- 文件大小(字节)
|
||||
@@ -50,6 +52,8 @@ COMMENT ON COLUMN file.tb_sys_file.deleted IS '是否已删除(0-未删除,1
|
||||
|
||||
-- TbSysFileDTO 特有字段注释
|
||||
COMMENT ON COLUMN file.tb_sys_file.file_id IS '文件ID (主键)';
|
||||
COMMENT ON COLUMN file.tb_sys_file.file_root_id IS '文件根ID';
|
||||
COMMENT ON COLUMN file.tb_sys_file.version IS '文件版本';
|
||||
COMMENT ON COLUMN file.tb_sys_file.name IS '文件名';
|
||||
COMMENT ON COLUMN file.tb_sys_file.path IS '文件路径';
|
||||
COMMENT ON COLUMN file.tb_sys_file.size IS '文件大小(字节)';
|
||||
@@ -73,48 +77,3 @@ CREATE INDEX idx_file_bucket ON file.tb_sys_file(bucket_name) WHERE deleted = 0;
|
||||
CREATE INDEX idx_file_status ON file.tb_sys_file(status) WHERE deleted = 0;
|
||||
CREATE INDEX idx_file_create_time ON file.tb_sys_file(create_time) WHERE deleted = 0;
|
||||
CREATE INDEX idx_file_md5 ON file.tb_sys_file(md5_hash) WHERE deleted = 0;
|
||||
|
||||
-- =============================
|
||||
-- 文件关联表
|
||||
-- =============================
|
||||
DROP TABLE IF EXISTS file.tb_file_relation CASCADE;
|
||||
CREATE TABLE file.tb_file_relation (
|
||||
optsn VARCHAR(50) NOT NULL,
|
||||
relation_id VARCHAR(50) NOT NULL,
|
||||
file_id VARCHAR(50) NOT NULL,
|
||||
object_type VARCHAR(50) NOT NULL, -- 对象类型:bidding_project/ticket/document等
|
||||
object_id VARCHAR(50) NOT NULL, -- 对象ID
|
||||
relation_type VARCHAR(30) DEFAULT 'attachment', -- 关联类型:attachment-附件/avatar-头像/banner-横幅
|
||||
order_num INTEGER DEFAULT 0, -- 排序号
|
||||
service_type VARCHAR(50), -- 服务类型(继承自object_type)
|
||||
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (relation_id),
|
||||
UNIQUE (optsn),
|
||||
FOREIGN KEY (file_id) REFERENCES file.tb_sys_file(file_id)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE file.tb_file_relation IS '文件关联表';
|
||||
COMMENT ON COLUMN file.tb_file_relation.optsn IS '流水号';
|
||||
COMMENT ON COLUMN file.tb_file_relation.relation_id IS '关联ID';
|
||||
COMMENT ON COLUMN file.tb_file_relation.file_id IS '文件ID';
|
||||
COMMENT ON COLUMN file.tb_file_relation.object_type IS '对象类型:bidding_project/ticket/document等';
|
||||
COMMENT ON COLUMN file.tb_file_relation.object_id IS '对象ID';
|
||||
COMMENT ON COLUMN file.tb_file_relation.relation_type IS '关联类型:attachment-附件/avatar-头像/banner-横幅';
|
||||
COMMENT ON COLUMN file.tb_file_relation.order_num IS '排序号';
|
||||
COMMENT ON COLUMN file.tb_file_relation.service_type IS '服务类型(继承自object_type)';
|
||||
COMMENT ON COLUMN file.tb_file_relation.creator IS '创建者';
|
||||
COMMENT ON COLUMN file.tb_file_relation.updater IS '更新者';
|
||||
COMMENT ON COLUMN file.tb_file_relation.create_time IS '创建时间';
|
||||
COMMENT ON COLUMN file.tb_file_relation.update_time IS '更新时间';
|
||||
COMMENT ON COLUMN file.tb_file_relation.delete_time IS '删除时间';
|
||||
COMMENT ON COLUMN file.tb_file_relation.deleted IS '是否删除';
|
||||
|
||||
-- 文件关联表索引
|
||||
CREATE INDEX idx_file_relation_object ON file.tb_file_relation(object_type, object_id) WHERE deleted = false;
|
||||
CREATE INDEX idx_file_relation_file ON file.tb_file_relation(file_id) WHERE deleted = false;
|
||||
CREATE INDEX idx_file_relation_service ON file.tb_file_relation(service_type) WHERE deleted = false;
|
||||
@@ -1,153 +0,0 @@
|
||||
-- =============================
|
||||
-- 知识库管理模块
|
||||
-- 支持:招投标知识库、客服知识库、企业内部知识库
|
||||
-- =============================
|
||||
CREATE SCHEMA IF NOT EXISTS knowledge;
|
||||
|
||||
-- 知识库表(多租户知识库定义)
|
||||
DROP TABLE IF EXISTS knowledge.tb_knowledge_base CASCADE;
|
||||
CREATE TABLE knowledge.tb_knowledge_base (
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
agent_id VARCHAR(50) NOT NULL, -- 智能体id
|
||||
knowledge_id VARCHAR(50) NOT NULL, -- 知识库ID
|
||||
name VARCHAR(255) NOT NULL, -- 知识库名称
|
||||
kb_type VARCHAR(50) NOT NULL, -- 知识库类型:bidding-招投标/customer_service-客服/internal-内部协同
|
||||
access_level VARCHAR(20) NOT NULL DEFAULT 'private', -- 访问级别:public-公开/private-私有/internal-内部
|
||||
description TEXT, -- 知识库描述
|
||||
storage_path VARCHAR(500), -- 存储路径
|
||||
version VARCHAR(20) DEFAULT '1.0', -- 当前版本号
|
||||
config JSONB DEFAULT NULL, -- 知识库配置(JSON格式:索引配置、检索参数等)
|
||||
service_type VARCHAR(50), -- 服务类型(bidding/customer_service/internal,冗余kb_type便于查询)
|
||||
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-激活/inactive-停用/archived-归档
|
||||
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (knowledge_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_kb_type ON knowledge.tb_knowledge_base(kb_type) WHERE deleted = false;
|
||||
CREATE INDEX idx_kb_service ON knowledge.tb_knowledge_base(service_type) WHERE deleted = false;
|
||||
CREATE INDEX idx_kb_dept_path ON knowledge.tb_knowledge_base(dept_path) WHERE deleted = false;
|
||||
|
||||
COMMENT ON TABLE knowledge.tb_knowledge_base IS '知识库表';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_base.kb_type IS '知识库类型:bidding-招投标/customer_service-客服/internal-内部协同';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_base.service_type IS '服务类型(冗余存储便于快速过滤,与kb_type保持一致)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_base.access_level IS '访问级别:public-公开/private-私有/internal-内部';
|
||||
|
||||
-- 知识文档表
|
||||
DROP TABLE IF EXISTS knowledge.tb_knowledge_document CASCADE;
|
||||
CREATE TABLE knowledge.tb_knowledge_document (
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
doc_id VARCHAR(50) NOT NULL, -- 文档ID
|
||||
knowledge_id VARCHAR(50) NOT NULL, -- 所属知识库ID
|
||||
title VARCHAR(500) NOT NULL, -- 文档标题
|
||||
doc_type VARCHAR(50) NOT NULL, -- 文档类型:text-文本/pdf/word/excel/image/video
|
||||
category VARCHAR(100), -- 文档分类(自动或手动分类)
|
||||
content TEXT, -- 文档内容(文本类型)
|
||||
content_summary TEXT, -- 内容摘要(AI生成)
|
||||
file_id VARCHAR(50), -- 关联文件表ID
|
||||
file_path VARCHAR(500), -- 文件路径
|
||||
file_size BIGINT, -- 文件大小(字节)
|
||||
mime_type VARCHAR(100), -- MIME类型
|
||||
version INTEGER DEFAULT 1, -- 文档版本号(仅做记录)
|
||||
root_doc_id VARCHAR(50), -- 根文档ID(版本组标识,保留用于整体版本管理)
|
||||
tags TEXT[], -- 文档标签数组
|
||||
keywords TEXT[], -- 关键词数组(AI提取)
|
||||
embedding_status VARCHAR(20) DEFAULT 'pending', -- 向量化状态:pending-待处理/processing-处理中/completed-完成/failed-失败
|
||||
embedding_model VARCHAR(100), -- 使用的向量化模型
|
||||
chunk_count INTEGER DEFAULT 0, -- 切片数量
|
||||
metadata JSONB DEFAULT NULL, -- 文档元数据(JSON格式)
|
||||
source_url VARCHAR(500), -- 来源URL
|
||||
service_type VARCHAR(50), -- 服务类型(继承自知识库)
|
||||
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-激活/inactive-停用/archived-归档
|
||||
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
updater VARCHAR(50) DEFAULT NULL, -- 更新者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (doc_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_doc_kb ON knowledge.tb_knowledge_document(knowledge_id) WHERE deleted = false;
|
||||
CREATE INDEX idx_doc_service ON knowledge.tb_knowledge_document(service_type) WHERE deleted = false;
|
||||
CREATE INDEX idx_doc_category ON knowledge.tb_knowledge_document(category) WHERE deleted = false;
|
||||
CREATE INDEX idx_doc_embedding_status ON knowledge.tb_knowledge_document(embedding_status) WHERE deleted = false;
|
||||
CREATE INDEX idx_doc_tags ON knowledge.tb_knowledge_document USING GIN(tags) WHERE deleted = false;
|
||||
CREATE INDEX idx_doc_root ON knowledge.tb_knowledge_document(root_doc_id) WHERE deleted = false;
|
||||
|
||||
COMMENT ON TABLE knowledge.tb_knowledge_document IS '知识文档表(文档级元数据,版本控制在chunk级别)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_document.service_type IS '服务类型(从知识库继承,用于服务间隔离)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_document.version IS '文档版本号(仅做记录,实际版本控制在chunk级别)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_document.root_doc_id IS '根文档ID(用于文档整体版本管理,可选)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_document.embedding_status IS '向量化状态:pending/processing/completed/failed';
|
||||
|
||||
-- 知识文档片段表(用于RAG检索)
|
||||
DROP TABLE IF EXISTS knowledge.tb_knowledge_chunk CASCADE;
|
||||
CREATE TABLE knowledge.tb_knowledge_chunk (
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
chunk_id VARCHAR(50) NOT NULL, -- 片段ID
|
||||
doc_id VARCHAR(50) NOT NULL, -- 所属文档ID
|
||||
knowledge_id VARCHAR(50) NOT NULL, -- 所属知识库ID
|
||||
chunk_index INTEGER NOT NULL, -- 片段索引(在文档中的顺序)
|
||||
content TEXT NOT NULL, -- 片段内容
|
||||
content_length INTEGER, -- 内容长度
|
||||
embedding vector(1536), -- 向量嵌入(假设使用OpenAI 1536维)
|
||||
chunk_type VARCHAR(20) DEFAULT 'text', -- 片段类型:text-文本/table-表格/image-图片
|
||||
version INTEGER DEFAULT 1, -- chunk版本号(每次修改自动+1)
|
||||
root_chunk_id VARCHAR(50), -- 根chunk ID(同一chunk的不同版本共享此ID)
|
||||
is_current BOOLEAN DEFAULT true, -- 是否当前使用的版本
|
||||
position_info JSONB, -- 位置信息(页码、坐标等)
|
||||
metadata JSONB, -- 片段元数据
|
||||
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
creator VARCHAR(50) DEFAULT NULL, -- 创建者
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||
PRIMARY KEY (chunk_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chunk_doc ON knowledge.tb_knowledge_chunk(doc_id) WHERE deleted = false;
|
||||
CREATE INDEX idx_chunk_kb ON knowledge.tb_knowledge_chunk(knowledge_id) WHERE deleted = false;
|
||||
CREATE INDEX idx_chunk_root_current ON knowledge.tb_knowledge_chunk(root_chunk_id, is_current) WHERE deleted = false;
|
||||
CREATE INDEX idx_chunk_current ON knowledge.tb_knowledge_chunk(is_current) WHERE deleted = false AND is_current = true;
|
||||
-- 向量检索索引(需要安装pgvector扩展,建议只索引当前版本)
|
||||
-- CREATE INDEX idx_chunk_embedding ON knowledge.tb_knowledge_chunk USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100) WHERE deleted = false AND is_current = true;
|
||||
|
||||
COMMENT ON TABLE knowledge.tb_knowledge_chunk IS '知识文档片段表(RAG检索基本单位,支持chunk级版本控制)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_chunk.version IS 'chunk版本号(整数,每次修改自动+1)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_chunk.root_chunk_id IS '根chunk ID(同一chunk的所有版本共享此ID,首次创建时等于chunk_id)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_chunk.is_current IS '是否当前使用的版本(每个root_chunk_id只有一个is_current=true,RAG检索时只使用当前版本)';
|
||||
COMMENT ON COLUMN knowledge.tb_knowledge_chunk.embedding IS '向量嵌入(需要pgvector扩展,建议只为is_current=true的chunk生成)';
|
||||
|
||||
-- 知识访问日志表
|
||||
DROP TABLE IF EXISTS knowledge.tb_knowledge_access_log CASCADE;
|
||||
CREATE TABLE knowledge.tb_knowledge_access_log (
|
||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||
log_id VARCHAR(50) NOT NULL, -- 日志ID
|
||||
knowledge_id VARCHAR(50), -- 知识库ID
|
||||
doc_id VARCHAR(50), -- 文档ID
|
||||
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||
access_type VARCHAR(20) NOT NULL, -- 访问类型:view-查看/download-下载/search-搜索/edit-编辑
|
||||
query_text TEXT, -- 搜索查询文本
|
||||
result_count INTEGER, -- 搜索结果数量
|
||||
ip_address VARCHAR(45), -- IP地址
|
||||
user_agent TEXT, -- 用户代理
|
||||
dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径
|
||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||
PRIMARY KEY (log_id),
|
||||
UNIQUE (optsn)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_access_log_user ON knowledge.tb_knowledge_access_log(user_id, create_time DESC);
|
||||
CREATE INDEX idx_access_log_kb ON knowledge.tb_knowledge_access_log(knowledge_id, create_time DESC);
|
||||
|
||||
COMMENT ON TABLE knowledge.tb_knowledge_access_log IS '知识访问日志表';
|
||||
@@ -24,8 +24,8 @@
|
||||
-- 5. 配置管理模块
|
||||
\i createTableConfig.sql
|
||||
|
||||
-- 6. 知识库管理模块
|
||||
\i createTableKnowledge.sql
|
||||
-- 6. AI模块 智能体+知识库
|
||||
\i createTableAI.sql
|
||||
|
||||
-- 7. 招投标业务模块
|
||||
\i createTableBidding.sql
|
||||
@@ -33,9 +33,6 @@
|
||||
-- 8. 智能客服业务模块
|
||||
\i createTableWorkcase.sql
|
||||
|
||||
-- 9. 智能体模块(暂不启用)
|
||||
-- \i createTableAgent.sql
|
||||
|
||||
-- =============================
|
||||
-- 第二阶段:初始化基础数据
|
||||
-- =============================
|
||||
|
||||
@@ -62,6 +62,23 @@ INSERT INTO config.tb_sys_config (
|
||||
('CFG-0416', 'cfg_sms_tpl_register', 'sms.templateCode.register','注册验证码模板', 'SMS_491985030', 'String', 'input', '注册验证码模板编码', NULL, NULL, 'notify', 'mod_message', 130, 1, '注册验证码短信模板', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0417', 'cfg_sms_timeout', 'sms.timeout', '请求超时时间', '30000', 'INTEGER', 'input', '请求超时时间(毫秒)', NULL, NULL, 'notify', 'mod_message', 140, 1, 'API请求超时时间(5000-60000)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
|
||||
-- Dify AI 配置
|
||||
-- Dify 基础配置
|
||||
('CFG-0450', 'cfg_dify_api_base', 'dify.apiBaseUrl', 'Dify API地址', 'http://localhost:8000/v1', 'String', 'input', 'Dify API基础地址', NULL, NULL, 'dify', 'mod_agent', 10, 1, 'Dify服务的API基础地址,如 http://localhost/dify/api', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0452', 'cfg_dify_knowledge_key','dify.knowledgeApiKey', '知识库API密钥', 'dataset-nupqKP4LONpzdXmGthIrbjeJ', 'String', 'password', '知识库API密钥', NULL, NULL, 'dify', 'mod_agent', 30, 1, '用于访问Dify知识库的API密钥', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0453', 'cfg_dify_timeout', 'dify.timeout', '请求超时时间', '60', 'INTEGER', 'input', '请求超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 40, 1, 'API请求的超时时间(10-600秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0454', 'cfg_dify_conn_timeout','dify.connectTimeout', '连接超时时间', '10', 'INTEGER', 'input', '连接超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 50, 1, 'API连接的超时时间(5-60秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0455', 'cfg_dify_read_timeout','dify.readTimeout', '读取超时时间', '60', 'INTEGER', 'input', '读取超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 60, 1, 'API读取响应的超时时间(10-600秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0456', 'cfg_dify_stream_timeout','dify.streamTimeout', '流式响应超时时间', '300', 'INTEGER', 'input', '流式响应超时时间(秒)', NULL, NULL, 'dify', 'mod_agent', 70, 1, '流式API响应的超时时间(30-1800秒)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
|
||||
-- Dify 上传配置
|
||||
('CFG-0460', 'cfg_dify_upload_types','dify.upload.allowedTypes','允许的文件类型', 'pdf,txt,docx,doc,md,html,htm,xlsx,xls,csv', 'String', 'textarea', '上传文件允许的类型', NULL, NULL, 'dify', 'mod_agent', 80, 1, '支持上传的文件类型列表,逗号分隔', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0461', 'cfg_dify_upload_max', 'dify.upload.maxSize', '最大文件大小', '50', 'INTEGER', 'input', '最大文件大小(MB)', NULL, NULL, 'dify', 'mod_agent', 90, 1, '单个文件上传的最大大小限制(1-500MB)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
|
||||
-- Dify 知识库配置
|
||||
('CFG-0470', 'cfg_dify_index_tech', 'dify.dataset.defaultIndexingTechnique','默认索引方式', 'high_quality', 'String', 'select', '默认索引方式', NULL, '["high_quality", "economy"]'::json, 'dify', 'mod_agent', 100, 1, '知识库文档的默认索引方式:high_quality(高质量)或 economy(经济)', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0471', 'cfg_dify_embed_model', 'dify.dataset.defaultEmbeddingModel','默认Embedding模型', 'text-embedding-ada-002', 'String', 'input', '默认Embedding模型', NULL, NULL, 'dify', 'mod_agent', 110, 1, '知识库使用的默认Embedding模型名称', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
|
||||
-- 日志与审计
|
||||
('CFG-0501', 'cfg_log_level', 'log.level', '日志级别', 'INFO', 'String', 'select', '系统日志级别', NULL, '["DEBUG", "INFO", "WARN", "ERROR"]'::json, 'log', 'mod_system', 10, 0, 'DEBUG/INFO/WARN/ERROR', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
('CFG-0502', 'cfg_audit_retention', 'audit.retentionDays', '审计日志保留', '90', 'INTEGER', 'input', '审计日志保留天数', NULL, NULL, 'log', 'mod_system', 20, 0, '合规按需调整', 'system', NULL, NULL, now(), NULL, NULL, false),
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package org.xyzh.agent.client;
|
||||
|
||||
public class DifyClient {
|
||||
|
||||
}
|
||||
@@ -10,12 +10,25 @@
|
||||
</parent>
|
||||
|
||||
<groupId>org.xyzh</groupId>
|
||||
<artifactId>agent</artifactId>
|
||||
<artifactId>ai</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.xyzh.apis</groupId>
|
||||
<artifactId>api-ai</artifactId>
|
||||
<version>${urban-lifeline.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xyzh.apis</groupId>
|
||||
<artifactId>api-system</artifactId>
|
||||
<version>${urban-lifeline.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.xyzh.agent;
|
||||
package org.xyzh.ai;
|
||||
|
||||
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||
import org.slf4j.Logger;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
package org.xyzh.ai.client.callback;
|
||||
|
||||
/**
|
||||
* @description 流式响应回调接口
|
||||
* @filename StreamCallback.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
public interface StreamCallback {
|
||||
|
||||
/**
|
||||
* 接收到消息片段
|
||||
* @param message 消息内容
|
||||
*/
|
||||
void onMessage(String message);
|
||||
|
||||
/**
|
||||
* 消息结束(包含元数据)
|
||||
* @param metadata JSON格式的元数据
|
||||
*/
|
||||
void onMessageEnd(String metadata);
|
||||
|
||||
/**
|
||||
* 接收到Dify原始事件(用于转发完整事件数据)
|
||||
* @param eventType 事件类型(如workflow_started、node_started等)
|
||||
* @param eventData 完整的事件JSON数据
|
||||
*/
|
||||
default void onEvent(String eventType, String eventData) {
|
||||
// 默认实现:不处理
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式响应完成
|
||||
*/
|
||||
void onComplete();
|
||||
|
||||
/**
|
||||
* 发生错误
|
||||
* @param error 错误对象
|
||||
*/
|
||||
void onError(Throwable error);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.xyzh.api.ai.dto.DifyFileInfo;
|
||||
|
||||
/**
|
||||
* @description 对话请求
|
||||
* @filename ChatRequest.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-15
|
||||
*/
|
||||
@Data
|
||||
public class ChatRequest {
|
||||
|
||||
/**
|
||||
* 输入变量
|
||||
*/
|
||||
private Map<String, Object> inputs;
|
||||
|
||||
/**
|
||||
* 用户问题
|
||||
*/
|
||||
private String query;
|
||||
|
||||
/**
|
||||
* 响应模式:streaming(流式)、blocking(阻塞)
|
||||
*/
|
||||
@JSONField(name = "response_mode")
|
||||
private String responseMode = "streaming";
|
||||
|
||||
/**
|
||||
* 对话ID(继续对话时传入)
|
||||
*/
|
||||
@JSONField(name = "conversation_id")
|
||||
private String conversationId;
|
||||
|
||||
/**
|
||||
* 用户标识
|
||||
*/
|
||||
private String user;
|
||||
|
||||
/**
|
||||
* 上传的文件列表
|
||||
*/
|
||||
private List<DifyFileInfo> files;
|
||||
|
||||
/**
|
||||
* 自动生成标题
|
||||
*/
|
||||
@JSONField(name = "auto_generate_name")
|
||||
private Boolean autoGenerateName = true;
|
||||
|
||||
/**
|
||||
* 指定的数据集ID列表(知识库检索)
|
||||
*/
|
||||
@JSONField(name = "dataset_ids")
|
||||
private List<String> datasetIds;
|
||||
|
||||
/**
|
||||
* 温度参数(0.0-1.0)
|
||||
*/
|
||||
private Double temperature;
|
||||
|
||||
/**
|
||||
* 最大token数
|
||||
*/
|
||||
@JSONField(name = "max_tokens")
|
||||
private Integer maxTokens;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description 对话响应(阻塞模式)
|
||||
* @filename ChatResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class ChatResponse {
|
||||
|
||||
/**
|
||||
* 消息ID
|
||||
*/
|
||||
@JSONField(name = "message_id")
|
||||
private String messageId;
|
||||
|
||||
/**
|
||||
* 对话ID
|
||||
*/
|
||||
@JSONField(name = "conversation_id")
|
||||
private String conversationId;
|
||||
|
||||
/**
|
||||
* 模式
|
||||
*/
|
||||
private String mode;
|
||||
|
||||
/**
|
||||
* 回答内容
|
||||
*/
|
||||
private String answer;
|
||||
|
||||
/**
|
||||
* 元数据
|
||||
*/
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
/**
|
||||
* Token使用情况
|
||||
*/
|
||||
private Usage usage;
|
||||
|
||||
/**
|
||||
* 检索信息
|
||||
*/
|
||||
@JSONField(name = "retrieval_info")
|
||||
private List<RetrievalInfo> retrievalInfo;
|
||||
|
||||
@Data
|
||||
public static class Usage {
|
||||
@JSONField(name = "prompt_tokens")
|
||||
private Integer promptTokens;
|
||||
|
||||
@JSONField(name = "prompt_unit_price")
|
||||
private String promptUnitPrice;
|
||||
|
||||
@JSONField(name = "prompt_price_unit")
|
||||
private String promptPriceUnit;
|
||||
|
||||
@JSONField(name = "prompt_price")
|
||||
private String promptPrice;
|
||||
|
||||
@JSONField(name = "completion_tokens")
|
||||
private Integer completionTokens;
|
||||
|
||||
@JSONField(name = "completion_unit_price")
|
||||
private String completionUnitPrice;
|
||||
|
||||
@JSONField(name = "completion_price_unit")
|
||||
private String completionPriceUnit;
|
||||
|
||||
@JSONField(name = "completion_price")
|
||||
private String completionPrice;
|
||||
|
||||
@JSONField(name = "total_tokens")
|
||||
private Integer totalTokens;
|
||||
|
||||
@JSONField(name = "total_price")
|
||||
private String totalPrice;
|
||||
|
||||
private String currency;
|
||||
|
||||
private Double latency;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RetrievalInfo {
|
||||
@JSONField(name = "dataset_id")
|
||||
private String datasetId;
|
||||
|
||||
@JSONField(name = "dataset_name")
|
||||
private String datasetName;
|
||||
|
||||
@JSONField(name = "document_id")
|
||||
private String documentId;
|
||||
|
||||
@JSONField(name = "document_name")
|
||||
private String documentName;
|
||||
|
||||
@JSONField(name = "segment_id")
|
||||
private String segmentId;
|
||||
|
||||
private Double score;
|
||||
|
||||
private String content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* @description 对话列表响应
|
||||
* @filename ConversationListResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class ConversationListResponse {
|
||||
|
||||
private Integer limit;
|
||||
|
||||
@JSONField(name = "has_more")
|
||||
private Boolean hasMore;
|
||||
|
||||
private List<ConversationInfo> data;
|
||||
|
||||
@Data
|
||||
public static class ConversationInfo {
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private List<InputInfo> inputs;
|
||||
|
||||
private String status;
|
||||
|
||||
private String introduction;
|
||||
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
@JSONField(name = "updated_at")
|
||||
private Long updatedAt;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class InputInfo {
|
||||
private String key;
|
||||
private String value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 创建知识库请求
|
||||
* @filename DatasetCreateRequest.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DatasetCreateRequest {
|
||||
|
||||
/**
|
||||
* 知识库名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 知识库描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 索引方式:high_quality(高质量)、economy(经济)
|
||||
*/
|
||||
@JSONField(name = "indexing_technique")
|
||||
private String indexingTechnique = "high_quality";
|
||||
|
||||
/**
|
||||
* Embedding模型
|
||||
*/
|
||||
@JSONField(name = "embedding_model")
|
||||
private String embeddingModel;
|
||||
|
||||
/**
|
||||
* Embedding模型提供商
|
||||
*/
|
||||
@JSONField(name = "embedding_model_provider")
|
||||
private String embeddingModelProvider;
|
||||
|
||||
/**
|
||||
* 检索模型配置(包含 Rerank、Top K、Score 阈值等)
|
||||
*/
|
||||
@JSONField(name = "retrieval_model")
|
||||
private RetrievalModel retrievalModel;
|
||||
|
||||
/**
|
||||
* 权限:only_me(仅自己)、all_team_members(团队所有成员)
|
||||
*/
|
||||
private String permission = "only_me";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 创建知识库响应
|
||||
* @filename DatasetCreateResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DatasetCreateResponse {
|
||||
|
||||
/**
|
||||
* 知识库ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 知识库名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 索引方式
|
||||
*/
|
||||
@JSONField(name = "indexing_technique")
|
||||
private String indexingTechnique;
|
||||
|
||||
/**
|
||||
* Embedding模型
|
||||
*/
|
||||
@JSONField(name = "embedding_model")
|
||||
private String embeddingModel;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 知识库详情响应
|
||||
* @filename DatasetDetailResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DatasetDetailResponse {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
@JSONField(name = "indexing_technique")
|
||||
private String indexingTechnique;
|
||||
|
||||
@JSONField(name = "embedding_model")
|
||||
private String embeddingModel;
|
||||
|
||||
@JSONField(name = "embedding_model_provider")
|
||||
private String embeddingModelProvider;
|
||||
|
||||
@JSONField(name = "embedding_available")
|
||||
private Boolean embeddingAvailable;
|
||||
|
||||
@JSONField(name = "retrieval_model_dict")
|
||||
private RetrievalModelDict retrievalModelDict;
|
||||
|
||||
@JSONField(name = "document_count")
|
||||
private Integer documentCount;
|
||||
|
||||
@JSONField(name = "word_count")
|
||||
private Integer wordCount;
|
||||
|
||||
@JSONField(name = "app_count")
|
||||
private Integer appCount;
|
||||
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
@JSONField(name = "updated_at")
|
||||
private Long updatedAt;
|
||||
|
||||
@Data
|
||||
public static class RetrievalModelDict {
|
||||
@JSONField(name = "search_method")
|
||||
private String searchMethod;
|
||||
|
||||
@JSONField(name = "reranking_enable")
|
||||
private Boolean rerankingEnable;
|
||||
|
||||
@JSONField(name = "reranking_model")
|
||||
private RerankingModel rerankingModel;
|
||||
|
||||
@JSONField(name = "top_k")
|
||||
private Integer topK;
|
||||
|
||||
@JSONField(name = "score_threshold_enabled")
|
||||
private Boolean scoreThresholdEnabled;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RerankingModel {
|
||||
@JSONField(name = "reranking_provider_name")
|
||||
private String rerankingProviderName;
|
||||
|
||||
@JSONField(name = "reranking_model_name")
|
||||
private String rerankingModelName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description 知识库列表响应
|
||||
* @filename DatasetListResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DatasetListResponse {
|
||||
|
||||
/**
|
||||
* 知识库列表
|
||||
*/
|
||||
private List<DatasetInfo> data;
|
||||
|
||||
/**
|
||||
* 是否有更多
|
||||
*/
|
||||
@JSONField(name = "has_more")
|
||||
private Boolean hasMore;
|
||||
|
||||
/**
|
||||
* 分页限制
|
||||
*/
|
||||
private Integer limit;
|
||||
|
||||
/**
|
||||
* 总数
|
||||
*/
|
||||
private Integer total;
|
||||
|
||||
/**
|
||||
* 当前页
|
||||
*/
|
||||
private Integer page;
|
||||
|
||||
@Data
|
||||
public static class DatasetInfo {
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String permission;
|
||||
@JSONField(name = "document_count")
|
||||
private Integer documentCount;
|
||||
@JSONField(name = "word_count")
|
||||
private Integer wordCount;
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
@JSONField(name = "updated_at")
|
||||
private Long updatedAt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description Dify知识库更新请求
|
||||
* @filename DatasetUpdateRequest.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DatasetUpdateRequest {
|
||||
|
||||
/**
|
||||
* 知识库名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 知识库描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 索引方式(high_quality/economy)
|
||||
*/
|
||||
@JSONField(name = "indexing_technique")
|
||||
private String indexingTechnique;
|
||||
|
||||
/**
|
||||
* Embedding模型
|
||||
*/
|
||||
@JSONField(name = "embedding_model")
|
||||
private String embeddingModel;
|
||||
|
||||
/**
|
||||
* Embedding模型提供商
|
||||
*/
|
||||
@JSONField(name = "embedding_model_provider")
|
||||
private String embeddingModelProvider;
|
||||
|
||||
/**
|
||||
* 检索模型配置(包含 Rerank、Top K、Score 阈值等)
|
||||
*/
|
||||
@JSONField(name = "retrieval_model")
|
||||
private RetrievalModel retrievalModel;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description Dify文档列表响应
|
||||
* @filename DocumentListResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-07
|
||||
*/
|
||||
@Data
|
||||
public class DocumentListResponse {
|
||||
|
||||
private List<Document> data;
|
||||
|
||||
@JSONField(name = "has_more")
|
||||
private Boolean hasMore;
|
||||
|
||||
private Integer limit;
|
||||
|
||||
private Integer total;
|
||||
|
||||
private Integer page;
|
||||
|
||||
/**
|
||||
* 文档信息
|
||||
*/
|
||||
@Data
|
||||
public static class Document {
|
||||
private String id;
|
||||
|
||||
private Integer position;
|
||||
|
||||
@JSONField(name = "data_source_type")
|
||||
private String dataSourceType;
|
||||
|
||||
@JSONField(name = "data_source_info")
|
||||
private DataSourceInfo dataSourceInfo;
|
||||
|
||||
@JSONField(name = "dataset_process_rule_id")
|
||||
private String datasetProcessRuleId;
|
||||
|
||||
private String name;
|
||||
|
||||
@JSONField(name = "created_from")
|
||||
private String createdFrom;
|
||||
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
private Integer tokens;
|
||||
|
||||
@JSONField(name = "indexing_status")
|
||||
private String indexingStatus;
|
||||
|
||||
private String error;
|
||||
|
||||
private Boolean enabled;
|
||||
|
||||
@JSONField(name = "disabled_at")
|
||||
private Long disabledAt;
|
||||
|
||||
@JSONField(name = "disabled_by")
|
||||
private String disabledBy;
|
||||
|
||||
private Boolean archived;
|
||||
|
||||
@JSONField(name = "display_status")
|
||||
private String displayStatus;
|
||||
|
||||
@JSONField(name = "word_count")
|
||||
private Integer wordCount;
|
||||
|
||||
@JSONField(name = "hit_count")
|
||||
private Integer hitCount;
|
||||
|
||||
@JSONField(name = "doc_form")
|
||||
private String docForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据源信息
|
||||
*/
|
||||
@Data
|
||||
public static class DataSourceInfo {
|
||||
@JSONField(name = "upload_file_id")
|
||||
private String uploadFileId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description 文档处理状态响应
|
||||
* @filename DocumentStatusResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DocumentStatusResponse {
|
||||
|
||||
/**
|
||||
* 文档列表
|
||||
*/
|
||||
private List<DocumentStatus> data;
|
||||
|
||||
@Data
|
||||
public static class DocumentStatus {
|
||||
/**
|
||||
* 文档ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 索引状态:waiting、parsing、cleaning、splitting、indexing、completed、error
|
||||
*/
|
||||
@JSONField(name = "indexing_status")
|
||||
private String indexingStatus;
|
||||
|
||||
/**
|
||||
* 处理开始时间
|
||||
*/
|
||||
@JSONField(name = "processing_started_at")
|
||||
private Long processingStartedAt;
|
||||
|
||||
/**
|
||||
* 解析完成时间
|
||||
*/
|
||||
@JSONField(name = "parsing_completed_at")
|
||||
private Long parsingCompletedAt;
|
||||
|
||||
/**
|
||||
* 清洗完成时间
|
||||
*/
|
||||
@JSONField(name = "cleaning_completed_at")
|
||||
private Long cleaningCompletedAt;
|
||||
|
||||
/**
|
||||
* 分割完成时间
|
||||
*/
|
||||
@JSONField(name = "splitting_completed_at")
|
||||
private Long splittingCompletedAt;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
@JSONField(name = "completed_at")
|
||||
private Long completedAt;
|
||||
|
||||
/**
|
||||
* 暂停时间
|
||||
*/
|
||||
@JSONField(name = "paused_at")
|
||||
private Long pausedAt;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 停止时间
|
||||
*/
|
||||
@JSONField(name = "stopped_at")
|
||||
private Long stoppedAt;
|
||||
|
||||
/**
|
||||
* 分段数量
|
||||
*/
|
||||
@JSONField(name = "completed_segments")
|
||||
private Integer completedSegments;
|
||||
|
||||
/**
|
||||
* 总分段数
|
||||
*/
|
||||
@JSONField(name = "total_segments")
|
||||
private Integer totalSegments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 文档上传请求
|
||||
* @filename DocumentUploadRequest.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DocumentUploadRequest {
|
||||
|
||||
/**
|
||||
* 文档名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 索引方式
|
||||
*/
|
||||
@JSONField(name = "indexing_technique")
|
||||
private String indexingTechnique;
|
||||
|
||||
/**
|
||||
* 处理规则
|
||||
*/
|
||||
@JSONField(name = "process_rule")
|
||||
private ProcessRule processRule;
|
||||
|
||||
@Data
|
||||
public static class ProcessRule {
|
||||
/**
|
||||
* 分段模式:automatic(自动)、custom(自定义)
|
||||
*/
|
||||
private String mode = "automatic";
|
||||
|
||||
/**
|
||||
* 预处理规则
|
||||
*/
|
||||
private Rules rules;
|
||||
|
||||
@Data
|
||||
public static class Rules {
|
||||
/**
|
||||
* 自动分段配置
|
||||
*/
|
||||
@JSONField(name = "pre_processing_rules")
|
||||
private PreProcessingRules preProcessingRules;
|
||||
|
||||
/**
|
||||
* 分段配置
|
||||
*/
|
||||
private Segmentation segmentation;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PreProcessingRules {
|
||||
/**
|
||||
* 移除额外空格
|
||||
*/
|
||||
@JSONField(name = "remove_extra_spaces")
|
||||
private Boolean removeExtraSpaces = true;
|
||||
|
||||
/**
|
||||
* 移除URL和邮箱
|
||||
*/
|
||||
@JSONField(name = "remove_urls_emails")
|
||||
private Boolean removeUrlsEmails = false;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Segmentation {
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
private String separator = "\\n";
|
||||
|
||||
/**
|
||||
* 最大分段长度
|
||||
*/
|
||||
@JSONField(name = "max_tokens")
|
||||
private Integer maxTokens = 1000;
|
||||
|
||||
/**
|
||||
* 分段重叠长度
|
||||
*/
|
||||
@JSONField(name = "chunk_overlap")
|
||||
private Integer chunkOverlap = 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 文档上传响应(根据 Dify API 返回结构)
|
||||
* @filename DocumentUploadResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class DocumentUploadResponse {
|
||||
|
||||
/**
|
||||
* 文档详细信息
|
||||
*/
|
||||
private Document document;
|
||||
|
||||
/**
|
||||
* 批次ID(用于查询处理状态)
|
||||
*/
|
||||
private String batch;
|
||||
|
||||
/**
|
||||
* 文档详细信息
|
||||
*/
|
||||
@Data
|
||||
public static class Document {
|
||||
/**
|
||||
* 文档ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 文档名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 位置(序号)
|
||||
*/
|
||||
private Integer position;
|
||||
|
||||
/**
|
||||
* 数据源类型
|
||||
*/
|
||||
@JSONField(name = "data_source_type")
|
||||
private String dataSourceType;
|
||||
|
||||
/**
|
||||
* 数据源信息
|
||||
*/
|
||||
@JSONField(name = "data_source_info")
|
||||
private Object dataSourceInfo;
|
||||
|
||||
/**
|
||||
* 数据集处理规则ID
|
||||
*/
|
||||
@JSONField(name = "dataset_process_rule_id")
|
||||
private String datasetProcessRuleId;
|
||||
|
||||
/**
|
||||
* 创建来源
|
||||
*/
|
||||
@JSONField(name = "created_from")
|
||||
private String createdFrom;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
* 创建时间(时间戳)
|
||||
*/
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
/**
|
||||
* Token数量
|
||||
*/
|
||||
private Integer tokens;
|
||||
|
||||
/**
|
||||
* 索引状态
|
||||
*/
|
||||
@JSONField(name = "indexing_status")
|
||||
private String indexingStatus;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 禁用时间
|
||||
*/
|
||||
@JSONField(name = "disabled_at")
|
||||
private Long disabledAt;
|
||||
|
||||
/**
|
||||
* 禁用人
|
||||
*/
|
||||
@JSONField(name = "disabled_by")
|
||||
private String disabledBy;
|
||||
|
||||
/**
|
||||
* 是否归档
|
||||
*/
|
||||
private Boolean archived;
|
||||
|
||||
/**
|
||||
* 显示状态
|
||||
*/
|
||||
@JSONField(name = "display_status")
|
||||
private String displayStatus;
|
||||
|
||||
/**
|
||||
* 字数
|
||||
*/
|
||||
@JSONField(name = "word_count")
|
||||
private Integer wordCount;
|
||||
|
||||
/**
|
||||
* 命中次数
|
||||
*/
|
||||
@JSONField(name = "hit_count")
|
||||
private Integer hitCount;
|
||||
|
||||
/**
|
||||
* 文档形式
|
||||
*/
|
||||
@JSONField(name = "doc_form")
|
||||
private String docForm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description Dify嵌入模型响应
|
||||
* @filename EmbeddingModelResponse.java
|
||||
* @author AI Assistant
|
||||
* @since 2025-11-06
|
||||
*/
|
||||
@Data
|
||||
public class EmbeddingModelResponse {
|
||||
|
||||
/**
|
||||
* 模型提供商列表
|
||||
*/
|
||||
@JSONField(name = "data")
|
||||
private List<ModelProvider> data;
|
||||
|
||||
/**
|
||||
* 模型提供商
|
||||
*/
|
||||
@Data
|
||||
public static class ModelProvider {
|
||||
/**
|
||||
* 提供商标识
|
||||
*/
|
||||
@JSONField(name = "provider")
|
||||
private String provider;
|
||||
|
||||
/**
|
||||
* 提供商标签
|
||||
*/
|
||||
@JSONField(name = "label")
|
||||
private Map<String, String> label;
|
||||
|
||||
/**
|
||||
* 小图标
|
||||
*/
|
||||
@JSONField(name = "icon_small")
|
||||
private Map<String, String> iconSmall;
|
||||
|
||||
/**
|
||||
* 大图标
|
||||
*/
|
||||
@JSONField(name = "icon_large")
|
||||
private Map<String, String> iconLarge;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JSONField(name = "status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 模型列表
|
||||
*/
|
||||
@JSONField(name = "models")
|
||||
private List<Model> models;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型详情
|
||||
*/
|
||||
@Data
|
||||
public static class Model {
|
||||
/**
|
||||
* 模型名称
|
||||
*/
|
||||
@JSONField(name = "model")
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 模型标签
|
||||
*/
|
||||
@JSONField(name = "label")
|
||||
private Map<String, String> label;
|
||||
|
||||
/**
|
||||
* 模型类型
|
||||
*/
|
||||
@JSONField(name = "model_type")
|
||||
private String modelType;
|
||||
|
||||
/**
|
||||
* 特性列表
|
||||
*/
|
||||
@JSONField(name = "features")
|
||||
private List<Object> features;
|
||||
|
||||
/**
|
||||
* 获取来源
|
||||
*/
|
||||
@JSONField(name = "fetch_from")
|
||||
private String fetchFrom;
|
||||
|
||||
/**
|
||||
* 模型属性
|
||||
*/
|
||||
@JSONField(name = "model_properties")
|
||||
private ModelProperties modelProperties;
|
||||
|
||||
/**
|
||||
* 是否已弃用
|
||||
*/
|
||||
@JSONField(name = "deprecated")
|
||||
private Boolean deprecated;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JSONField(name = "status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 是否启用负载均衡
|
||||
*/
|
||||
@JSONField(name = "load_balancing_enabled")
|
||||
private Boolean loadBalancingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型属性
|
||||
*/
|
||||
@Data
|
||||
public static class ModelProperties {
|
||||
/**
|
||||
* 上下文大小
|
||||
*/
|
||||
@JSONField(name = "context_size")
|
||||
private Integer contextSize;
|
||||
|
||||
/**
|
||||
* 最大分块数
|
||||
*/
|
||||
@JSONField(name = "max_chunks")
|
||||
private Integer maxChunks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description 消息历史响应
|
||||
* @filename MessageHistoryResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class MessageHistoryResponse {
|
||||
|
||||
private Integer limit;
|
||||
|
||||
@JSONField(name = "has_more")
|
||||
private Boolean hasMore;
|
||||
|
||||
private List<MessageInfo> data;
|
||||
|
||||
@Data
|
||||
public static class MessageInfo {
|
||||
private String id;
|
||||
|
||||
@JSONField(name = "conversation_id")
|
||||
private String conversationId;
|
||||
|
||||
private List<MessageContent> inputs;
|
||||
|
||||
private String query;
|
||||
|
||||
private String answer;
|
||||
|
||||
@JSONField(name = "message_files")
|
||||
private List<MessageFile> messageFiles;
|
||||
|
||||
private Feedback feedback;
|
||||
|
||||
@JSONField(name = "retriever_resources")
|
||||
private List<RetrieverResource> retrieverResources;
|
||||
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
@JSONField(name = "agent_thoughts")
|
||||
private List<Object> agentThoughts;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MessageContent {
|
||||
private String key;
|
||||
private String value;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MessageFile {
|
||||
private String id;
|
||||
private String type;
|
||||
private String url;
|
||||
@JSONField(name = "belongs_to")
|
||||
private String belongsTo;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Feedback {
|
||||
private String rating;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RetrieverResource {
|
||||
@JSONField(name = "dataset_id")
|
||||
private String datasetId;
|
||||
|
||||
@JSONField(name = "dataset_name")
|
||||
private String datasetName;
|
||||
|
||||
@JSONField(name = "document_id")
|
||||
private String documentId;
|
||||
|
||||
@JSONField(name = "document_name")
|
||||
private String documentName;
|
||||
|
||||
@JSONField(name = "segment_id")
|
||||
private String segmentId;
|
||||
|
||||
private Double score;
|
||||
|
||||
private String content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description Dify Rerank模型响应
|
||||
* @filename RerankModelResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-06
|
||||
*/
|
||||
@Data
|
||||
public class RerankModelResponse {
|
||||
private List<ModelProvider> data;
|
||||
|
||||
@Data
|
||||
public static class ModelProvider {
|
||||
private String provider;
|
||||
private Map<String, String> label; // e.g., {"en_US": "Cohere", "zh_Hans": "Cohere"}
|
||||
@JSONField(name = "icon_small")
|
||||
private String iconSmall;
|
||||
@JSONField(name = "icon_large")
|
||||
private String iconLarge;
|
||||
private String status; // e.g., "active"
|
||||
private List<Model> models;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Model {
|
||||
private String model; // e.g., "rerank-multilingual-v3.0"
|
||||
private Map<String, String> label;
|
||||
@JSONField(name = "model_type")
|
||||
private String modelType; // e.g., "rerank"
|
||||
private List<String> features;
|
||||
@JSONField(name = "fetch_from")
|
||||
private String fetchFrom;
|
||||
@JSONField(name = "model_properties")
|
||||
private ModelProperties modelProperties;
|
||||
private Boolean deprecated;
|
||||
private String status; // e.g., "active"
|
||||
private String provider; // 模型提供商(可能在 model 数据中)
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ModelProperties {
|
||||
@JSONField(name = "context_size")
|
||||
private Integer contextSize;
|
||||
@JSONField(name = "max_chunks")
|
||||
private Integer maxChunks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description Dify检索模型配置(Retrieval Model)
|
||||
* @filename RetrievalModel.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-06
|
||||
*/
|
||||
@Data
|
||||
public class RetrievalModel {
|
||||
|
||||
/**
|
||||
* 搜索方法:vector_search(向量搜索)、full_text_search(全文搜索)、hybrid_search(混合搜索)
|
||||
*/
|
||||
@JSONField(name = "search_method")
|
||||
private String searchMethod;
|
||||
|
||||
/**
|
||||
* Rerank是否启用
|
||||
*/
|
||||
@JSONField(name = "reranking_enable")
|
||||
private Boolean rerankingEnable;
|
||||
|
||||
/**
|
||||
* Rerank模式(字符串,值为 "reranking_model")
|
||||
*/
|
||||
@JSONField(name = "reranking_mode")
|
||||
private String rerankingMode;
|
||||
|
||||
/**
|
||||
* Rerank模型配置(当 reranking_enable=true 时必须设置)
|
||||
*/
|
||||
@JSONField(name = "reranking_model")
|
||||
private RerankingModel rerankingModel;
|
||||
|
||||
/**
|
||||
* Top K(返回前K个结果)
|
||||
*/
|
||||
@JSONField(name = "top_k")
|
||||
private Integer topK;
|
||||
|
||||
/**
|
||||
* 分数阈值(0.00-1.00)
|
||||
*/
|
||||
@JSONField(name = "score_threshold")
|
||||
private Double scoreThreshold;
|
||||
|
||||
/**
|
||||
* 是否启用分数阈值
|
||||
*/
|
||||
@JSONField(name = "score_threshold_enabled")
|
||||
private Boolean scoreThresholdEnabled;
|
||||
|
||||
/**
|
||||
* Rerank模型配置(嵌套对象)
|
||||
*/
|
||||
@Data
|
||||
public static class RerankingModel {
|
||||
/**
|
||||
* Rerank模型提供商
|
||||
*/
|
||||
@JSONField(name = "reranking_provider_name")
|
||||
private String rerankingProviderName;
|
||||
|
||||
/**
|
||||
* Rerank模型名称
|
||||
*/
|
||||
@JSONField(name = "reranking_model_name")
|
||||
private String rerankingModelName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description 知识库检索请求
|
||||
* @filename RetrievalRequest.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class RetrievalRequest {
|
||||
|
||||
/**
|
||||
* 查询文本
|
||||
*/
|
||||
private String query;
|
||||
|
||||
/**
|
||||
* 返回的最相关结果数量
|
||||
*/
|
||||
@JSONField(name = "top_k")
|
||||
private Integer topK = 3;
|
||||
|
||||
/**
|
||||
* 相似度阈值(0-1)
|
||||
*/
|
||||
@JSONField(name = "score_threshold")
|
||||
private Double scoreThreshold = 0.7;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.xyzh.ai.client.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description 知识库检索响应
|
||||
* @filename RetrievalResponse.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Data
|
||||
public class RetrievalResponse {
|
||||
|
||||
/**
|
||||
* 查询ID
|
||||
*/
|
||||
@JSONField(name = "query_id")
|
||||
private String queryId;
|
||||
|
||||
/**
|
||||
* 检索结果列表
|
||||
*/
|
||||
private List<RetrievalRecord> records;
|
||||
|
||||
@Data
|
||||
public static class RetrievalRecord {
|
||||
/**
|
||||
* 分段内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 相似度分数
|
||||
*/
|
||||
private Double score;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 元数据
|
||||
*/
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* 文档ID
|
||||
*/
|
||||
@JSONField(name = "document_id")
|
||||
private String documentId;
|
||||
|
||||
/**
|
||||
* 文档名称
|
||||
*/
|
||||
@JSONField(name = "document_name")
|
||||
private String documentName;
|
||||
|
||||
/**
|
||||
* 分段ID
|
||||
*/
|
||||
@JSONField(name = "segment_id")
|
||||
private String segmentId;
|
||||
|
||||
/**
|
||||
* 分段位置
|
||||
*/
|
||||
@JSONField(name = "segment_position")
|
||||
private Integer segmentPosition;
|
||||
|
||||
/**
|
||||
* 索引节点ID
|
||||
*/
|
||||
@JSONField(name = "index_node_id")
|
||||
private String indexNodeId;
|
||||
|
||||
/**
|
||||
* 索引节点哈希
|
||||
*/
|
||||
@JSONField(name = "index_node_hash")
|
||||
private String indexNodeHash;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
package org.xyzh.ai.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.xyzh.api.system.service.SysConfigService;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @description Dify配置类
|
||||
* @filename DifyConfig.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
@Configuration
|
||||
public class DifyConfig {
|
||||
|
||||
@Autowired
|
||||
private SysConfigService sysConfigService;
|
||||
|
||||
/**
|
||||
* Dify API基础地址
|
||||
*/
|
||||
private String apiBaseUrl = "http://192.168.130.131/v1";
|
||||
|
||||
private String knowledgeApiKey="dataset-nupqKP4LONpzdXmGthIrbjeJ";
|
||||
|
||||
/**
|
||||
* 请求超时时间(秒)
|
||||
*/
|
||||
private Integer timeout = 60;
|
||||
|
||||
/**
|
||||
* 连接超时时间(秒)
|
||||
*/
|
||||
private Integer connectTimeout = 10;
|
||||
|
||||
/**
|
||||
* 读取超时时间(秒)
|
||||
*/
|
||||
private Integer readTimeout = 60;
|
||||
|
||||
/**
|
||||
* 流式响应超时时间(秒)
|
||||
*/
|
||||
private Integer streamTimeout = 300;
|
||||
|
||||
/**
|
||||
* 上传文件配置
|
||||
*/
|
||||
private Upload upload = new Upload();
|
||||
|
||||
/**
|
||||
* 知识库配置
|
||||
*/
|
||||
private Dataset dataset = new Dataset();
|
||||
|
||||
/**
|
||||
* 初始化配置,从数据库加载
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
log.info("开始从数据库加载Dify配置...");
|
||||
|
||||
// 基础配置
|
||||
loadStringConfig("dify.apiBaseUrl", val -> this.apiBaseUrl = val);
|
||||
loadStringConfig("dify.knowledgeApiKey", val -> this.knowledgeApiKey = val);
|
||||
loadIntegerConfig("dify.timeout", val -> this.timeout = val);
|
||||
loadIntegerConfig("dify.connectTimeout", val -> this.connectTimeout = val);
|
||||
loadIntegerConfig("dify.readTimeout", val -> this.readTimeout = val);
|
||||
loadIntegerConfig("dify.streamTimeout", val -> this.streamTimeout = val);
|
||||
|
||||
// Upload配置
|
||||
loadStringConfig("dify.upload.allowedTypes", val -> {
|
||||
if (val != null && !val.trim().isEmpty()) {
|
||||
this.upload.allowedTypes = val.split(",");
|
||||
}
|
||||
});
|
||||
loadIntegerConfig("dify.upload.maxSize", val -> this.upload.maxSize = val);
|
||||
|
||||
// Dataset配置
|
||||
loadStringConfig("dify.dataset.defaultIndexingTechnique", val -> this.dataset.defaultIndexingTechnique = val);
|
||||
loadStringConfig("dify.dataset.defaultEmbeddingModel", val -> this.dataset.defaultEmbeddingModel = val);
|
||||
|
||||
log.info("Dify配置加载完成 - API地址: {}", apiBaseUrl);
|
||||
} catch (Exception e) {
|
||||
log.error("加载Dify配置失败,将使用默认值", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载字符串配置
|
||||
*/
|
||||
private void loadStringConfig(String key, java.util.function.Consumer<String> setter) {
|
||||
try {
|
||||
String value = sysConfigService.getStringConfig(key);
|
||||
if (value != null && !value.trim().isEmpty()) {
|
||||
setter.accept(value);
|
||||
log.debug("加载配置: {} = {}", key, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("加载配置失败: {}, 错误: {}", key, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载整数配置
|
||||
*/
|
||||
private void loadIntegerConfig(String key, java.util.function.Consumer<Integer> setter) {
|
||||
try {
|
||||
Integer value = sysConfigService.getIntConfig(key);
|
||||
if (value != null) {
|
||||
setter.accept(value);
|
||||
log.debug("加载配置: {} = {}", key, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("加载配置失败: {}, 错误: {}", key, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Upload {
|
||||
/**
|
||||
* 支持的文件类型
|
||||
*/
|
||||
private String[] allowedTypes = {"pdf", "txt", "docx", "doc", "md", "html", "htm"};
|
||||
|
||||
/**
|
||||
* 最大文件大小(MB)
|
||||
*/
|
||||
private Integer maxSize = 50;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Dataset {
|
||||
/**
|
||||
* 默认索引方式(high_quality/economy)
|
||||
*/
|
||||
private String defaultIndexingTechnique = "high_quality";
|
||||
|
||||
/**
|
||||
* 默认Embedding模型
|
||||
*/
|
||||
private String defaultEmbeddingModel = "text-embedding-ada-002";
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证配置是否有效
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return apiBaseUrl != null && !apiBaseUrl.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的API URL
|
||||
*/
|
||||
public String getFullApiUrl(String endpoint) {
|
||||
String baseUrl = apiBaseUrl.endsWith("/") ? apiBaseUrl.substring(0, apiBaseUrl.length() - 1) : apiBaseUrl;
|
||||
String path = endpoint.startsWith("/") ? endpoint : "/" + endpoint;
|
||||
return baseUrl + path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.xyzh.ai.exception;
|
||||
|
||||
/**
|
||||
* @description Dify API调用异常
|
||||
* @filename DifyException.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-04
|
||||
*/
|
||||
public class DifyException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer code;
|
||||
|
||||
public DifyException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DifyException(Integer code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public DifyException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public DifyException(Integer code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.xyzh.api.agent.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* 知识库DTO
|
||||
* 用于创建和更新知识库
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识库DTO")
|
||||
public class KnowledgeBaseDTO extends BaseDTO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "知识库ID(更新时需要)")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "智能体ID")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "知识库名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "知识库类型:bidding-招投标/customer_service-客服/internal-内部协同")
|
||||
private String kbType;
|
||||
|
||||
@Schema(description = "访问级别:public-公开/private-私有/internal-内部")
|
||||
private String accessLevel;
|
||||
|
||||
@Schema(description = "知识库描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "存储路径")
|
||||
private String storagePath;
|
||||
|
||||
@Schema(description = "当前版本号")
|
||||
private String version;
|
||||
|
||||
@Schema(description = "知识库配置")
|
||||
private JsonNode config;
|
||||
|
||||
@Schema(description = "服务类型")
|
||||
private String serviceType;
|
||||
|
||||
@Schema(description = "状态:active-激活/inactive-停用/archived-归档")
|
||||
private String status;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.xyzh.api.agent.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* 知识文档片段DTO
|
||||
* 用于创建和更新知识文档片段
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识文档片段DTO")
|
||||
public class KnowledgeChunkDTO extends BaseDTO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "片段ID(更新时需要)")
|
||||
private String chunkId;
|
||||
|
||||
@Schema(description = "所属文档ID")
|
||||
private String docId;
|
||||
|
||||
@Schema(description = "所属知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "片段索引")
|
||||
private Integer chunkIndex;
|
||||
|
||||
@Schema(description = "片段内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "片段类型:text-文本/table-表格/image-图片")
|
||||
private String chunkType;
|
||||
|
||||
@Schema(description = "根chunk ID")
|
||||
private String rootChunkId;
|
||||
|
||||
@Schema(description = "是否当前版本", defaultValue = "true")
|
||||
private Boolean isCurrent;
|
||||
|
||||
@Schema(description = "位置信息")
|
||||
private JsonNode positionInfo;
|
||||
|
||||
@Schema(description = "片段元数据")
|
||||
private JsonNode metadata;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.xyzh.api.agent.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 知识文档DTO
|
||||
* 用于创建和更新知识文档
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识文档DTO")
|
||||
public class KnowledgeDocumentDTO extends BaseDTO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "文档ID(更新时需要)")
|
||||
private String docId;
|
||||
|
||||
@Schema(description = "所属知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "文档标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档类型:text-文本/pdf/word/excel/image/video")
|
||||
private String docType;
|
||||
|
||||
@Schema(description = "文档分类")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "文档内容(文本类型)")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "关联文件ID")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件路径")
|
||||
private String filePath;
|
||||
|
||||
@Schema(description = "文件大小")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "MIME类型")
|
||||
private String mimeType;
|
||||
|
||||
@Schema(description = "根文档ID")
|
||||
private String rootDocId;
|
||||
|
||||
@Schema(description = "文档标签")
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "来源URL")
|
||||
private String sourceUrl;
|
||||
|
||||
@Schema(description = "服务类型")
|
||||
private String serviceType;
|
||||
|
||||
@Schema(description = "文档元数据")
|
||||
private JsonNode metadata;
|
||||
|
||||
@Schema(description = "状态:active-激活/inactive-停用/archived-归档")
|
||||
private String status;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package org.xyzh.api.agent.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.vo.BaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 知识库VO
|
||||
* 用于前端展示知识库信息
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识库VO")
|
||||
public class KnowledgeBaseVO extends BaseVO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "智能体ID")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "智能体名称")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "知识库名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "知识库类型")
|
||||
private String kbType;
|
||||
|
||||
@Schema(description = "知识库类型名称")
|
||||
private String kbTypeName;
|
||||
|
||||
@Schema(description = "访问级别")
|
||||
private String accessLevel;
|
||||
|
||||
@Schema(description = "访问级别名称")
|
||||
private String accessLevelName;
|
||||
|
||||
@Schema(description = "知识库描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "存储路径")
|
||||
private String storagePath;
|
||||
|
||||
@Schema(description = "当前版本号")
|
||||
private String version;
|
||||
|
||||
@Schema(description = "知识库配置")
|
||||
private JsonNode config;
|
||||
|
||||
@Schema(description = "服务类型")
|
||||
private String serviceType;
|
||||
|
||||
@Schema(description = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "状态名称")
|
||||
private String statusName;
|
||||
|
||||
@Schema(description = "状态颜色")
|
||||
private String statusColor;
|
||||
|
||||
@Schema(description = "文档总数")
|
||||
private Long documentCount;
|
||||
|
||||
@Schema(description = "已向量化文档数")
|
||||
private Long embeddedDocCount;
|
||||
|
||||
@Schema(description = "chunk总数")
|
||||
private Long chunkCount;
|
||||
|
||||
@Schema(description = "总存储大小(字节)")
|
||||
private Long totalSize;
|
||||
|
||||
@Schema(description = "总存储大小格式化显示")
|
||||
private String totalSizeFormatted;
|
||||
|
||||
@Schema(description = "最后同步时间", format = "date-time")
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date lastSyncTime;
|
||||
|
||||
@Schema(description = "创建者姓名")
|
||||
private String creatorName;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package org.xyzh.api.agent.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.vo.BaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 知识文档片段VO
|
||||
* 用于前端展示知识文档片段信息
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识文档片段VO")
|
||||
public class KnowledgeChunkVO extends BaseVO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "片段ID")
|
||||
private String chunkId;
|
||||
|
||||
@Schema(description = "所属文档ID")
|
||||
private String docId;
|
||||
|
||||
@Schema(description = "文档标题")
|
||||
private String docTitle;
|
||||
|
||||
@Schema(description = "所属知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "知识库名称")
|
||||
private String knowledgeName;
|
||||
|
||||
@Schema(description = "片段索引")
|
||||
private Integer chunkIndex;
|
||||
|
||||
@Schema(description = "片段内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "内容长度")
|
||||
private Integer contentLength;
|
||||
|
||||
@Schema(description = "片段类型")
|
||||
private String chunkType;
|
||||
|
||||
@Schema(description = "片段类型名称")
|
||||
private String chunkTypeName;
|
||||
|
||||
@Schema(description = "版本号")
|
||||
private Integer version;
|
||||
|
||||
@Schema(description = "根chunk ID")
|
||||
private String rootChunkId;
|
||||
|
||||
@Schema(description = "是否当前版本", defaultValue = "false")
|
||||
private Boolean isCurrent;
|
||||
|
||||
@Schema(description = "位置信息")
|
||||
private JsonNode positionInfo;
|
||||
|
||||
@Schema(description = "片段元数据")
|
||||
private JsonNode metadata;
|
||||
|
||||
@Schema(description = "部门名称")
|
||||
private String deptName;
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package org.xyzh.api.agent.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.xyzh.common.vo.BaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 知识文档VO
|
||||
* 用于前端展示知识文档信息
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识文档VO")
|
||||
public class KnowledgeDocumentVO extends BaseVO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "文档ID")
|
||||
private String docId;
|
||||
|
||||
@Schema(description = "所属知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "知识库名称")
|
||||
private String knowledgeName;
|
||||
|
||||
@Schema(description = "文档标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档类型")
|
||||
private String docType;
|
||||
|
||||
@Schema(description = "文档类型名称")
|
||||
private String docTypeName;
|
||||
|
||||
@Schema(description = "文档分类")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "文档内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "内容摘要")
|
||||
private String contentSummary;
|
||||
|
||||
@Schema(description = "关联文件ID")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件路径")
|
||||
private String filePath;
|
||||
|
||||
@Schema(description = "文件下载URL")
|
||||
private String fileUrl;
|
||||
|
||||
@Schema(description = "文件大小")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "文件大小格式化显示")
|
||||
private String fileSizeFormatted;
|
||||
|
||||
@Schema(description = "MIME类型")
|
||||
private String mimeType;
|
||||
|
||||
@Schema(description = "版本号")
|
||||
private Integer version;
|
||||
|
||||
@Schema(description = "根文档ID")
|
||||
private String rootDocId;
|
||||
|
||||
@Schema(description = "文档标签")
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "关键词")
|
||||
private List<String> keywords;
|
||||
|
||||
@Schema(description = "向量化状态")
|
||||
private String embeddingStatus;
|
||||
|
||||
@Schema(description = "向量化状态名称")
|
||||
private String embeddingStatusName;
|
||||
|
||||
@Schema(description = "使用的向量化模型")
|
||||
private String embeddingModel;
|
||||
|
||||
@Schema(description = "切片数量")
|
||||
private Integer chunkCount;
|
||||
|
||||
@Schema(description = "文档元数据")
|
||||
private JsonNode metadata;
|
||||
|
||||
@Schema(description = "来源URL")
|
||||
private String sourceUrl;
|
||||
|
||||
@Schema(description = "服务类型")
|
||||
private String serviceType;
|
||||
|
||||
@Schema(description = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "状态名称")
|
||||
private String statusName;
|
||||
|
||||
@Schema(description = "创建者姓名")
|
||||
private String creatorName;
|
||||
|
||||
@Schema(description = "更新者姓名")
|
||||
private String updaterName;
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.xyzh</groupId>
|
||||
<artifactId>api-agent</artifactId>
|
||||
<groupId>org.xyzh.apis</groupId>
|
||||
<artifactId>api-ai</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<properties>
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.xyzh.api.agent;
|
||||
package org.xyzh.api.ai;
|
||||
|
||||
/**
|
||||
* Agent服务接口
|
||||
@@ -0,0 +1,99 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @description Dify文件信息(用于对话文件上传和请求)
|
||||
* @filename DifyFileInfo.java
|
||||
* @author AI Assistant
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-15
|
||||
*/
|
||||
@Data
|
||||
public class DifyFileInfo {
|
||||
/**
|
||||
* 文件ID(Dify返回)
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 文件大小(字节)
|
||||
*/
|
||||
private Integer size;
|
||||
|
||||
/**
|
||||
* 文件扩展名
|
||||
*/
|
||||
private String extension;
|
||||
|
||||
/**
|
||||
* 文件MIME类型
|
||||
*/
|
||||
@JSONField(name = "mime_type")
|
||||
private String mimeType;
|
||||
|
||||
/**
|
||||
* 上传人ID
|
||||
*/
|
||||
@JSONField(name = "created_by")
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
* 上传时间(时间戳)
|
||||
*/
|
||||
@JSONField(name = "created_at")
|
||||
private Long createdAt;
|
||||
|
||||
/**
|
||||
* 预览URL
|
||||
*/
|
||||
@JSONField(name = "preview_url")
|
||||
private String previewUrl;
|
||||
|
||||
/**
|
||||
* 源文件URL
|
||||
*/
|
||||
@JSONField(name = "source_url")
|
||||
private String sourceUrl;
|
||||
|
||||
/**
|
||||
* 文件类型:image、document、audio、video、file
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 传输方式:remote_url、local_file
|
||||
*/
|
||||
@JSONField(name = "transfer_method")
|
||||
private String transferMethod;
|
||||
|
||||
/**
|
||||
* 文件URL或ID
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 本地文件上传ID
|
||||
*/
|
||||
@JSONField(name = "upload_file_id")
|
||||
private String uploadFileId;
|
||||
|
||||
/**
|
||||
* 系统文件ID
|
||||
*/
|
||||
@JSONField(name = "sys_file_id")
|
||||
private String sysFileId;
|
||||
|
||||
/**
|
||||
* 文件路径(从系统文件表获取)
|
||||
*/
|
||||
@JSONField(name = "file_path")
|
||||
private String filePath;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "智能体提示卡")
|
||||
public class PromptCard {
|
||||
@Schema(description = "文件ID")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "提示词")
|
||||
private String prompt;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "系统文件DTO")
|
||||
public class TbAgent extends BaseDTO{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "智能体ID")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "智能体名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "智能体描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "智能体url")
|
||||
private String link;
|
||||
|
||||
@Schema(description = "智能体APIKEY")
|
||||
private String apiKey;
|
||||
|
||||
@Schema(description = "引导词")
|
||||
private String introduce;
|
||||
|
||||
@Schema(description = "提示卡片数组")
|
||||
private List<PromptCard> promptCards;
|
||||
|
||||
@Schema(description = "分类")
|
||||
private String category;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "AI智能体对话")
|
||||
public class TbChat extends BaseDTO{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "对话ID")
|
||||
private String chatId;
|
||||
|
||||
@Schema(description = "智能体ID")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private String userId;
|
||||
|
||||
@Schema(description = "对话标题")
|
||||
private String title;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "AI智能体对话消息")
|
||||
public class TbChatMessage extends BaseDTO{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "消息ID")
|
||||
private String messageId;
|
||||
|
||||
@Schema(description = "对话ID")
|
||||
private String chatId;
|
||||
|
||||
@Schema(description = "角色")
|
||||
private String role;
|
||||
|
||||
@Schema(description = "内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "文件ID数组")
|
||||
private List<String> files;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "知识库配置")
|
||||
public class TbKnowledge extends BaseDTO{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "知识库标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "知识库头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "知识库描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "Dify知识库ID(Dataset ID)")
|
||||
private String difyDatasetId;
|
||||
|
||||
@Schema(description = "Dify索引方式(high_quality/economy)")
|
||||
private String difyIndexingTechnique;
|
||||
|
||||
@Schema(description = "向量模型名称")
|
||||
private String embeddingModel;
|
||||
|
||||
@Schema(description = "向量模型提供商")
|
||||
private String embeddingModelProvider;
|
||||
|
||||
@Schema(description = "Rerank模型名称")
|
||||
private String rerankModel;
|
||||
|
||||
@Schema(description = "Rerank模型提供商")
|
||||
private String rerankModelProvider;
|
||||
|
||||
@Schema(description = "是否启用Rerank(0否 1是)")
|
||||
private Integer rerankingEnable;
|
||||
|
||||
@Schema(description = "检索Top K(返回前K个结果)")
|
||||
private Integer retrievalTopK;
|
||||
|
||||
@Schema(description = "检索分数阈值(0.00-1.00)")
|
||||
private Double retrievalScoreThreshold;
|
||||
|
||||
@Schema(description = "文档数量")
|
||||
private Integer documentCount;
|
||||
|
||||
@Schema(description = "总分段数")
|
||||
private Integer totalChunks;
|
||||
|
||||
@Schema(description = "所属服务 workcase、bidding")
|
||||
private String service;
|
||||
|
||||
@Schema(description = "bidding所属项目ID")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "所属分类 workcase 内部知识库、外部知识库")
|
||||
private String category;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.xyzh.api.ai.dto;
|
||||
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "知识库文件")
|
||||
public class TbKnowledgeFile extends BaseDTO{
|
||||
private final static long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "文件ID")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件根ID")
|
||||
private String fileRootId;
|
||||
|
||||
@Schema(description = "Dify文件ID")
|
||||
private String difyFileId;
|
||||
|
||||
@Schema(description = "文件版本")
|
||||
private String version;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.xyzh.api.ai.vo;
|
||||
|
||||
import org.xyzh.common.vo.BaseVO;
|
||||
|
||||
import lombok.Data;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Data
|
||||
@Schema(description = "智能体VO")
|
||||
public class AgentVO extends BaseVO{
|
||||
|
||||
}
|
||||
@@ -22,6 +22,12 @@ public class TbSysFileDTO extends BaseDTO {
|
||||
@Schema(description = "文件ID (主键)")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件根ID")
|
||||
private String fileRootId;
|
||||
|
||||
@Schema(description = "文件版本")
|
||||
private String version;
|
||||
|
||||
@Schema(description = "文件名")
|
||||
private String name;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<module>api-log</module>
|
||||
<module>api-system</module>
|
||||
<module>api-crontab</module>
|
||||
<module>api-agent</module>
|
||||
<module>api-ai</module>
|
||||
<module>api-bidding</module>
|
||||
<module>api-platform</module>
|
||||
<module>api-workcase</module>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.xyzh.common.utils.json;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description PostgreSQL VARCHAR数组类型处理器
|
||||
* @filename StringArrayTypeHandler.java
|
||||
* @author yslg
|
||||
* @copyright yslg
|
||||
* @since 2025-12-15
|
||||
*/
|
||||
@MappedTypes({List.class})
|
||||
public class StringArrayTypeHandler extends BaseTypeHandler<List<String>> {
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
|
||||
if (parameter == null || parameter.isEmpty()) {
|
||||
ps.setArray(i, null);
|
||||
} else {
|
||||
ps.setArray(i, ps.getConnection().createArrayOf("varchar", parameter.toArray()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
java.sql.Array array = rs.getArray(columnName);
|
||||
return parseArray(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
java.sql.Array array = rs.getArray(columnIndex);
|
||||
return parseArray(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
java.sql.Array array = cs.getArray(columnIndex);
|
||||
return parseArray(array);
|
||||
}
|
||||
|
||||
private List<String> parseArray(java.sql.Array array) throws SQLException {
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
Object[] objects = (Object[]) array.getArray();
|
||||
return new ArrayList<>(Arrays.asList((String[]) objects));
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
<module>file</module>
|
||||
<module>message</module>
|
||||
<module>crontab</module>
|
||||
<module>agent</module>
|
||||
<module>ai</module>
|
||||
<module>bidding</module>
|
||||
<module>platform</module>
|
||||
<module>workcase</module>
|
||||
|
||||
2
urbanLifelineServ/知识库逻辑变更.md
Normal file
2
urbanLifelineServ/知识库逻辑变更.md
Normal file
@@ -0,0 +1,2 @@
|
||||
1. 不再自己构建知识库,使用dify的知识库
|
||||
2. 服务的知识库表,只对文件进行重新上传才产生版本,对知识库内文档分段等修改不生成新的版本
|
||||
Reference in New Issue
Block a user