refactor: 按go modules规范重构
This commit is contained in:
@@ -10,11 +10,11 @@ import (
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
"knowledge-graph-backend/config"
|
||||
"knowledge-graph-backend/docs"
|
||||
"knowledge-graph-backend/handlers"
|
||||
neo4jClient "knowledge-graph-backend/neo4j"
|
||||
"knowledge-graph-backend/services"
|
||||
"knowledge-graph-backend/internal/config"
|
||||
"knowledge-graph-backend/internal/handler"
|
||||
neo4jClient "knowledge-graph-backend/internal/repository/neo4j"
|
||||
"knowledge-graph-backend/internal/service"
|
||||
)
|
||||
|
||||
// @title 知识图谱 API
|
||||
@@ -31,15 +31,15 @@ func main() {
|
||||
driver := neo4jClient.NewDriver(cfg.Neo4j)
|
||||
defer driver.Close(context.Background())
|
||||
|
||||
graphService := services.NewNeo4jService(driver)
|
||||
graphService := service.NewNeo4jService(driver)
|
||||
|
||||
graphHandler := handlers.NewGraphHandler(graphService)
|
||||
searchHandler := handlers.NewSearchHandler(graphService)
|
||||
nodeHandler := handlers.NewNodeHandler(graphService)
|
||||
graphHandler := handler.NewGraphHandler(graphService)
|
||||
searchHandler := handler.NewSearchHandler(graphService)
|
||||
nodeHandler := handler.NewNodeHandler(graphService)
|
||||
|
||||
// 增删改处理器
|
||||
nodeCRUDHandler := handlers.NewNodeCRUDHandler(graphService)
|
||||
edgeCRUDHandler := handlers.NewEdgeCRUDHandler(graphService)
|
||||
nodeCRUDHandler := handler.NewNodeCRUDHandler(graphService)
|
||||
edgeCRUDHandler := handler.NewEdgeCRUDHandler(graphService)
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
+83
-93
@@ -32,7 +32,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.CreateEdgeRequest"
|
||||
"$ref": "#/definitions/model.CreateEdgeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -40,31 +40,31 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "创建成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.EdgeResponse"
|
||||
"$ref": "#/definitions/model.EdgeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "源节点或目标节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "边已存在",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,19 +90,19 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.DeleteResponse"
|
||||
"$ref": "#/definitions/model.DeleteResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "边未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,13 +119,13 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.GraphData"
|
||||
"$ref": "#/definitions/model.GraphData"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,13 +142,13 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.SimpleGraphData"
|
||||
"$ref": "#/definitions/model.SimpleGraphData"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ const docTemplate = `{
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.CreateNodeRequest"
|
||||
"$ref": "#/definitions/model.CreateNodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -203,25 +203,25 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "创建成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "节点已存在",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,25 +247,25 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.NodeResponse"
|
||||
"$ref": "#/definitions/model.NodeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,7 +293,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.UpdateNodeRequest"
|
||||
"$ref": "#/definitions/model.UpdateNodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -301,25 +301,25 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "更新成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,19 +343,19 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.DeleteResponse"
|
||||
"$ref": "#/definitions/model.DeleteResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,25 +381,25 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.NeighborResponse"
|
||||
"$ref": "#/definitions/model.NeighborResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,19 +425,19 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.SearchResponse"
|
||||
"$ref": "#/definitions/model.SearchResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,7 +445,7 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"models.CreateEdgeRequest": {
|
||||
"model.CreateEdgeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
@@ -455,38 +455,32 @@ const docTemplate = `{
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "边的唯一标识",
|
||||
"type": "string",
|
||||
"example": "edge_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "边的显示标签",
|
||||
"type": "string",
|
||||
"example": "包含"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"source": {
|
||||
"description": "源节点ID",
|
||||
"type": "string",
|
||||
"example": "node_1"
|
||||
},
|
||||
"target": {
|
||||
"description": "目标节点ID",
|
||||
"type": "string",
|
||||
"example": "node_2"
|
||||
},
|
||||
"type": {
|
||||
"description": "边的类型(可选,默认为关系类型)",
|
||||
"type": "string",
|
||||
"example": "CONTAINS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.CreateNodeRequest": {
|
||||
"model.CreateNodeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
@@ -495,58 +489,49 @@ const docTemplate = `{
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "节点唯一标识",
|
||||
"type": "string",
|
||||
"example": "node_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "节点显示标签",
|
||||
"type": "string",
|
||||
"example": "人工智能"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"description": "节点类型",
|
||||
"type": "string",
|
||||
"example": "概念"
|
||||
},
|
||||
"x": {
|
||||
"description": "X坐标(可选)",
|
||||
"type": "number",
|
||||
"example": 100
|
||||
},
|
||||
"y": {
|
||||
"description": "Y坐标(可选)",
|
||||
"type": "number",
|
||||
"example": 200
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.DeleteResponse": {
|
||||
"model.DeleteResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "被删除的实体ID(可选)",
|
||||
"type": "string",
|
||||
"example": "node_123"
|
||||
},
|
||||
"message": {
|
||||
"description": "消息",
|
||||
"type": "string",
|
||||
"example": "节点已成功删除"
|
||||
},
|
||||
"success": {
|
||||
"description": "是否成功",
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Edge": {
|
||||
"model.Edge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -574,42 +559,36 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.EdgeResponse": {
|
||||
"model.EdgeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "边的ID",
|
||||
"type": "string",
|
||||
"example": "edge_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "边的显示标签",
|
||||
"type": "string",
|
||||
"example": "包含"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"source": {
|
||||
"description": "源节点ID",
|
||||
"type": "string",
|
||||
"example": "node_1"
|
||||
},
|
||||
"target": {
|
||||
"description": "目标节点ID",
|
||||
"type": "string",
|
||||
"example": "node_2"
|
||||
},
|
||||
"type": {
|
||||
"description": "边的类型",
|
||||
"type": "string",
|
||||
"example": "CONTAINS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ErrorResponse": {
|
||||
"model.ErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
@@ -620,41 +599,41 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.GraphData": {
|
||||
"model.GraphData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Edge"
|
||||
"$ref": "#/definitions/model.Edge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.NeighborResponse": {
|
||||
"model.NeighborResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Edge"
|
||||
"$ref": "#/definitions/model.Edge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Node": {
|
||||
"model.Node": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -682,42 +661,58 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.NodeResponse": {
|
||||
"model.NodeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"example": "1"
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"example": "人工智能"
|
||||
"type": "string"
|
||||
},
|
||||
"neighbors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"style": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "概念"
|
||||
"type": "string"
|
||||
},
|
||||
"x": {
|
||||
"type": "number"
|
||||
},
|
||||
"y": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SearchResponse": {
|
||||
"model.SearchResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"results": {
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleEdge": {
|
||||
"model.SimpleEdge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
@@ -738,24 +733,24 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleGraphData": {
|
||||
"model.SimpleGraphData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SimpleEdge"
|
||||
"$ref": "#/definitions/model.SimpleEdge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SimpleNode"
|
||||
"$ref": "#/definitions/model.SimpleNode"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleNode": {
|
||||
"model.SimpleNode": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -772,31 +767,26 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.UpdateNodeRequest": {
|
||||
"model.UpdateNodeRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "节点显示标签",
|
||||
"type": "string",
|
||||
"example": "机器学习"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性(更新)",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"description": "节点类型",
|
||||
"type": "string",
|
||||
"example": "工具"
|
||||
},
|
||||
"x": {
|
||||
"description": "X坐标",
|
||||
"type": "number",
|
||||
"example": 150
|
||||
},
|
||||
"y": {
|
||||
"description": "Y坐标",
|
||||
"type": "number",
|
||||
"example": 250
|
||||
}
|
||||
|
||||
+83
-93
@@ -26,7 +26,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.CreateEdgeRequest"
|
||||
"$ref": "#/definitions/model.CreateEdgeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -34,31 +34,31 @@
|
||||
"200": {
|
||||
"description": "创建成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.EdgeResponse"
|
||||
"$ref": "#/definitions/model.EdgeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "源节点或目标节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "边已存在",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,19 +84,19 @@
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.DeleteResponse"
|
||||
"$ref": "#/definitions/model.DeleteResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "边未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,13 +113,13 @@
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.GraphData"
|
||||
"$ref": "#/definitions/model.GraphData"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,13 +136,13 @@
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.SimpleGraphData"
|
||||
"$ref": "#/definitions/model.SimpleGraphData"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,7 @@
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.CreateNodeRequest"
|
||||
"$ref": "#/definitions/model.CreateNodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -197,25 +197,25 @@
|
||||
"200": {
|
||||
"description": "创建成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "节点已存在",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,25 +241,25 @@
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.NodeResponse"
|
||||
"$ref": "#/definitions/model.NodeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.UpdateNodeRequest"
|
||||
"$ref": "#/definitions/model.UpdateNodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -295,25 +295,25 @@
|
||||
"200": {
|
||||
"description": "更新成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,19 +337,19 @@
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.DeleteResponse"
|
||||
"$ref": "#/definitions/model.DeleteResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,25 +375,25 @@
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.NeighborResponse"
|
||||
"$ref": "#/definitions/model.NeighborResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "节点未找到",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,19 +419,19 @@
|
||||
"200": {
|
||||
"description": "成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.SearchResponse"
|
||||
"$ref": "#/definitions/model.SearchResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "内部错误",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.ErrorResponse"
|
||||
"$ref": "#/definitions/model.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,7 +439,7 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"models.CreateEdgeRequest": {
|
||||
"model.CreateEdgeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
@@ -449,38 +449,32 @@
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "边的唯一标识",
|
||||
"type": "string",
|
||||
"example": "edge_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "边的显示标签",
|
||||
"type": "string",
|
||||
"example": "包含"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"source": {
|
||||
"description": "源节点ID",
|
||||
"type": "string",
|
||||
"example": "node_1"
|
||||
},
|
||||
"target": {
|
||||
"description": "目标节点ID",
|
||||
"type": "string",
|
||||
"example": "node_2"
|
||||
},
|
||||
"type": {
|
||||
"description": "边的类型(可选,默认为关系类型)",
|
||||
"type": "string",
|
||||
"example": "CONTAINS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.CreateNodeRequest": {
|
||||
"model.CreateNodeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
@@ -489,58 +483,49 @@
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "节点唯一标识",
|
||||
"type": "string",
|
||||
"example": "node_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "节点显示标签",
|
||||
"type": "string",
|
||||
"example": "人工智能"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"description": "节点类型",
|
||||
"type": "string",
|
||||
"example": "概念"
|
||||
},
|
||||
"x": {
|
||||
"description": "X坐标(可选)",
|
||||
"type": "number",
|
||||
"example": 100
|
||||
},
|
||||
"y": {
|
||||
"description": "Y坐标(可选)",
|
||||
"type": "number",
|
||||
"example": 200
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.DeleteResponse": {
|
||||
"model.DeleteResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "被删除的实体ID(可选)",
|
||||
"type": "string",
|
||||
"example": "node_123"
|
||||
},
|
||||
"message": {
|
||||
"description": "消息",
|
||||
"type": "string",
|
||||
"example": "节点已成功删除"
|
||||
},
|
||||
"success": {
|
||||
"description": "是否成功",
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Edge": {
|
||||
"model.Edge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -568,42 +553,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.EdgeResponse": {
|
||||
"model.EdgeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "边的ID",
|
||||
"type": "string",
|
||||
"example": "edge_123"
|
||||
},
|
||||
"label": {
|
||||
"description": "边的显示标签",
|
||||
"type": "string",
|
||||
"example": "包含"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"source": {
|
||||
"description": "源节点ID",
|
||||
"type": "string",
|
||||
"example": "node_1"
|
||||
},
|
||||
"target": {
|
||||
"description": "目标节点ID",
|
||||
"type": "string",
|
||||
"example": "node_2"
|
||||
},
|
||||
"type": {
|
||||
"description": "边的类型",
|
||||
"type": "string",
|
||||
"example": "CONTAINS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.ErrorResponse": {
|
||||
"model.ErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
@@ -614,41 +593,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.GraphData": {
|
||||
"model.GraphData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Edge"
|
||||
"$ref": "#/definitions/model.Edge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.NeighborResponse": {
|
||||
"model.NeighborResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Edge"
|
||||
"$ref": "#/definitions/model.Edge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.Node": {
|
||||
"model.Node": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -676,42 +655,58 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.NodeResponse": {
|
||||
"model.NodeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"example": "1"
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"example": "人工智能"
|
||||
"type": "string"
|
||||
},
|
||||
"neighbors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"style": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "概念"
|
||||
"type": "string"
|
||||
},
|
||||
"x": {
|
||||
"type": "number"
|
||||
},
|
||||
"y": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SearchResponse": {
|
||||
"model.SearchResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"results": {
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.Node"
|
||||
"$ref": "#/definitions/model.Node"
|
||||
}
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleEdge": {
|
||||
"model.SimpleEdge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
@@ -732,24 +727,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleGraphData": {
|
||||
"model.SimpleGraphData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"edges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SimpleEdge"
|
||||
"$ref": "#/definitions/model.SimpleEdge"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.SimpleNode"
|
||||
"$ref": "#/definitions/model.SimpleNode"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.SimpleNode": {
|
||||
"model.SimpleNode": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -766,31 +761,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.UpdateNodeRequest": {
|
||||
"model.UpdateNodeRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "节点显示标签",
|
||||
"type": "string",
|
||||
"example": "机器学习"
|
||||
},
|
||||
"properties": {
|
||||
"description": "自定义属性(更新)",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"type": {
|
||||
"description": "节点类型",
|
||||
"type": "string",
|
||||
"example": "工具"
|
||||
},
|
||||
"x": {
|
||||
"description": "X坐标",
|
||||
"type": "number",
|
||||
"example": 150
|
||||
},
|
||||
"y": {
|
||||
"description": "Y坐标",
|
||||
"type": "number",
|
||||
"example": 250
|
||||
}
|
||||
|
||||
+74
-90
@@ -1,29 +1,23 @@
|
||||
basePath: /
|
||||
definitions:
|
||||
models.CreateEdgeRequest:
|
||||
model.CreateEdgeRequest:
|
||||
properties:
|
||||
id:
|
||||
description: 边的唯一标识
|
||||
example: edge_123
|
||||
type: string
|
||||
label:
|
||||
description: 边的显示标签
|
||||
example: 包含
|
||||
type: string
|
||||
properties:
|
||||
additionalProperties: true
|
||||
description: 自定义属性
|
||||
type: object
|
||||
source:
|
||||
description: 源节点ID
|
||||
example: node_1
|
||||
type: string
|
||||
target:
|
||||
description: 目标节点ID
|
||||
example: node_2
|
||||
type: string
|
||||
type:
|
||||
description: 边的类型(可选,默认为关系类型)
|
||||
example: CONTAINS
|
||||
type: string
|
||||
required:
|
||||
@@ -32,30 +26,24 @@ definitions:
|
||||
- source
|
||||
- target
|
||||
type: object
|
||||
models.CreateNodeRequest:
|
||||
model.CreateNodeRequest:
|
||||
properties:
|
||||
id:
|
||||
description: 节点唯一标识
|
||||
example: node_123
|
||||
type: string
|
||||
label:
|
||||
description: 节点显示标签
|
||||
example: 人工智能
|
||||
type: string
|
||||
properties:
|
||||
additionalProperties: true
|
||||
description: 自定义属性
|
||||
type: object
|
||||
type:
|
||||
description: 节点类型
|
||||
example: 概念
|
||||
type: string
|
||||
x:
|
||||
description: X坐标(可选)
|
||||
example: 100
|
||||
type: number
|
||||
"y":
|
||||
description: Y坐标(可选)
|
||||
example: 200
|
||||
type: number
|
||||
required:
|
||||
@@ -63,22 +51,19 @@ definitions:
|
||||
- label
|
||||
- type
|
||||
type: object
|
||||
models.DeleteResponse:
|
||||
model.DeleteResponse:
|
||||
properties:
|
||||
id:
|
||||
description: 被删除的实体ID(可选)
|
||||
example: node_123
|
||||
type: string
|
||||
message:
|
||||
description: 消息
|
||||
example: 节点已成功删除
|
||||
type: string
|
||||
success:
|
||||
description: 是否成功
|
||||
example: true
|
||||
type: boolean
|
||||
type: object
|
||||
models.Edge:
|
||||
model.Edge:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
@@ -97,63 +82,57 @@ definitions:
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
models.EdgeResponse:
|
||||
model.EdgeResponse:
|
||||
properties:
|
||||
id:
|
||||
description: 边的ID
|
||||
example: edge_123
|
||||
type: string
|
||||
label:
|
||||
description: 边的显示标签
|
||||
example: 包含
|
||||
type: string
|
||||
properties:
|
||||
additionalProperties: true
|
||||
description: 自定义属性
|
||||
type: object
|
||||
source:
|
||||
description: 源节点ID
|
||||
example: node_1
|
||||
type: string
|
||||
target:
|
||||
description: 目标节点ID
|
||||
example: node_2
|
||||
type: string
|
||||
type:
|
||||
description: 边的类型
|
||||
example: CONTAINS
|
||||
type: string
|
||||
type: object
|
||||
models.ErrorResponse:
|
||||
model.ErrorResponse:
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
models.GraphData:
|
||||
model.GraphData:
|
||||
properties:
|
||||
edges:
|
||||
items:
|
||||
$ref: '#/definitions/models.Edge'
|
||||
$ref: '#/definitions/model.Edge'
|
||||
type: array
|
||||
nodes:
|
||||
items:
|
||||
$ref: '#/definitions/models.Node'
|
||||
$ref: '#/definitions/model.Node'
|
||||
type: array
|
||||
type: object
|
||||
models.NeighborResponse:
|
||||
model.NeighborResponse:
|
||||
properties:
|
||||
edges:
|
||||
items:
|
||||
$ref: '#/definitions/models.Edge'
|
||||
$ref: '#/definitions/model.Edge'
|
||||
type: array
|
||||
nodes:
|
||||
items:
|
||||
$ref: '#/definitions/models.Node'
|
||||
$ref: '#/definitions/model.Node'
|
||||
type: array
|
||||
type: object
|
||||
models.Node:
|
||||
model.Node:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
@@ -172,31 +151,41 @@ definitions:
|
||||
"y":
|
||||
type: number
|
||||
type: object
|
||||
models.NodeResponse:
|
||||
model.NodeResponse:
|
||||
properties:
|
||||
id:
|
||||
example: "1"
|
||||
type: string
|
||||
label:
|
||||
example: 人工智能
|
||||
type: string
|
||||
neighbors:
|
||||
items:
|
||||
$ref: '#/definitions/model.Node'
|
||||
type: array
|
||||
properties:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
style:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
type:
|
||||
example: 概念
|
||||
type: string
|
||||
x:
|
||||
type: number
|
||||
"y":
|
||||
type: number
|
||||
type: object
|
||||
models.SearchResponse:
|
||||
model.SearchResponse:
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
results:
|
||||
nodes:
|
||||
items:
|
||||
$ref: '#/definitions/models.Node'
|
||||
$ref: '#/definitions/model.Node'
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
type: object
|
||||
models.SimpleEdge:
|
||||
model.SimpleEdge:
|
||||
properties:
|
||||
label:
|
||||
example: 包含
|
||||
@@ -211,18 +200,18 @@ definitions:
|
||||
example: CONTAINS
|
||||
type: string
|
||||
type: object
|
||||
models.SimpleGraphData:
|
||||
model.SimpleGraphData:
|
||||
properties:
|
||||
edges:
|
||||
items:
|
||||
$ref: '#/definitions/models.SimpleEdge'
|
||||
$ref: '#/definitions/model.SimpleEdge'
|
||||
type: array
|
||||
nodes:
|
||||
items:
|
||||
$ref: '#/definitions/models.SimpleNode'
|
||||
$ref: '#/definitions/model.SimpleNode'
|
||||
type: array
|
||||
type: object
|
||||
models.SimpleNode:
|
||||
model.SimpleNode:
|
||||
properties:
|
||||
id:
|
||||
example: "1"
|
||||
@@ -234,26 +223,21 @@ definitions:
|
||||
example: 概念
|
||||
type: string
|
||||
type: object
|
||||
models.UpdateNodeRequest:
|
||||
model.UpdateNodeRequest:
|
||||
properties:
|
||||
label:
|
||||
description: 节点显示标签
|
||||
example: 机器学习
|
||||
type: string
|
||||
properties:
|
||||
additionalProperties: true
|
||||
description: 自定义属性(更新)
|
||||
type: object
|
||||
type:
|
||||
description: 节点类型
|
||||
example: 工具
|
||||
type: string
|
||||
x:
|
||||
description: X坐标
|
||||
example: 150
|
||||
type: number
|
||||
"y":
|
||||
description: Y坐标
|
||||
example: 250
|
||||
type: number
|
||||
type: object
|
||||
@@ -275,30 +259,30 @@ paths:
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.CreateEdgeRequest'
|
||||
$ref: '#/definitions/model.CreateEdgeRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 创建成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.EdgeResponse'
|
||||
$ref: '#/definitions/model.EdgeResponse'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"404":
|
||||
description: 源节点或目标节点未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"409":
|
||||
description: 边已存在
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 创建边
|
||||
/api/edges/{id}:
|
||||
delete:
|
||||
@@ -315,15 +299,15 @@ paths:
|
||||
"200":
|
||||
description: 删除成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.DeleteResponse'
|
||||
$ref: '#/definitions/model.DeleteResponse'
|
||||
"404":
|
||||
description: 边未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 删除边
|
||||
/api/graph:
|
||||
get:
|
||||
@@ -334,11 +318,11 @@ paths:
|
||||
"200":
|
||||
description: 成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.GraphData'
|
||||
$ref: '#/definitions/model.GraphData'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 获取图数据
|
||||
/api/graph/simpleJson:
|
||||
get:
|
||||
@@ -349,11 +333,11 @@ paths:
|
||||
"200":
|
||||
description: 成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.SimpleGraphData'
|
||||
$ref: '#/definitions/model.SimpleGraphData'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 获取简化图数据
|
||||
/api/graph/stats:
|
||||
get:
|
||||
@@ -369,7 +353,7 @@ paths:
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 获取图统计信息
|
||||
/api/nodes:
|
||||
post:
|
||||
@@ -382,26 +366,26 @@ paths:
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.CreateNodeRequest'
|
||||
$ref: '#/definitions/model.CreateNodeRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 创建成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.Node'
|
||||
$ref: '#/definitions/model.Node'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"409":
|
||||
description: 节点已存在
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 创建节点
|
||||
/api/nodes/{id}:
|
||||
delete:
|
||||
@@ -418,15 +402,15 @@ paths:
|
||||
"200":
|
||||
description: 删除成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.DeleteResponse'
|
||||
$ref: '#/definitions/model.DeleteResponse'
|
||||
"404":
|
||||
description: 节点未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 删除节点
|
||||
get:
|
||||
description: 根据节点 ID 获取知识图谱中的节点详细信息
|
||||
@@ -442,19 +426,19 @@ paths:
|
||||
"200":
|
||||
description: 成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.NodeResponse'
|
||||
$ref: '#/definitions/model.NodeResponse'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"404":
|
||||
description: 节点未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 获取节点详情
|
||||
put:
|
||||
consumes:
|
||||
@@ -471,26 +455,26 @@ paths:
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.UpdateNodeRequest'
|
||||
$ref: '#/definitions/model.UpdateNodeRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 更新成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.Node'
|
||||
$ref: '#/definitions/model.Node'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"404":
|
||||
description: 节点未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 更新节点
|
||||
/api/nodes/{id}/neighbors:
|
||||
get:
|
||||
@@ -507,19 +491,19 @@ paths:
|
||||
"200":
|
||||
description: 成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.NeighborResponse'
|
||||
$ref: '#/definitions/model.NeighborResponse'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"404":
|
||||
description: 节点未找到
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 获取节点邻居
|
||||
/api/search:
|
||||
get:
|
||||
@@ -536,14 +520,14 @@ paths:
|
||||
"200":
|
||||
description: 成功
|
||||
schema:
|
||||
$ref: '#/definitions/models.SearchResponse'
|
||||
$ref: '#/definitions/model.SearchResponse'
|
||||
"400":
|
||||
description: 请求错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
"500":
|
||||
description: 内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/models.ErrorResponse'
|
||||
$ref: '#/definitions/model.ErrorResponse'
|
||||
summary: 搜索节点
|
||||
swagger: "2.0"
|
||||
|
||||
@@ -41,8 +41,8 @@ type Config struct {
|
||||
|
||||
func Load() (*Config, error) {
|
||||
var err error
|
||||
err = godotenv.Load("../config/.env")
|
||||
err = godotenv.Load("./config/.env")
|
||||
err = godotenv.Load("../configs/.env")
|
||||
err = godotenv.Load("./configs/.env")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading .env file: %w", err)
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"knowledge-graph-backend/models"
|
||||
"knowledge-graph-backend/services"
|
||||
"knowledge-graph-backend/internal/model"
|
||||
"knowledge-graph-backend/internal/service"
|
||||
)
|
||||
|
||||
// NodeCRUDHandler 节点的增删改处理器
|
||||
type NodeCRUDHandler struct {
|
||||
service services.GraphService
|
||||
service service.GraphService
|
||||
}
|
||||
|
||||
// NewNodeCRUDHandler 创建节点CRUD处理器
|
||||
func NewNodeCRUDHandler(service services.GraphService) *NodeCRUDHandler {
|
||||
func NewNodeCRUDHandler(svc service.GraphService) *NodeCRUDHandler {
|
||||
return &NodeCRUDHandler{
|
||||
service: service,
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
// EdgeCRUDHandler 边的增删改处理器
|
||||
type EdgeCRUDHandler struct {
|
||||
service services.GraphService
|
||||
service service.GraphService
|
||||
}
|
||||
|
||||
// NewEdgeCRUDHandler 创建边CRUD处理器
|
||||
func NewEdgeCRUDHandler(service services.GraphService) *EdgeCRUDHandler {
|
||||
func NewEdgeCRUDHandler(svc service.GraphService) *EdgeCRUDHandler {
|
||||
return &EdgeCRUDHandler{
|
||||
service: service,
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,16 +37,16 @@ func NewEdgeCRUDHandler(service services.GraphService) *EdgeCRUDHandler {
|
||||
// @Description 在知识图谱中创建一个新节点
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.CreateNodeRequest true "节点创建请求"
|
||||
// @Success 200 {object} models.Node "创建成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 409 {object} models.ErrorResponse "节点已存在"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Param request body model.CreateNodeRequest true "节点创建请求"
|
||||
// @Success 200 {object} model.Node "创建成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 409 {object} model.ErrorResponse "节点已存在"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/nodes [post]
|
||||
func (h *NodeCRUDHandler) CreateNode(c *gin.Context) {
|
||||
var req models.CreateNodeRequest
|
||||
var req model.CreateNodeRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, model.ErrorResponse{
|
||||
Error: "invalid_request",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -55,7 +55,7 @@ func (h *NodeCRUDHandler) CreateNode(c *gin.Context) {
|
||||
|
||||
node, err := h.service.CreateNode(req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusConflict, models.ErrorResponse{
|
||||
c.JSON(http.StatusConflict, model.ErrorResponse{
|
||||
Error: "create_failed",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -71,18 +71,18 @@ func (h *NodeCRUDHandler) CreateNode(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "节点ID"
|
||||
// @Param request body models.UpdateNodeRequest true "节点更新请求"
|
||||
// @Success 200 {object} models.Node "更新成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} models.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Param request body model.UpdateNodeRequest true "节点更新请求"
|
||||
// @Success 200 {object} model.Node "更新成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/nodes/{id} [put]
|
||||
func (h *NodeCRUDHandler) UpdateNode(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var req models.UpdateNodeRequest
|
||||
var req model.UpdateNodeRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, model.ErrorResponse{
|
||||
Error: "invalid_request",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -91,7 +91,7 @@ func (h *NodeCRUDHandler) UpdateNode(c *gin.Context) {
|
||||
|
||||
node, err := h.service.UpdateNode(id, req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, model.ErrorResponse{
|
||||
Error: "update_failed",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -106,23 +106,23 @@ func (h *NodeCRUDHandler) UpdateNode(c *gin.Context) {
|
||||
// @Description 从知识图谱中删除指定节点及其相关的所有边
|
||||
// @Produce json
|
||||
// @Param id path string true "节点ID"
|
||||
// @Success 200 {object} models.DeleteResponse "删除成功"
|
||||
// @Failure 404 {object} models.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.DeleteResponse "删除成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/nodes/{id} [delete]
|
||||
func (h *NodeCRUDHandler) DeleteNode(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
err := h.service.DeleteNode(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, model.ErrorResponse{
|
||||
Error: "delete_failed",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.DeleteResponse{
|
||||
c.JSON(http.StatusOK, model.DeleteResponse{
|
||||
Success: true,
|
||||
Message: "节点已成功删除",
|
||||
ID: id,
|
||||
@@ -134,17 +134,17 @@ func (h *NodeCRUDHandler) DeleteNode(c *gin.Context) {
|
||||
// @Description 在知识图谱中创建一个新边(关系)
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.CreateEdgeRequest true "边创建请求"
|
||||
// @Success 200 {object} models.EdgeResponse "创建成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} models.ErrorResponse "源节点或目标节点未找到"
|
||||
// @Failure 409 {object} models.ErrorResponse "边已存在"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Param request body model.CreateEdgeRequest true "边创建请求"
|
||||
// @Success 200 {object} model.EdgeResponse "创建成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "源节点或目标节点未找到"
|
||||
// @Failure 409 {object} model.ErrorResponse "边已存在"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/edges [post]
|
||||
func (h *EdgeCRUDHandler) CreateEdge(c *gin.Context) {
|
||||
var req models.CreateEdgeRequest
|
||||
var req model.CreateEdgeRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||
c.JSON(http.StatusBadRequest, model.ErrorResponse{
|
||||
Error: "invalid_request",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -153,7 +153,7 @@ func (h *EdgeCRUDHandler) CreateEdge(c *gin.Context) {
|
||||
|
||||
edge, err := h.service.CreateEdge(req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusConflict, models.ErrorResponse{
|
||||
c.JSON(http.StatusConflict, model.ErrorResponse{
|
||||
Error: "create_failed",
|
||||
Message: err.Error(),
|
||||
})
|
||||
@@ -161,7 +161,7 @@ func (h *EdgeCRUDHandler) CreateEdge(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
response := models.EdgeResponse{
|
||||
response := model.EdgeResponse{
|
||||
ID: edge.ID,
|
||||
Source: edge.Source,
|
||||
Target: edge.Target,
|
||||
@@ -178,23 +178,23 @@ func (h *EdgeCRUDHandler) CreateEdge(c *gin.Context) {
|
||||
// @Description 从知识图谱中删除指定的边
|
||||
// @Produce json
|
||||
// @Param id path string true "边ID"
|
||||
// @Success 200 {object} models.DeleteResponse "删除成功"
|
||||
// @Failure 404 {object} models.ErrorResponse "边未找到"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.DeleteResponse "删除成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "边未找到"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/edges/{id} [delete]
|
||||
func (h *EdgeCRUDHandler) DeleteEdge(c *gin.Context) {
|
||||
edgeID := c.Param("id")
|
||||
|
||||
err := h.service.DeleteEdge(edgeID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, models.ErrorResponse{
|
||||
c.JSON(http.StatusNotFound, model.ErrorResponse{
|
||||
Error: "delete_failed",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.DeleteResponse{
|
||||
c.JSON(http.StatusOK, model.DeleteResponse{
|
||||
Success: true,
|
||||
Message: "边已成功删除",
|
||||
ID: edgeID,
|
||||
@@ -1,27 +1,27 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"knowledge-graph-backend/services"
|
||||
"knowledge-graph-backend/internal/service"
|
||||
)
|
||||
|
||||
type GraphHandler struct {
|
||||
service services.GraphService
|
||||
service service.GraphService
|
||||
}
|
||||
|
||||
func NewGraphHandler(service services.GraphService) *GraphHandler {
|
||||
func NewGraphHandler(svc service.GraphService) *GraphHandler {
|
||||
return &GraphHandler{
|
||||
service: service,
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
// @Summary 获取图数据
|
||||
// @Description 获取知识图谱的全部节点和边数据
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.GraphData "成功"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.GraphData "成功"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/graph [get]
|
||||
func (h *GraphHandler) GetGraphData(c *gin.Context) {
|
||||
data := h.service.GetGraphData()
|
||||
@@ -32,7 +32,7 @@ func (h *GraphHandler) GetGraphData(c *gin.Context) {
|
||||
// @Description 获取知识图谱的节点数、边数等统计信息
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{} "成功"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/graph/stats [get]
|
||||
func (h *GraphHandler) GetStats(c *gin.Context) {
|
||||
stats := h.service.GetStats()
|
||||
@@ -42,8 +42,8 @@ func (h *GraphHandler) GetStats(c *gin.Context) {
|
||||
// @Summary 获取简化图数据
|
||||
// @Description 获取知识图谱的全部节点和边数据(仅保留核心信息,适合LLM处理)
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.SimpleGraphData "成功"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.SimpleGraphData "成功"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/graph/simpleJson [get]
|
||||
func (h *GraphHandler) GetSimpleGraphData(c *gin.Context) {
|
||||
data := h.service.GetSimpleGraphData()
|
||||
@@ -1,19 +1,19 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"knowledge-graph-backend/services"
|
||||
"knowledge-graph-backend/internal/service"
|
||||
)
|
||||
|
||||
type NodeHandler struct {
|
||||
service services.GraphService
|
||||
service service.GraphService
|
||||
}
|
||||
|
||||
func NewNodeHandler(service services.GraphService) *NodeHandler {
|
||||
func NewNodeHandler(svc service.GraphService) *NodeHandler {
|
||||
return &NodeHandler{
|
||||
service: service,
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ func NewNodeHandler(service services.GraphService) *NodeHandler {
|
||||
// @Description 根据节点 ID 获取知识图谱中的节点详细信息
|
||||
// @Produce json
|
||||
// @Param id path string true "节点 ID"
|
||||
// @Success 200 {object} models.NodeResponse "成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} models.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.NodeResponse "成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/nodes/{id} [get]
|
||||
func (h *NodeHandler) GetNodeByID(c *gin.Context) {
|
||||
nodeID := c.Param("id")
|
||||
@@ -52,10 +52,10 @@ func (h *NodeHandler) GetNodeByID(c *gin.Context) {
|
||||
// @Description 根据节点 ID 获取其所有邻居节点及关联边
|
||||
// @Produce json
|
||||
// @Param id path string true "节点 ID"
|
||||
// @Success 200 {object} models.NeighborResponse "成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} models.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.NeighborResponse "成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "节点未找到"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/nodes/{id}/neighbors [get]
|
||||
func (h *NodeHandler) GetNeighbors(c *gin.Context) {
|
||||
nodeID := c.Param("id")
|
||||
@@ -1,19 +1,19 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"knowledge-graph-backend/services"
|
||||
"knowledge-graph-backend/internal/service"
|
||||
)
|
||||
|
||||
type SearchHandler struct {
|
||||
service services.GraphService
|
||||
service service.GraphService
|
||||
}
|
||||
|
||||
func NewSearchHandler(service services.GraphService) *SearchHandler {
|
||||
func NewSearchHandler(svc service.GraphService) *SearchHandler {
|
||||
return &SearchHandler{
|
||||
service: service,
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ func NewSearchHandler(service services.GraphService) *SearchHandler {
|
||||
// @Description 根据关键词搜索知识图谱中的节点
|
||||
// @Produce json
|
||||
// @Param q query string true "搜索关键词"
|
||||
// @Success 200 {object} models.SearchResponse "成功"
|
||||
// @Failure 400 {object} models.ErrorResponse "请求错误"
|
||||
// @Failure 500 {object} models.ErrorResponse "内部错误"
|
||||
// @Success 200 {object} model.SearchResponse "成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求错误"
|
||||
// @Failure 500 {object} model.ErrorResponse "内部错误"
|
||||
// @Router /api/search [get]
|
||||
func (h *SearchHandler) SearchNodes(c *gin.Context) {
|
||||
query := c.Query("q")
|
||||
@@ -1,25 +1,28 @@
|
||||
package models
|
||||
package model
|
||||
|
||||
// Node represents a graph node
|
||||
type Node struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
X float64 `json:"x,omitempty"`
|
||||
Y float64 `json:"y,omitempty"`
|
||||
Style map[string]interface{} `json:"style,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// Edge represents a graph edge
|
||||
type Edge struct {
|
||||
ID string `json:"id"`
|
||||
Source string `json:"source"`
|
||||
Target string `json:"target"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
Style map[string]interface{} `json:"style,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// GraphData represents the complete graph structure
|
||||
type GraphData struct {
|
||||
Nodes []Node `json:"nodes"`
|
||||
Edges []Edge `json:"edges"`
|
||||
@@ -45,3 +48,43 @@ type SimpleGraphData struct {
|
||||
Nodes []SimpleNode `json:"nodes"`
|
||||
Edges []SimpleEdge `json:"edges"`
|
||||
}
|
||||
|
||||
// StatsResponse represents graph statistics
|
||||
type StatsResponse struct {
|
||||
TotalNodes int `json:"totalNodes"`
|
||||
TotalEdges int `json:"totalEdges"`
|
||||
ConceptNodes int `json:"conceptNodes,omitempty"`
|
||||
ToolNodes int `json:"toolNodes,omitempty"`
|
||||
ApplicationNodes int `json:"applicationNodes,omitempty"`
|
||||
}
|
||||
|
||||
// NeighborResponse represents a node's neighbors and related edges
|
||||
type NeighborResponse struct {
|
||||
Nodes []Node `json:"nodes"`
|
||||
Edges []Edge `json:"edges"`
|
||||
}
|
||||
|
||||
// NodeResponse represents a node detail response
|
||||
type NodeResponse struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Type string `json:"type,omitempty"`
|
||||
X float64 `json:"x,omitempty"`
|
||||
Y float64 `json:"y,omitempty"`
|
||||
Style map[string]interface{} `json:"style,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
Neighbors []Node `json:"neighbors,omitempty"`
|
||||
}
|
||||
|
||||
// SearchResponse represents search results
|
||||
type SearchResponse struct {
|
||||
Count int `json:"count"`
|
||||
Query string `json:"query"`
|
||||
Nodes []Node `json:"nodes"`
|
||||
}
|
||||
|
||||
// ErrorResponse represents an error response
|
||||
type ErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package model
|
||||
|
||||
// NodeInfo represents detailed node information
|
||||
type NodeInfo struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Type string `json:"type"`
|
||||
X float64 `json:"x,omitempty"`
|
||||
Y float64 `json:"y,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
Neighbors []Node `json:"neighbors,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package model
|
||||
|
||||
// CreateNodeRequest creates a new node
|
||||
type CreateNodeRequest struct {
|
||||
ID string `json:"id" binding:"required" example:"node_123"`
|
||||
Label string `json:"label" binding:"required" example:"人工智能"`
|
||||
Type string `json:"type" binding:"required" example:"概念"`
|
||||
X float64 `json:"x" example:"100"`
|
||||
Y float64 `json:"y" example:"200"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateNodeRequest updates an existing node
|
||||
type UpdateNodeRequest struct {
|
||||
Label string `json:"label,omitempty" example:"机器学习"`
|
||||
Type string `json:"type,omitempty" example:"工具"`
|
||||
X *float64 `json:"x,omitempty" example:"150"`
|
||||
Y *float64 `json:"y,omitempty" example:"250"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteResponse represents a delete operation response
|
||||
type DeleteResponse struct {
|
||||
Success bool `json:"success" example:"true"`
|
||||
Message string `json:"message" example:"节点已成功删除"`
|
||||
ID string `json:"id,omitempty" example:"node_123"`
|
||||
}
|
||||
|
||||
// CreateEdgeRequest creates a new edge
|
||||
type CreateEdgeRequest struct {
|
||||
ID string `json:"id" binding:"required" example:"edge_123"`
|
||||
Source string `json:"source" binding:"required" example:"node_1"`
|
||||
Target string `json:"target" binding:"required" example:"node_2"`
|
||||
Label string `json:"label" binding:"required" example:"包含"`
|
||||
Type string `json:"type" example:"CONTAINS"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// EdgeResponse represents an edge response
|
||||
type EdgeResponse struct {
|
||||
ID string `json:"id" example:"edge_123"`
|
||||
Source string `json:"source" example:"node_1"`
|
||||
Target string `json:"target" example:"node_2"`
|
||||
Label string `json:"label" example:"包含"`
|
||||
Type string `json:"type" example:"CONTAINS"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
|
||||
"knowledge-graph-backend/config"
|
||||
"knowledge-graph-backend/internal/config"
|
||||
)
|
||||
|
||||
func NewDriver(cfg config.Neo4jConfig) neo4j.DriverWithContext {
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"knowledge-graph-backend/config"
|
||||
"knowledge-graph-backend/internal/config"
|
||||
)
|
||||
|
||||
func TestNewDriver(t *testing.T) {
|
||||
@@ -0,0 +1,20 @@
|
||||
package service
|
||||
|
||||
import "knowledge-graph-backend/internal/model"
|
||||
|
||||
type GraphService interface {
|
||||
GetGraphData() model.GraphData
|
||||
GetSimpleGraphData() model.SimpleGraphData
|
||||
GetNodeByID(id string) (model.Node, bool)
|
||||
SearchNodes(query string) []model.Node
|
||||
GetNeighbors(nodeID string) (model.NeighborResponse, bool)
|
||||
GetStats() map[string]int
|
||||
|
||||
// 新增增删改接口
|
||||
CreateNode(req model.CreateNodeRequest) (model.Node, error)
|
||||
UpdateNode(id string, req model.UpdateNodeRequest) (model.Node, error)
|
||||
DeleteNode(id string) error
|
||||
|
||||
CreateEdge(req model.CreateEdgeRequest) (model.Edge, error)
|
||||
DeleteEdge(id string) error
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
|
||||
"knowledge-graph-backend/models"
|
||||
"knowledge-graph-backend/internal/model"
|
||||
)
|
||||
|
||||
type Neo4jService struct {
|
||||
@@ -18,10 +18,10 @@ func NewNeo4jService(driver neo4j.DriverWithContext) *Neo4jService {
|
||||
return &Neo4jService{driver: driver}
|
||||
}
|
||||
|
||||
func (s *Neo4jService) GetGraphData() models.GraphData {
|
||||
func (s *Neo4jService) GetGraphData() model.GraphData {
|
||||
ctx := context.Background()
|
||||
var nodes []models.Node
|
||||
var edges []models.Edge
|
||||
var nodes []model.Node
|
||||
var edges []model.Edge
|
||||
|
||||
nodeResult, err := neo4j.ExecuteQuery(ctx, s.driver,
|
||||
"MATCH (n) RETURN n",
|
||||
@@ -30,7 +30,7 @@ func (s *Neo4jService) GetGraphData() models.GraphData {
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying nodes: %v\n", err)
|
||||
return models.GraphData{}
|
||||
return model.GraphData{}
|
||||
}
|
||||
for _, record := range nodeResult.Records {
|
||||
if v, ok := record.Get("n"); ok {
|
||||
@@ -47,7 +47,7 @@ func (s *Neo4jService) GetGraphData() models.GraphData {
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying edges: %v\n", err)
|
||||
return models.GraphData{Nodes: nodes}
|
||||
return model.GraphData{Nodes: nodes}
|
||||
}
|
||||
for _, record := range edgeResult.Records {
|
||||
source, _ := record.Get("source")
|
||||
@@ -65,10 +65,10 @@ func (s *Neo4jService) GetGraphData() models.GraphData {
|
||||
}
|
||||
}
|
||||
|
||||
return models.GraphData{Nodes: nodes, Edges: edges}
|
||||
return model.GraphData{Nodes: nodes, Edges: edges}
|
||||
}
|
||||
|
||||
func (s *Neo4jService) GetNodeByID(id string) (models.Node, bool) {
|
||||
func (s *Neo4jService) GetNodeByID(id string) (model.Node, bool) {
|
||||
ctx := context.Background()
|
||||
result, err := neo4j.ExecuteQuery(ctx, s.driver,
|
||||
"MATCH (n {id: $id}) RETURN n",
|
||||
@@ -76,18 +76,18 @@ func (s *Neo4jService) GetNodeByID(id string) (models.Node, bool) {
|
||||
neo4j.EagerResultTransformer,
|
||||
)
|
||||
if err != nil || len(result.Records) == 0 {
|
||||
return models.Node{}, false
|
||||
return model.Node{}, false
|
||||
}
|
||||
v, _ := result.Records[0].Get("n")
|
||||
if n, ok := v.(neo4j.Node); ok {
|
||||
return neo4jNodeToModel(n), true
|
||||
}
|
||||
return models.Node{}, false
|
||||
return model.Node{}, false
|
||||
}
|
||||
|
||||
func (s *Neo4jService) SearchNodes(query string) []models.Node {
|
||||
func (s *Neo4jService) SearchNodes(query string) []model.Node {
|
||||
if query == "" {
|
||||
return []models.Node{}
|
||||
return []model.Node{}
|
||||
}
|
||||
ctx := context.Background()
|
||||
result, err := neo4j.ExecuteQuery(ctx, s.driver,
|
||||
@@ -100,9 +100,9 @@ func (s *Neo4jService) SearchNodes(query string) []models.Node {
|
||||
neo4j.EagerResultTransformer,
|
||||
)
|
||||
if err != nil {
|
||||
return []models.Node{}
|
||||
return []model.Node{}
|
||||
}
|
||||
var nodes []models.Node
|
||||
var nodes []model.Node
|
||||
for _, record := range result.Records {
|
||||
v, _ := record.Get("n")
|
||||
if n, ok := v.(neo4j.Node); ok {
|
||||
@@ -112,12 +112,12 @@ func (s *Neo4jService) SearchNodes(query string) []models.Node {
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (s *Neo4jService) GetNeighbors(nodeID string) (models.NeighborResponse, bool) {
|
||||
func (s *Neo4jService) GetNeighbors(nodeID string) (model.NeighborResponse, bool) {
|
||||
ctx := context.Background()
|
||||
|
||||
_, exists := s.GetNodeByID(nodeID)
|
||||
if !exists {
|
||||
return models.NeighborResponse{}, false
|
||||
return model.NeighborResponse{}, false
|
||||
}
|
||||
|
||||
result, err := neo4j.ExecuteQuery(ctx, s.driver,
|
||||
@@ -127,11 +127,11 @@ func (s *Neo4jService) GetNeighbors(nodeID string) (models.NeighborResponse, boo
|
||||
neo4j.EagerResultTransformer,
|
||||
)
|
||||
if err != nil {
|
||||
return models.NeighborResponse{Nodes: []models.Node{}, Edges: []models.Edge{}}, true
|
||||
return model.NeighborResponse{Nodes: []model.Node{}, Edges: []model.Edge{}}, true
|
||||
}
|
||||
|
||||
neighborMap := make(map[string]models.Node)
|
||||
edgeMap := make(map[string]models.Edge)
|
||||
neighborMap := make(map[string]model.Node)
|
||||
edgeMap := make(map[string]model.Edge)
|
||||
|
||||
for _, record := range result.Records {
|
||||
if v, ok := record.Get("m"); ok {
|
||||
@@ -159,17 +159,17 @@ func (s *Neo4jService) GetNeighbors(nodeID string) (models.NeighborResponse, boo
|
||||
}
|
||||
}
|
||||
|
||||
var neighborNodes []models.Node
|
||||
var neighborNodes []model.Node
|
||||
for _, n := range neighborMap {
|
||||
neighborNodes = append(neighborNodes, n)
|
||||
}
|
||||
|
||||
var relatedEdges []models.Edge
|
||||
var relatedEdges []model.Edge
|
||||
for _, e := range edgeMap {
|
||||
relatedEdges = append(relatedEdges, e)
|
||||
}
|
||||
|
||||
return models.NeighborResponse{
|
||||
return model.NeighborResponse{
|
||||
Nodes: neighborNodes,
|
||||
Edges: relatedEdges,
|
||||
}, true
|
||||
@@ -216,10 +216,10 @@ func (s *Neo4jService) GetStats() map[string]int {
|
||||
}
|
||||
|
||||
// GetSimpleGraphData 获取简化的图数据,仅保留核心信息,适合 LLM 处理
|
||||
func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData {
|
||||
func (s *Neo4jService) GetSimpleGraphData() model.SimpleGraphData {
|
||||
ctx := context.Background()
|
||||
var nodes []models.SimpleNode
|
||||
var edges []models.SimpleEdge
|
||||
var nodes []model.SimpleNode
|
||||
var edges []model.SimpleEdge
|
||||
|
||||
nodeResult, err := neo4j.ExecuteQuery(ctx, s.driver,
|
||||
"MATCH (n) RETURN n",
|
||||
@@ -228,13 +228,13 @@ func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData {
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying nodes: %v\n", err)
|
||||
return models.SimpleGraphData{}
|
||||
return model.SimpleGraphData{}
|
||||
}
|
||||
for _, record := range nodeResult.Records {
|
||||
if v, ok := record.Get("n"); ok {
|
||||
if n, ok := v.(neo4j.Node); ok {
|
||||
props := n.Props
|
||||
node := models.SimpleNode{
|
||||
node := model.SimpleNode{
|
||||
ID: getStr(props, "id"),
|
||||
Label: getStr(props, "label"),
|
||||
Type: getStr(props, "type"),
|
||||
@@ -251,7 +251,7 @@ func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData {
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying edges: %v\n", err)
|
||||
return models.SimpleGraphData{Nodes: nodes}
|
||||
return model.SimpleGraphData{Nodes: nodes}
|
||||
}
|
||||
for _, record := range edgeResult.Records {
|
||||
source, _ := record.Get("source")
|
||||
@@ -259,7 +259,7 @@ func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData {
|
||||
v, _ := record.Get("r")
|
||||
if rel, ok := v.(neo4j.Relationship); ok {
|
||||
props := rel.Props
|
||||
edge := models.SimpleEdge{
|
||||
edge := model.SimpleEdge{
|
||||
Source: getStr(props, "source"),
|
||||
Target: getStr(props, "target"),
|
||||
Type: rel.Type,
|
||||
@@ -275,12 +275,12 @@ func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData {
|
||||
}
|
||||
}
|
||||
|
||||
return models.SimpleGraphData{Nodes: nodes, Edges: edges}
|
||||
return model.SimpleGraphData{Nodes: nodes, Edges: edges}
|
||||
}
|
||||
|
||||
func neo4jNodeToModel(n neo4j.Node) models.Node {
|
||||
func neo4jNodeToModel(n neo4j.Node) model.Node {
|
||||
props := n.Props
|
||||
node := models.Node{
|
||||
node := model.Node{
|
||||
ID: getStr(props, "id"),
|
||||
Label: getStr(props, "label"),
|
||||
Type: getStr(props, "type"),
|
||||
@@ -307,9 +307,9 @@ func neo4jNodeToModel(n neo4j.Node) models.Node {
|
||||
return node
|
||||
}
|
||||
|
||||
func neo4jRelToModel(r neo4j.Relationship) models.Edge {
|
||||
func neo4jRelToModel(r neo4j.Relationship) model.Edge {
|
||||
props := r.Props
|
||||
edge := models.Edge{
|
||||
edge := model.Edge{
|
||||
ID: getStr(props, "id"),
|
||||
Label: getStr(props, "label"),
|
||||
Type: r.Type,
|
||||
@@ -365,7 +365,7 @@ func getInt(record *neo4j.Record, key string) int {
|
||||
}
|
||||
|
||||
// CreateNode 创建新节点
|
||||
func (s *Neo4jService) CreateNode(req models.CreateNodeRequest) (models.Node, error) {
|
||||
func (s *Neo4jService) CreateNode(req model.CreateNodeRequest) (model.Node, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 检查节点是否已存在
|
||||
@@ -373,10 +373,10 @@ func (s *Neo4jService) CreateNode(req models.CreateNodeRequest) (models.Node, er
|
||||
checkResult, err := neo4j.ExecuteQuery(ctx, s.driver, checkQuery,
|
||||
map[string]any{"id": req.ID}, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
return models.Node{}, fmt.Errorf("error checking node existence: %w", err)
|
||||
return model.Node{}, fmt.Errorf("error checking node existence: %w", err)
|
||||
}
|
||||
if len(checkResult.Records) > 0 {
|
||||
return models.Node{}, fmt.Errorf("node with id %s already exists", req.ID)
|
||||
return model.Node{}, fmt.Errorf("node with id %s already exists", req.ID)
|
||||
}
|
||||
|
||||
// 构建创建属性
|
||||
@@ -419,11 +419,11 @@ func (s *Neo4jService) CreateNode(req models.CreateNodeRequest) (models.Node, er
|
||||
map[string]any{"props": props}, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating node: %v\n", err)
|
||||
return models.Node{}, fmt.Errorf("failed to create node: %w", err)
|
||||
return model.Node{}, fmt.Errorf("failed to create node: %w", err)
|
||||
}
|
||||
|
||||
if len(result.Records) == 0 {
|
||||
return models.Node{}, fmt.Errorf("failed to create node: no result returned")
|
||||
return model.Node{}, fmt.Errorf("failed to create node: no result returned")
|
||||
}
|
||||
|
||||
v, _ := result.Records[0].Get("n")
|
||||
@@ -431,11 +431,11 @@ func (s *Neo4jService) CreateNode(req models.CreateNodeRequest) (models.Node, er
|
||||
return neo4jNodeToModel(n), nil
|
||||
}
|
||||
|
||||
return models.Node{}, fmt.Errorf("unexpected result type while creating node")
|
||||
return model.Node{}, fmt.Errorf("unexpected result type while creating node")
|
||||
}
|
||||
|
||||
// CreateNodeV2 创建新节点(改进版)
|
||||
func (s *Neo4jService) CreateNodeV2(req models.CreateNodeRequest) (models.Node, error) {
|
||||
func (s *Neo4jService) CreateNodeV2(req model.CreateNodeRequest) (model.Node, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 先检查节点是否已存在
|
||||
@@ -443,10 +443,10 @@ func (s *Neo4jService) CreateNodeV2(req models.CreateNodeRequest) (models.Node,
|
||||
checkResult, err := neo4j.ExecuteQuery(ctx, s.driver, checkQuery,
|
||||
map[string]any{"id": req.ID}, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
return models.Node{}, err
|
||||
return model.Node{}, err
|
||||
}
|
||||
if len(checkResult.Records) > 0 {
|
||||
return models.Node{}, fmt.Errorf("node with id %s already exists", req.ID)
|
||||
return model.Node{}, fmt.Errorf("node with id %s already exists", req.ID)
|
||||
}
|
||||
|
||||
// 构建创建属性
|
||||
@@ -489,11 +489,11 @@ func (s *Neo4jService) CreateNodeV2(req models.CreateNodeRequest) (models.Node,
|
||||
map[string]any{"props": props}, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating node: %v\n", err)
|
||||
return models.Node{}, err
|
||||
return model.Node{}, err
|
||||
}
|
||||
|
||||
if len(result.Records) == 0 {
|
||||
return models.Node{}, fmt.Errorf("failed to create node")
|
||||
return model.Node{}, fmt.Errorf("failed to create node")
|
||||
}
|
||||
|
||||
v, _ := result.Records[0].Get("n")
|
||||
@@ -501,17 +501,17 @@ func (s *Neo4jService) CreateNodeV2(req models.CreateNodeRequest) (models.Node,
|
||||
return neo4jNodeToModel(n), nil
|
||||
}
|
||||
|
||||
return models.Node{}, fmt.Errorf("unexpected result type while creating node")
|
||||
return model.Node{}, fmt.Errorf("unexpected result type while creating node")
|
||||
}
|
||||
|
||||
// UpdateNode 更新节点
|
||||
func (s *Neo4jService) UpdateNode(id string, req models.UpdateNodeRequest) (models.Node, error) {
|
||||
func (s *Neo4jService) UpdateNode(id string, req model.UpdateNodeRequest) (model.Node, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 检查节点是否存在
|
||||
_, exists := s.GetNodeByID(id)
|
||||
if !exists {
|
||||
return models.Node{}, fmt.Errorf("node with id %s not found", id)
|
||||
return model.Node{}, fmt.Errorf("node with id %s not found", id)
|
||||
}
|
||||
|
||||
// 构建更新语句
|
||||
@@ -558,11 +558,11 @@ func (s *Neo4jService) UpdateNode(id string, req models.UpdateNodeRequest) (mode
|
||||
result, err := neo4j.ExecuteQuery(ctx, s.driver, query, params, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
fmt.Printf("Error updating node: %v\n", err)
|
||||
return models.Node{}, err
|
||||
return model.Node{}, err
|
||||
}
|
||||
|
||||
if len(result.Records) == 0 {
|
||||
return models.Node{}, fmt.Errorf("failed to update node")
|
||||
return model.Node{}, fmt.Errorf("failed to update node")
|
||||
}
|
||||
|
||||
v, _ := result.Records[0].Get("n")
|
||||
@@ -570,7 +570,7 @@ func (s *Neo4jService) UpdateNode(id string, req models.UpdateNodeRequest) (mode
|
||||
return neo4jNodeToModel(n), nil
|
||||
}
|
||||
|
||||
return models.Node{}, fmt.Errorf("unexpected result type while updating node")
|
||||
return model.Node{}, fmt.Errorf("unexpected result type while updating node")
|
||||
}
|
||||
|
||||
// DeleteNode 删除节点
|
||||
@@ -611,17 +611,17 @@ func (s *Neo4jService) DeleteNode(id string) error {
|
||||
}
|
||||
|
||||
// CreateEdge 创建新边
|
||||
func (s *Neo4jService) CreateEdge(req models.CreateEdgeRequest) (models.Edge, error) {
|
||||
func (s *Neo4jService) CreateEdge(req model.CreateEdgeRequest) (model.Edge, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 检查源节点和目标节点是否存在
|
||||
_, sourceExists := s.GetNodeByID(req.Source)
|
||||
if !sourceExists {
|
||||
return models.Edge{}, fmt.Errorf("source node with id %s not found", req.Source)
|
||||
return model.Edge{}, fmt.Errorf("source node with id %s not found", req.Source)
|
||||
}
|
||||
_, targetExists := s.GetNodeByID(req.Target)
|
||||
if !targetExists {
|
||||
return models.Edge{}, fmt.Errorf("target node with id %s not found", req.Target)
|
||||
return model.Edge{}, fmt.Errorf("target node with id %s not found", req.Target)
|
||||
}
|
||||
|
||||
// 构建创建属性
|
||||
@@ -663,11 +663,11 @@ func (s *Neo4jService) CreateEdge(req models.CreateEdgeRequest) (models.Edge, er
|
||||
result, err := neo4j.ExecuteQuery(ctx, s.driver, query, params, neo4j.EagerResultTransformer)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating edge: %v\n", err)
|
||||
return models.Edge{}, err
|
||||
return model.Edge{}, err
|
||||
}
|
||||
|
||||
if len(result.Records) == 0 {
|
||||
return models.Edge{}, fmt.Errorf("failed to create edge")
|
||||
return model.Edge{}, fmt.Errorf("failed to create edge")
|
||||
}
|
||||
|
||||
v, _ := result.Records[0].Get("r")
|
||||
@@ -678,7 +678,7 @@ func (s *Neo4jService) CreateEdge(req models.CreateEdgeRequest) (models.Edge, er
|
||||
return edge, nil
|
||||
}
|
||||
|
||||
return models.Edge{}, fmt.Errorf("unexpected result type while creating edge")
|
||||
return model.Edge{}, fmt.Errorf("unexpected result type while creating edge")
|
||||
}
|
||||
|
||||
// DeleteEdge 删除边
|
||||
@@ -1,23 +0,0 @@
|
||||
package models
|
||||
|
||||
type NodeResponse struct {
|
||||
ID string `json:"id" example:"1"`
|
||||
Label string `json:"label" example:"人工智能"`
|
||||
Type string `json:"type,omitempty" example:"概念"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
type NeighborResponse struct {
|
||||
Nodes []Node `json:"nodes"`
|
||||
Edges []Edge `json:"edges"`
|
||||
}
|
||||
|
||||
type SearchResponse struct {
|
||||
Results []Node `json:"results"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package models
|
||||
|
||||
// CreateNodeRequest 创建节点的请求结构
|
||||
type CreateNodeRequest struct {
|
||||
ID string `json:"id" binding:"required" example:"node_123"` // 节点唯一标识
|
||||
Label string `json:"label" binding:"required" example:"人工智能"` // 节点显示标签
|
||||
Type string `json:"type" binding:"required" example:"概念"` // 节点类型
|
||||
X float64 `json:"x" example:"100"` // X坐标(可选)
|
||||
Y float64 `json:"y" example:"200"` // Y坐标(可选)
|
||||
Properties map[string]interface{} `json:"properties,omitempty"` // 自定义属性
|
||||
}
|
||||
|
||||
// UpdateNodeRequest 更新节点的请求结构
|
||||
type UpdateNodeRequest struct {
|
||||
Label string `json:"label,omitempty" example:"机器学习"` // 节点显示标签
|
||||
Type string `json:"type,omitempty" example:"工具"` // 节点类型
|
||||
X *float64 `json:"x,omitempty" example:"150"` // X坐标
|
||||
Y *float64 `json:"y,omitempty" example:"250"` // Y坐标
|
||||
Properties map[string]interface{} `json:"properties,omitempty"` // 自定义属性(更新)
|
||||
}
|
||||
|
||||
// DeleteResponse 删除操作的响应结构
|
||||
type DeleteResponse struct {
|
||||
Success bool `json:"success" example:"true"` // 是否成功
|
||||
Message string `json:"message" example:"节点已成功删除"` // 消息
|
||||
ID string `json:"id,omitempty" example:"node_123"` // 被删除的实体ID(可选)
|
||||
}
|
||||
|
||||
// CreateEdgeRequest 创建边的请求结构
|
||||
type CreateEdgeRequest struct {
|
||||
ID string `json:"id" binding:"required" example:"edge_123"` // 边的唯一标识
|
||||
Source string `json:"source" binding:"required" example:"node_1"` // 源节点ID
|
||||
Target string `json:"target" binding:"required" example:"node_2"` // 目标节点ID
|
||||
Label string `json:"label" binding:"required" example:"包含"` // 边的显示标签
|
||||
Type string `json:"type" example:"CONTAINS"` // 边的类型(可选,默认为关系类型)
|
||||
Properties map[string]interface{} `json:"properties,omitempty"` // 自定义属性
|
||||
}
|
||||
|
||||
// EdgeResponse 边的响应结构
|
||||
type EdgeResponse struct {
|
||||
ID string `json:"id" example:"edge_123"` // 边的ID
|
||||
Source string `json:"source" example:"node_1"` // 源节点ID
|
||||
Target string `json:"target" example:"node_2"` // 目标节点ID
|
||||
Label string `json:"label" example:"包含"` // 边的显示标签
|
||||
Type string `json:"type" example:"CONTAINS"` // 边的类型
|
||||
Properties map[string]interface{} `json:"properties,omitempty"` // 自定义属性
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"knowledge-graph-backend/models"
|
||||
)
|
||||
|
||||
type DataService struct {
|
||||
data models.GraphData
|
||||
mutex sync.RWMutex
|
||||
filePath string
|
||||
}
|
||||
|
||||
func NewDataService(filePath string) (*DataService, error) {
|
||||
ds := &DataService{
|
||||
filePath: filePath,
|
||||
mutex: sync.RWMutex{},
|
||||
}
|
||||
|
||||
if err := ds.loadData(); err != nil {
|
||||
return nil, fmt.Errorf("failed to load data: %w", err)
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
func (ds *DataService) loadData() error {
|
||||
ds.mutex.Lock()
|
||||
defer ds.mutex.Unlock()
|
||||
|
||||
file, err := os.Open(ds.filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open data file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
byteValue, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read data file: %w", err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(byteValue, &ds.data); err != nil {
|
||||
return fmt.Errorf("failed to parse data file: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d nodes and %d edges from %s",
|
||||
len(ds.data.Nodes), len(ds.data.Edges), ds.filePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *DataService) GetGraphData() models.GraphData {
|
||||
ds.mutex.RLock()
|
||||
defer ds.mutex.RUnlock()
|
||||
return ds.data
|
||||
}
|
||||
|
||||
func (ds *DataService) GetNodeByID(id string) (models.Node, bool) {
|
||||
ds.mutex.RLock()
|
||||
defer ds.mutex.RUnlock()
|
||||
|
||||
for _, node := range ds.data.Nodes {
|
||||
if node.ID == id {
|
||||
return node, true
|
||||
}
|
||||
}
|
||||
return models.Node{}, false
|
||||
}
|
||||
|
||||
func (ds *DataService) SearchNodes(query string) []models.Node {
|
||||
ds.mutex.RLock()
|
||||
defer ds.mutex.RUnlock()
|
||||
|
||||
if query == "" {
|
||||
return []models.Node{}
|
||||
}
|
||||
|
||||
searchLower := strings.ToLower(query)
|
||||
var results []models.Node
|
||||
|
||||
for _, node := range ds.data.Nodes {
|
||||
labelMatch := strings.Contains(strings.ToLower(node.Label), searchLower)
|
||||
idMatch := strings.Contains(strings.ToLower(node.ID), searchLower)
|
||||
typeMatch := node.Type != "" && strings.Contains(strings.ToLower(node.Type), searchLower)
|
||||
|
||||
if labelMatch || idMatch || typeMatch {
|
||||
results = append(results, node)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
func (ds *DataService) GetNeighbors(nodeID string) (models.NeighborResponse, bool) {
|
||||
ds.mutex.RLock()
|
||||
defer ds.mutex.RUnlock()
|
||||
|
||||
_, exists := ds.GetNodeByID(nodeID)
|
||||
if !exists {
|
||||
return models.NeighborResponse{}, false
|
||||
}
|
||||
|
||||
var neighborIDs []string
|
||||
var relatedEdges []models.Edge
|
||||
|
||||
for _, edge := range ds.data.Edges {
|
||||
if edge.Source == nodeID {
|
||||
neighborIDs = append(neighborIDs, edge.Target)
|
||||
relatedEdges = append(relatedEdges, edge)
|
||||
} else if edge.Target == nodeID {
|
||||
neighborIDs = append(neighborIDs, edge.Source)
|
||||
relatedEdges = append(relatedEdges, edge)
|
||||
}
|
||||
}
|
||||
|
||||
var neighborNodes []models.Node
|
||||
for _, node := range ds.data.Nodes {
|
||||
for _, neighborID := range neighborIDs {
|
||||
if node.ID == neighborID {
|
||||
neighborNodes = append(neighborNodes, node)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return models.NeighborResponse{
|
||||
Nodes: neighborNodes,
|
||||
Edges: relatedEdges,
|
||||
}, true
|
||||
}
|
||||
|
||||
func (ds *DataService) ReloadData() error {
|
||||
return ds.loadData()
|
||||
}
|
||||
|
||||
func (ds *DataService) GetStats() map[string]int {
|
||||
ds.mutex.RLock()
|
||||
defer ds.mutex.RUnlock()
|
||||
|
||||
typeCounts := make(map[string]int)
|
||||
for _, node := range ds.data.Nodes {
|
||||
if node.Type != "" {
|
||||
typeCounts[node.Type]++
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]int{
|
||||
"totalNodes": len(ds.data.Nodes),
|
||||
"totalEdges": len(ds.data.Edges),
|
||||
"conceptNodes": typeCounts["概念"],
|
||||
"toolNodes": typeCounts["工具"],
|
||||
"applicationNodes": typeCounts["应用"],
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package services
|
||||
|
||||
import "knowledge-graph-backend/models"
|
||||
|
||||
type GraphService interface {
|
||||
GetGraphData() models.GraphData
|
||||
GetSimpleGraphData() models.SimpleGraphData
|
||||
GetNodeByID(id string) (models.Node, bool)
|
||||
SearchNodes(query string) []models.Node
|
||||
GetNeighbors(nodeID string) (models.NeighborResponse, bool)
|
||||
GetStats() map[string]int
|
||||
|
||||
// 新增增删改接口
|
||||
CreateNode(req models.CreateNodeRequest) (models.Node, error)
|
||||
UpdateNode(id string, req models.UpdateNodeRequest) (models.Node, error)
|
||||
DeleteNode(id string) error
|
||||
|
||||
CreateEdge(req models.CreateEdgeRequest) (models.Edge, error)
|
||||
DeleteEdge(id string) error
|
||||
}
|
||||
Reference in New Issue
Block a user