This commit is contained in:
ivamp 2024-12-10 18:22:14 +08:00
parent 29a8dcf827
commit ce9bd1ccfe
41 changed files with 686 additions and 1258 deletions

View File

@ -50,40 +50,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.DocumentBlock"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -117,10 +93,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "文档块不存在", "description": "文档块不存在",
@ -164,30 +137,15 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -227,40 +185,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -304,22 +238,10 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.DocumentDTO"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
}
]
} }
}, },
"403": { "403": {
@ -353,7 +275,7 @@ const docTemplate = `{
"parameters": [ "parameters": [
{ {
"type": "integer", "type": "integer",
"description": "集<EFBFBD><EFBFBD>ID", "description": "集ID",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
@ -363,19 +285,7 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"404": { "404": {
@ -420,40 +330,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -529,40 +415,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/dto.DocumentDTO"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"403": { "403": {
@ -606,22 +468,10 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/entity.DocumentBlock"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -666,40 +516,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.DocumentBlock"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -737,19 +563,7 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/dto.DocumentDTO"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
]
} }
}, },
"403": { "403": {
@ -800,40 +614,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Document"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Document"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -867,10 +657,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "文档不存在", "description": "文档不存在",
@ -898,22 +685,10 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/entity.Workspace"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
}
]
} }
} }
} }
@ -945,40 +720,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Workspace"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
} }
} }
@ -1010,19 +761,7 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Workspace"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
]
} }
}, },
"404": { "404": {
@ -1056,10 +795,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "工作空间不存在", "description": "工作空间不存在",
@ -1071,6 +807,42 @@ const docTemplate = `{
} }
}, },
"/workspaces/{id}/members": { "/workspaces/{id}/members": {
"get": {
"description": "根据工作空间ID获取工作空间的成员",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Workspace"
],
"summary": "获取工作空间的成员",
"parameters": [
{
"type": "integer",
"description": "工作空间ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/entity.Workspace"
}
},
"404": {
"description": "工作空间不存在",
"schema": {
"$ref": "#/definitions/dto.Response"
}
}
}
},
"post": { "post": {
"description": "向工作空间添加新成员", "description": "向工作空间添加新成员",
"consumes": [ "consumes": [
@ -1105,40 +877,16 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.WorkspaceMember"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.WorkspaceMember"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -1227,22 +975,10 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -1270,7 +1006,6 @@ const docTemplate = `{
"dto.CreateBlockRequest": { "dto.CreateBlockRequest": {
"type": "object", "type": "object",
"required": [ "required": [
"content",
"type" "type"
], ],
"properties": { "properties": {

View File

@ -41,40 +41,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.DocumentBlock"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -108,10 +84,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "文档块不存在", "description": "文档块不存在",
@ -155,30 +128,15 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -218,40 +176,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -295,22 +229,10 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.DocumentDTO"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
}
]
} }
}, },
"403": { "403": {
@ -344,7 +266,7 @@
"parameters": [ "parameters": [
{ {
"type": "integer", "type": "integer",
"description": "集<EFBFBD><EFBFBD>ID", "description": "集ID",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
@ -354,19 +276,7 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"404": { "404": {
@ -411,40 +321,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -520,40 +406,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/dto.DocumentDTO"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"403": { "403": {
@ -597,22 +459,10 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/entity.DocumentBlock"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -657,40 +507,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.DocumentBlock"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.DocumentBlock"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -728,19 +554,7 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/dto.DocumentDTO"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.DocumentDTO"
}
}
}
]
} }
}, },
"403": { "403": {
@ -791,40 +605,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Document"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Document"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -858,10 +648,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "文档不存在", "description": "文档不存在",
@ -889,22 +676,10 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/entity.Workspace"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
}
]
} }
} }
} }
@ -936,40 +711,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Workspace"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
} }
} }
@ -1001,19 +752,7 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.Workspace"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.Workspace"
}
}
}
]
} }
}, },
"404": { "404": {
@ -1047,10 +786,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"$ref": "#/definitions/dto.Response"
}
}, },
"404": { "404": {
"description": "工作空间不存在", "description": "工作空间不存在",
@ -1062,6 +798,42 @@
} }
}, },
"/workspaces/{id}/members": { "/workspaces/{id}/members": {
"get": {
"description": "根据工作空间ID获取工作空间的成员",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Workspace"
],
"summary": "获取工作空间的成员",
"parameters": [
{
"type": "integer",
"description": "工作空间ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/entity.Workspace"
}
},
"404": {
"description": "工作空间不存在",
"schema": {
"$ref": "#/definitions/dto.Response"
}
}
}
},
"post": { "post": {
"description": "向工作空间添加新成员", "description": "向工作空间添加新成员",
"consumes": [ "consumes": [
@ -1096,40 +868,16 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "$ref": "#/definitions/entity.WorkspaceMember"
{
"$ref": "#/definitions/dto.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/entity.WorkspaceMember"
}
}
}
]
} }
}, },
"400": { "400": {
"description": "参数验证失败", "description": "参数验证失败",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/dto.ValidateError"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ValidateError"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -1218,22 +966,10 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"allOf": [ "type": "array",
{ "items": {
"$ref": "#/definitions/dto.Response" "$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}, }
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection"
}
}
}
}
]
} }
}, },
"404": { "404": {
@ -1261,7 +997,6 @@
"dto.CreateBlockRequest": { "dto.CreateBlockRequest": {
"type": "object", "type": "object",
"required": [ "required": [
"content",
"type" "type"
], ],
"properties": { "properties": {

View File

@ -15,7 +15,6 @@ definitions:
type: type:
type: string type: string
required: required:
- content
- type - type
type: object type: object
dto.CreateCollectionRequest: dto.CreateCollectionRequest:
@ -222,8 +221,6 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
schema:
$ref: '#/definitions/dto.Response'
"404": "404":
description: 文档块不存在 description: 文档块不存在
schema: schema:
@ -253,23 +250,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.DocumentBlock'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.DocumentBlock'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 文档块不存在 description: 文档块不存在
schema: schema:
@ -299,19 +286,12 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
schema:
$ref: '#/definitions/dto.Response'
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 文档块不存在 description: 文档块不存在
schema: schema:
@ -337,23 +317,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 工作空间不存在 description: 工作空间不存在
schema: schema:
@ -382,14 +352,9 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.DocumentDTO'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.DocumentDTO'
type: array
type: object
"403": "403":
description: 无权访问 description: 无权访问
schema: schema:
@ -431,7 +396,7 @@ paths:
- application/json - application/json
description: 根据集合ID获取集合详情 description: 根据集合ID获取集合详情
parameters: parameters:
- description: <EFBFBD><EFBFBD>ID - description: ID
in: path in: path
name: id name: id
required: true required: true
@ -442,12 +407,7 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
type: object
"404": "404":
description: 集合不存在 description: 集合不存在
schema: schema:
@ -477,23 +437,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 集合不存在 description: 集合不存在
schema: schema:
@ -519,23 +469,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/dto.DocumentDTO'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/dto.DocumentDTO'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"403": "403":
description: 无权访问 description: 无权访问
schema: schema:
@ -564,14 +504,9 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/entity.DocumentBlock'
- properties: type: array
data:
items:
$ref: '#/definitions/entity.DocumentBlock'
type: array
type: object
"404": "404":
description: 文档不存在 description: 文档不存在
schema: schema:
@ -601,23 +536,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.DocumentBlock'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.DocumentBlock'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 文档不存在 description: 文档不存在
schema: schema:
@ -641,8 +566,6 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
schema:
$ref: '#/definitions/dto.Response'
"404": "404":
description: 文档不存在 description: 文档不存在
schema: schema:
@ -666,12 +589,7 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/dto.DocumentDTO'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/dto.DocumentDTO'
type: object
"403": "403":
description: 无权访问 description: 无权访问
schema: schema:
@ -705,23 +623,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.Document'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.Document'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 文档不存在 description: 文档不存在
schema: schema:
@ -740,14 +648,9 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/entity.Workspace'
- properties: type: array
data:
items:
$ref: '#/definitions/entity.Workspace'
type: array
type: object
summary: 列出工作空间列表 summary: 列出工作空间列表
tags: tags:
- Workspace - Workspace
@ -768,23 +671,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.Workspace'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.Workspace'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
summary: 创建工作空间 summary: 创建工作空间
tags: tags:
- Workspace - Workspace
@ -804,8 +697,6 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
schema:
$ref: '#/definitions/dto.Response'
"404": "404":
description: 工作空间不存在 description: 工作空间不存在
schema: schema:
@ -829,12 +720,7 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.Workspace'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.Workspace'
type: object
"404": "404":
description: 工作空间不存在 description: 工作空间不存在
schema: schema:
@ -843,6 +729,30 @@ paths:
tags: tags:
- Workspace - Workspace
/workspaces/{id}/members: /workspaces/{id}/members:
get:
consumes:
- application/json
description: 根据工作空间ID获取工作空间的成员
parameters:
- description: 工作空间ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/entity.Workspace'
"404":
description: 工作空间不存在
schema:
$ref: '#/definitions/dto.Response'
summary: 获取工作空间的成员
tags:
- Workspace
post: post:
consumes: consumes:
- application/json - application/json
@ -865,23 +775,13 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: $ref: '#/definitions/entity.WorkspaceMember'
- $ref: '#/definitions/dto.Response'
- properties:
data:
$ref: '#/definitions/entity.WorkspaceMember'
type: object
"400": "400":
description: 参数验证失败 description: 参数验证失败
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/dto.ValidateError'
- properties: type: array
data:
items:
$ref: '#/definitions/dto.ValidateError'
type: array
type: object
"404": "404":
description: 工作空间不存在 description: 工作空间不存在
schema: schema:
@ -940,14 +840,9 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
allOf: items:
- $ref: '#/definitions/dto.Response' $ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
- properties: type: array
data:
items:
$ref: '#/definitions/leafdev_top_Leaf_leaf-library-3_internal_entity.Collection'
type: array
type: object
"404": "404":
description: 工作空间不存在 description: 工作空间不存在
schema: schema:

View File

@ -2,16 +2,15 @@ package interceptor
import ( import (
"context" "context"
"leafdev.top/Leaf/leaf-library-3/internal/constants"
"leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/base/logger"
authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/types/constants"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
authInterceptor "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" authInterceptor "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
"google.golang.org/grpc" "google.golang.org/grpc"
"leafdev.top/Leaf/leaf-library-3/internal/base/conf"
"leafdev.top/Leaf/leaf-library-3/internal/base/logger"
authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
) )
var ignoreAuthApis = map[string]bool{ var ignoreAuthApis = map[string]bool{

View File

@ -1,14 +1,17 @@
package controller package controller
import ( import (
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
_ "leafdev.top/Leaf/leaf-library-3/internal/entity" _ "leafdev.top/Leaf/leaf-library-3/internal/entity"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator"
"leafdev.top/Leaf/leaf-library-3/internal/services/auth" "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/services/collection" "leafdev.top/Leaf/leaf-library-3/internal/services/collection"
"leafdev.top/Leaf/leaf-library-3/internal/services/workspace" "leafdev.top/Leaf/leaf-library-3/internal/services/workspace"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
) )
type CollectionController struct { type CollectionController struct {
@ -36,38 +39,38 @@ func NewCollectionController(
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param request body dto.CreateCollectionRequest true "创建集合请求" // @Param request body dto.CreateCollectionRequest true "创建集合请求"
// @Success 200 {object} dto.Response{data=entity.Collection} // @Success 200 {object} entity.Collection
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "工作空间不存在" // @Failure 404 {object} dto.Response "工作空间不存在"
// @Router /collections [post] // @Router /collections [post]
func (c *CollectionController) CreateCollection(ctx *fiber.Ctx) error { func (c *CollectionController) CreateCollection(ctx *fiber.Ctx) error {
var req dto.CreateCollectionRequest var req dto.CreateCollectionRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Message((*validationErrors)[0].Message).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Message((*validationErrors)[0].Message).Status(fiber.StatusBadRequest).Send()
} }
// 检查工作空间是否存在 // 检查工作空间是否存在
exists, err := c.workspaceService.Exists(ctx.Context(), req.WorkspaceID) exists, err := c.workspaceService.Exists(ctx.Context(), req.WorkspaceID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
collection, err := c.collectionService.Create(ctx.Context(), req.WorkspaceID, req.Name) collectionEntity, err := c.collectionService.Create(ctx.Context(), req.WorkspaceID, req.Name)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(collection).Send() return response.Ctx(ctx).Success(collectionEntity).Send()
} }
// GetCollection 获取集合 // GetCollection 获取集合
@ -76,30 +79,30 @@ func (c *CollectionController) CreateCollection(ctx *fiber.Ctx) error {
// @Tags Collection // @Tags Collection
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "集<EFBFBD><EFBFBD>ID" // @Param id path int true "集ID"
// @Success 200 {object} dto.Response{data=entity.Collection} // @Success 200 {object} entity.Collection
// @Failure 404 {object} dto.Response "集合不存在" // @Failure 404 {object} dto.Response "集合不存在"
// @Router /collections/{id} [get] // @Router /collections/{id} [get]
func (c *CollectionController) GetCollection(ctx *fiber.Ctx) error { func (c *CollectionController) GetCollection(ctx *fiber.Ctx) error {
var req dto.GetCollectionRequest var req dto.GetCollectionRequest
if err := ctx.ParamsParser(&req); err != nil { if err := ctx.ParamsParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
exists, err := c.collectionService.Exists(ctx.Context(), req.ID) exists, err := c.collectionService.Exists(ctx.Context(), req.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send()
} }
collection, err := c.collectionService.Get(ctx.Context(), req.ID) collectionEntity, err := c.collectionService.Get(ctx.Context(), req.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(collection).Send() return response.Ctx(ctx).Success(collectionEntity).Send()
} }
// ListCollections 列出工作空间下的所有集合 // ListCollections 列出工作空间下的所有集合
@ -109,30 +112,30 @@ func (c *CollectionController) GetCollection(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param workspace_id path int true "工作空间ID" // @Param workspace_id path int true "工作空间ID"
// @Success 200 {object} dto.Response{data=[]entity.Collection} // @Success 200 {object} []entity.Collection
// @Failure 404 {object} dto.Response "工作空间不存在" // @Failure 404 {object} dto.Response "工作空间不存在"
// @Router /workspaces/{workspace_id}/collections [get] // @Router /workspaces/{workspace_id}/collections [get]
func (c *CollectionController) ListCollections(ctx *fiber.Ctx) error { func (c *CollectionController) ListCollections(ctx *fiber.Ctx) error {
var req dto.ListCollectionsRequest var req dto.ListCollectionsRequest
if err := ctx.ParamsParser(&req); err != nil { if err := ctx.ParamsParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 检<EFBFBD><EFBFBD><EFBFBD>工作空间是否存在 // 检工作空间是否存在
exists, err := c.workspaceService.Exists(ctx.Context(), req.WorkspaceID) exists, err := c.workspaceService.Exists(ctx.Context(), req.WorkspaceID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
collections, err := c.collectionService.List(ctx.Context(), req.WorkspaceID) collections, err := c.collectionService.List(ctx.Context(), req.WorkspaceID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(collections).Send() return response.Ctx(ctx).Success(collections).Send()
} }
// UpdateCollection 更新集合 // UpdateCollection 更新集合
@ -143,59 +146,59 @@ func (c *CollectionController) ListCollections(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param id path int true "集合ID" // @Param id path int true "集合ID"
// @Param request body dto.UpdateCollectionRequest true "更新集合请求" // @Param request body dto.UpdateCollectionRequest true "更新集合请求"
// @Success 200 {object} dto.Response{data=entity.Collection} // @Success 200 {object} entity.Collection
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "集合不存在" // @Failure 404 {object} dto.Response "集合不存在"
// @Router /collections/{id} [put] // @Router /collections/{id} [put]
func (c *CollectionController) UpdateCollection(ctx *fiber.Ctx) error { func (c *CollectionController) UpdateCollection(ctx *fiber.Ctx) error {
var params dto.CollectionIDParam var params dto.CollectionIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var req dto.UpdateCollectionRequest var req dto.UpdateCollectionRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
// 检查集合是否存在 // 检查集合是否存在
collection, err := c.collectionService.Get(ctx.Context(), params.ID) collectionEntity, err := c.collectionService.Get(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if collection == nil { if collectionEntity == nil {
return dto.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该集合 // 检查用户是否有权限访问该集合
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
// 更新集合 // 更新集合
collection, err = c.collectionService.Update(ctx.Context(), params.ID, req.Name) collectionEntity, err = c.collectionService.Update(ctx.Context(), params.ID, req.Name)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(collection).Send() return response.Ctx(ctx).Success(collectionEntity).Send()
} }
// DeleteCollection 删除集合 // DeleteCollection 删除集合
@ -211,38 +214,38 @@ func (c *CollectionController) UpdateCollection(ctx *fiber.Ctx) error {
func (c *CollectionController) DeleteCollection(ctx *fiber.Ctx) error { func (c *CollectionController) DeleteCollection(ctx *fiber.Ctx) error {
var params dto.CollectionIDParam var params dto.CollectionIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 检查集合是否存在 // 检查集合是否存在
collection, err := c.collectionService.Get(ctx.Context(), params.ID) collectionEntity, err := c.collectionService.Get(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if collection == nil { if collectionEntity == nil {
return dto.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该集合 // 检查用户是否有权限访问该集合
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
// 删除集合 // 删除集合
err = c.collectionService.Delete(ctx.Context(), params.ID) err = c.collectionService.Delete(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
} }

View File

@ -2,13 +2,15 @@ package controller
import ( import (
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator"
"leafdev.top/Leaf/leaf-library-3/internal/services/auth" "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/services/collection" "leafdev.top/Leaf/leaf-library-3/internal/services/collection"
"leafdev.top/Leaf/leaf-library-3/internal/services/document" "leafdev.top/Leaf/leaf-library-3/internal/services/document"
"leafdev.top/Leaf/leaf-library-3/internal/services/workspace" "leafdev.top/Leaf/leaf-library-3/internal/services/workspace"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto" "net/http"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
) )
type DocumentController struct { type DocumentController struct {
@ -39,76 +41,76 @@ func NewDocumentController(
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param request body dto.CreateDocumentRequest true "创建文档请求" // @Param request body dto.CreateDocumentRequest true "创建文档请求"
// @Success 200 {object} dto.Response{data=dto.DocumentDTO} // @Success 200 {object} dto.DocumentDTO
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 403 {object} dto.Response "无权访问" // @Failure 403 {object} dto.Response "无权访问"
// @Failure 404 {object} dto.Response "集合不存在或父文档不存在" // @Failure 404 {object} dto.Response "集合不存在或父文档不存在"
// @Router /documents [post] // @Router /documents [post]
func (c *DocumentController) CreateDocument(ctx *fiber.Ctx) error { func (c *DocumentController) CreateDocument(ctx *fiber.Ctx) error {
var req dto.CreateDocumentRequest var req dto.CreateDocumentRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
// 检查集合是否存在 // 检查集合是否存在
collection, err := c.collectionService.Get(ctx.Context(), req.CollectionID) collectionEntity, err := c.collectionService.Get(ctx.Context(), req.CollectionID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if collection == nil { if collectionEntity == nil {
return dto.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该集合 // 检查用户是否有权限访问该集合
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if workspace == nil { if workspaceEntity == nil {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
// 如果是子文档,检查父文档是否存在且属于同一个集合 // 如果是子文档,检查父文档是否存在且属于同一个集合
if req.ParentID != nil { if req.ParentID != nil {
parentDoc, err := c.documentService.Get(ctx.Context(), *req.ParentID) parentDoc, err := c.documentService.Get(ctx.Context(), *req.ParentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if parentDoc == nil { if parentDoc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
if parentDoc.CollectionId != req.CollectionID { if parentDoc.CollectionId != req.CollectionID {
return dto.Ctx(ctx).Error(errs.ErrInvalidParentDocument).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Error(errs.ErrInvalidParentDocument).Status(fiber.StatusBadRequest).Send()
} }
} }
doc, err := c.documentService.Create(ctx.Context(), req.Name, req.WorkspaceID, req.CollectionID, req.ParentID) doc, err := c.documentService.Create(ctx.Context(), req.Name, req.WorkspaceID, req.CollectionID, req.ParentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
docDTO, err := c.documentService.ToDTO(ctx.Context(), doc) docDTO, err := c.documentService.ToDTO(ctx.Context(), doc)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(docDTO).Send() return response.Ctx(ctx).Success(docDTO).Send()
} }
// GetDocument 获取文档 // GetDocument 获取文档
@ -118,49 +120,49 @@ func (c *DocumentController) CreateDocument(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "文档ID" // @Param id path int true "文档ID"
// @Success 200 {object} dto.Response{data=dto.DocumentDTO} // @Success 200 {object} dto.DocumentDTO
// @Failure 403 {object} dto.Response "无权访问" // @Failure 403 {object} dto.Response "无权访问"
// @Failure 404 {object} dto.Response "文档不存在" // @Failure 404 {object} dto.Response "文档不存在"
// @Router /documents/{id} [get] // @Router /documents/{id} [get]
func (c *DocumentController) GetDocument(ctx *fiber.Ctx) error { func (c *DocumentController) GetDocument(ctx *fiber.Ctx) error {
var params dto.DocumentIDParam var params dto.DocumentIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
doc, err := c.documentService.Get(ctx.Context(), params.ID) doc, err := c.documentService.Get(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
docDTO, err := c.documentService.ToDTO(ctx.Context(), doc) docDTO, err := c.documentService.ToDTO(ctx.Context(), doc)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(docDTO).Send() return response.Ctx(ctx).Success(docDTO).Send()
} }
// ListDocuments 列出集合或父文档下的所有文档 // ListDocuments 列出集合或父文档下的所有文档
@ -171,63 +173,63 @@ func (c *DocumentController) GetDocument(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param collection_id path int true "集合ID" // @Param collection_id path int true "集合ID"
// @Param parent_id query int false "父文档ID不传则获取根文档" // @Param parent_id query int false "父文档ID不传则获取根文档"
// @Success 200 {object} dto.Response{data=[]dto.DocumentDTO} // @Success 200 {object} []dto.DocumentDTO
// @Failure 403 {object} dto.Response "无权访问" // @Failure 403 {object} dto.Response "无权访问"
// @Failure 404 {object} dto.Response "集合不存在或父文档不存在" // @Failure 404 {object} dto.Response "集合不存在或父文档不存在"
// @Router /collections/{collection_id}/documents [get] // @Router /collections/{collection_id}/documents [get]
func (c *DocumentController) ListDocuments(ctx *fiber.Ctx) error { func (c *DocumentController) ListDocuments(ctx *fiber.Ctx) error {
var pathParams dto.ListDocumentsPathParam var pathParams dto.ListDocumentsPathParam
if err := ctx.ParamsParser(&pathParams); err != nil { if err := ctx.ParamsParser(&pathParams); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var queryParams dto.ListDocumentsQueryParam var queryParams dto.ListDocumentsQueryParam
if err := ctx.QueryParser(&queryParams); err != nil { if err := ctx.QueryParser(&queryParams); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 检查集合是否存在 // 检查集合是否存在
collection, err := c.collectionService.Get(ctx.Context(), pathParams.CollectionID) collectionEntity, err := c.collectionService.Get(ctx.Context(), pathParams.CollectionID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if collection == nil { if collectionEntity == nil {
return dto.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrCollectionNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该集合 // 检查用户是否有权限访问该集合
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
// 如果指定了父文档,检查父文档是否存在且属于同一个集合 // 如果指定了父文档,检查父文档是否存在且属于同一个集合
if queryParams.ParentID != nil { if queryParams.ParentID != nil {
parentDoc, err := c.documentService.Get(ctx.Context(), *queryParams.ParentID) parentDoc, err := c.documentService.Get(ctx.Context(), *queryParams.ParentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if parentDoc == nil { if parentDoc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
if parentDoc.CollectionId != pathParams.CollectionID { if parentDoc.CollectionId != pathParams.CollectionID {
return dto.Ctx(ctx).Error(errs.ErrInvalidParentDocument).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Error(errs.ErrInvalidParentDocument).Status(fiber.StatusBadRequest).Send()
} }
} }
// 获取文档列表 // 获取文档列表
docs, err := c.documentService.List(ctx.Context(), pathParams.CollectionID, queryParams.ParentID) docs, err := c.documentService.List(ctx.Context(), pathParams.CollectionID, queryParams.ParentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 转换为 DTO // 转换为 DTO
@ -235,12 +237,12 @@ func (c *DocumentController) ListDocuments(ctx *fiber.Ctx) error {
for i, doc := range docs { for i, doc := range docs {
docDTO, err := c.documentService.ToDTO(ctx.Context(), doc) docDTO, err := c.documentService.ToDTO(ctx.Context(), doc)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
dtos[i] = docDTO dtos[i] = docDTO
} }
return dto.Ctx(ctx).Success(dtos).Send() return response.Ctx(ctx).Success(dtos).Send()
} }
// UpdateDocument 更新文档 // UpdateDocument 更新文档
@ -251,39 +253,39 @@ func (c *DocumentController) ListDocuments(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param id path int true "文档ID" // @Param id path int true "文档ID"
// @Param request body dto.UpdateDocumentRequest true "更新文档请求" // @Param request body dto.UpdateDocumentRequest true "更新文档请求"
// @Success 200 {object} dto.Response{data=entity.Document} // @Success 200 {object} entity.Document
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "文档不存在" // @Failure 404 {object} dto.Response "文档不存在"
// @Router /documents/{id} [put] // @Router /documents/{id} [put]
func (c *DocumentController) UpdateDocument(ctx *fiber.Ctx) error { func (c *DocumentController) UpdateDocument(ctx *fiber.Ctx) error {
var params dto.DocumentIDParam var params dto.DocumentIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var req dto.UpdateDocumentRequest var req dto.UpdateDocumentRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
doc, err := c.documentService.Update(ctx.Context(), params.ID, req.Name) doc, err := c.documentService.Update(ctx.Context(), params.ID, req.Name)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
docDTO, err := c.documentService.ToDTO(ctx.Context(), doc) docDTO, err := c.documentService.ToDTO(ctx.Context(), doc)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(docDTO).Send() return response.Ctx(ctx).Success(docDTO).Send()
} }
// DeleteDocument 删除文档 // DeleteDocument 删除文档
@ -293,21 +295,21 @@ func (c *DocumentController) UpdateDocument(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "文档ID" // @Param id path int true "文档ID"
// @Success 200 {object} dto.Response // @Success 200
// @Failure 404 {object} dto.Response "文档不存在" // @Failure 404 {object} dto.Response "文档不存在"
// @Router /documents/{id} [delete] // @Router /documents/{id} [delete]
func (c *DocumentController) DeleteDocument(ctx *fiber.Ctx) error { func (c *DocumentController) DeleteDocument(ctx *fiber.Ctx) error {
var params dto.DocumentIDParam var params dto.DocumentIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
err := c.documentService.Delete(ctx.Context(), params.ID) err := c.documentService.Delete(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
} }
// CreateBlock 创建文档块 // CreateBlock 创建文档块
@ -318,59 +320,59 @@ func (c *DocumentController) DeleteDocument(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param document_id path int true "文档ID" // @Param document_id path int true "文档ID"
// @Param request body dto.CreateBlockRequest true "创建文档块请求" // @Param request body dto.CreateBlockRequest true "创建文档块请求"
// @Success 200 {object} dto.Response{data=entity.DocumentBlock} // @Success 200 {object} entity.DocumentBlock
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "文档不存在" // @Failure 404 {object} dto.Response "文档不存在"
// @Router /documents/{document_id}/blocks [post] // @Router /documents/{document_id}/blocks [post]
func (c *DocumentController) CreateBlock(ctx *fiber.Ctx) error { func (c *DocumentController) CreateBlock(ctx *fiber.Ctx) error {
var params dto.ListBlocksRequest var params dto.ListBlocksRequest
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var req dto.CreateBlockRequest var req dto.CreateBlockRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
return dto.Ctx(ctx).Data(validationErrors).Error(err).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Error(err).Status(fiber.StatusBadRequest).Send()
} }
// 检查文档是否存在 // 检查文档是否存在
doc, err := c.documentService.Get(ctx.Context(), params.DocumentID) doc, err := c.documentService.Get(ctx.Context(), params.DocumentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
block, err := c.documentService.CreateBlock(ctx.Context(), params.DocumentID, req.Type, req.Content, req.AfterBlockID) block, err := c.documentService.CreateBlock(ctx.Context(), params.DocumentID, req.Type, req.Content, req.AfterBlockID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(block).Send() return response.Ctx(ctx).Success(block).Send()
} }
// UpdateBlock 更新文档块 // UpdateBlock 更新文档块
@ -381,71 +383,71 @@ func (c *DocumentController) CreateBlock(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param block_id path int true "文档块ID" // @Param block_id path int true "文档块ID"
// @Param request body dto.UpdateBlockRequest true "更新文档块请求" // @Param request body dto.UpdateBlockRequest true "更新文档块请求"
// @Success 200 {object} dto.Response{data=entity.DocumentBlock} // @Success 200 {object} entity.DocumentBlock
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "文档块不存在" // @Failure 404 {object} dto.Response "文档块不存在"
// @Router /blocks/{block_id} [put] // @Router /blocks/{block_id} [put]
func (c *DocumentController) UpdateBlock(ctx *fiber.Ctx) error { func (c *DocumentController) UpdateBlock(ctx *fiber.Ctx) error {
var params dto.BlockIDParam var params dto.BlockIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var req dto.UpdateBlockRequest var req dto.UpdateBlockRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
// 获取块信息 // 获取块信息
block, err := c.documentService.GetBlock(ctx.Context(), params.ID) block, err := c.documentService.GetBlock(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if block == nil { if block == nil {
return dto.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查文档是否存在 // 检查文档是否存在
doc, err := c.documentService.Get(ctx.Context(), block.DocumentId) doc, err := c.documentService.Get(ctx.Context(), block.DocumentId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
block, err = c.documentService.UpdateBlock(ctx.Context(), params.ID, req.Content) block, err = c.documentService.UpdateBlock(ctx.Context(), params.ID, req.Content)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(block).Send() return response.Ctx(ctx).Success(block).Send()
} }
// DeleteBlock <20><><EFBFBD>除文档块 // DeleteBlock <20><><EFBFBD>除文档块
@ -455,58 +457,58 @@ func (c *DocumentController) UpdateBlock(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param block_id path int true "文档块ID" // @Param block_id path int true "文档块ID"
// @Success 200 {object} dto.Response // @Success 200
// @Failure 404 {object} dto.Response "文档块不存在" // @Failure 404 {object} dto.Response "文档块不存在"
// @Router /blocks/{block_id} [delete] // @Router /blocks/{block_id} [delete]
func (c *DocumentController) DeleteBlock(ctx *fiber.Ctx) error { func (c *DocumentController) DeleteBlock(ctx *fiber.Ctx) error {
var params dto.BlockIDParam var params dto.BlockIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 获取块信息 // 获取块信息
block, err := c.documentService.GetBlock(ctx.Context(), params.ID) block, err := c.documentService.GetBlock(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if block == nil { if block == nil {
return dto.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查文档是否存在 // 检查文档是否存在
doc, err := c.documentService.Get(ctx.Context(), block.DocumentId) doc, err := c.documentService.Get(ctx.Context(), block.DocumentId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
err = c.documentService.DeleteBlock(ctx.Context(), params.ID) err = c.documentService.DeleteBlock(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
} }
// ListBlocks 列出文档下的所有块 // ListBlocks 列出文档下的所有块
@ -516,49 +518,49 @@ func (c *DocumentController) DeleteBlock(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param document_id path int true "文档ID" // @Param document_id path int true "文档ID"
// @Success 200 {object} dto.Response{data=[]entity.DocumentBlock} // @Success 200 {object} []entity.DocumentBlock
// @Failure 404 {object} dto.Response "文档不存在" // @Failure 404 {object} dto.Response "文档不存在"
// @Router /documents/{document_id}/blocks [get] // @Router /documents/{document_id}/blocks [get]
func (c *DocumentController) ListBlocks(ctx *fiber.Ctx) error { func (c *DocumentController) ListBlocks(ctx *fiber.Ctx) error {
var params dto.ListBlocksRequest var params dto.ListBlocksRequest
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 检查文档是否存在 // 检查文档是否存在
doc, err := c.documentService.Get(ctx.Context(), params.DocumentID) doc, err := c.documentService.Get(ctx.Context(), params.DocumentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
blocks, err := c.documentService.ListBlocks(ctx.Context(), params.DocumentID) blocks, err := c.documentService.ListBlocks(ctx.Context(), params.DocumentID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(blocks).Send() return response.Ctx(ctx).Success(blocks).Send()
} }
// MoveBlock 移动文档块 // MoveBlock 移动文档块
@ -569,62 +571,62 @@ func (c *DocumentController) ListBlocks(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param block_id path int true "文档块ID" // @Param block_id path int true "文档块ID"
// @Param request body dto.MoveBlockRequest true "移动文档块请求" // @Param request body dto.MoveBlockRequest true "移动文档块请求"
// @Success 200 {object} dto.Response // @Success 200
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "文档块不存在" // @Failure 404 {object} dto.Response "文档块不存在"
// @Router /blocks/{block_id}/move [post] // @Router /blocks/{block_id}/move [post]
func (c *DocumentController) MoveBlock(ctx *fiber.Ctx) error { func (c *DocumentController) MoveBlock(ctx *fiber.Ctx) error {
var params dto.BlockIDParam var params dto.BlockIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
var req dto.MoveBlockRequest var req dto.MoveBlockRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
// 获取块信息 // 获取块信息
block, err := c.documentService.GetBlock(ctx.Context(), params.ID) block, err := c.documentService.GetBlock(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if block == nil { if block == nil {
return dto.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrBlockNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查文档是否存在 // 检查文档是否存在
doc, err := c.documentService.Get(ctx.Context(), block.DocumentId) doc, err := c.documentService.Get(ctx.Context(), block.DocumentId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if doc == nil { if doc == nil {
return dto.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrDocumentNotExists).Status(fiber.StatusNotFound).Send()
} }
// 检查用户是否有权限访问该文档 // 检查用户是否有权限访问该文档
user := c.authService.GetUser(ctx) user := c.authService.GetUser(ctx)
collection, err := c.collectionService.Get(ctx.Context(), doc.CollectionId) collectionEntity, err := c.collectionService.Get(ctx.Context(), doc.CollectionId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), collection.WorkspaceId) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), collectionEntity.WorkspaceId)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspace) isMember, err := c.workspaceService.IsMember(ctx.Context(), user.ID, workspaceEntity)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !isMember { if !isMember {
return dto.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send() return response.Ctx(ctx).Error(errs.ErrNoPermission).Status(fiber.StatusForbidden).Send()
} }
err = c.documentService.MoveBlock(ctx.Context(), params.ID, req.AfterBlockID) err = c.documentService.MoveBlock(ctx.Context(), params.ID, req.AfterBlockID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
} }

View File

@ -1,14 +1,18 @@
package controller package controller
import ( import (
"errors"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/dto/user"
_ "leafdev.top/Leaf/leaf-library-3/internal/entity" _ "leafdev.top/Leaf/leaf-library-3/internal/entity"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator"
"leafdev.top/Leaf/leaf-library-3/internal/services/auth" "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/services/workspace" "leafdev.top/Leaf/leaf-library-3/internal/services/workspace"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
"leafdev.top/Leaf/leaf-library-3/internal/types/user"
) )
type WorkspaceController struct { type WorkspaceController struct {
@ -30,32 +34,32 @@ func NewWorkspaceController(workspaceService *workspace.Service, authService *au
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param request body dto.CreateWorkspaceRequest true "创建工作空间请求" // @Param request body dto.CreateWorkspaceRequest true "创建工作空间请求"
// @Success 200 {object} dto.Response{data=entity.Workspace} // @Success 200 {object} entity.Workspace
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Router /workspaces [post] // @Router /workspaces [post]
func (c *WorkspaceController) CreateWorkspace(ctx *fiber.Ctx) error { func (c *WorkspaceController) CreateWorkspace(ctx *fiber.Ctx) error {
var req dto.CreateWorkspaceRequest var req dto.CreateWorkspaceRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
// 从上下文获取用户ID // 从上下文获取用户ID
user := c.authService.GetUser(ctx) authUser := c.authService.GetUser(ctx)
userId := user.ID userId := authUser.ID
workspace, err := c.workspaceService.Create(ctx.Context(), userId, req.Name) workspaceEntity, err := c.workspaceService.Create(ctx.Context(), userId, req.Name)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(workspace).Send() return response.Ctx(ctx).Success(workspaceEntity).Send()
} }
// GetWorkspace 获取工作空间 // GetWorkspace 获取工作空间
@ -65,29 +69,29 @@ func (c *WorkspaceController) CreateWorkspace(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "工作空间ID" // @Param id path int true "工作空间ID"
// @Success 200 {object} dto.Response{data=entity.Workspace} // @Success 200 {object} entity.Workspace
// @Failure 404 {object} dto.Response "工作空间不存在" // @Failure 404 {object} dto.Response "工作空间不存在"
// @Router /workspaces/{id} [get] // @Router /workspaces/{id} [get]
func (c *WorkspaceController) GetWorkspace(ctx *fiber.Ctx) error { func (c *WorkspaceController) GetWorkspace(ctx *fiber.Ctx) error {
var params dto.WorkspaceIDParam var params dto.WorkspaceIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
exists, err := c.workspaceService.Exists(ctx.Context(), params.ID) exists, err := c.workspaceService.Exists(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), params.ID) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(workspace).Send() return response.Ctx(ctx).Success(workspaceEntity).Send()
} }
// ListWorkspaces 列出用户的所有工作空间 // ListWorkspaces 列出用户的所有工作空间
@ -96,19 +100,18 @@ func (c *WorkspaceController) GetWorkspace(ctx *fiber.Ctx) error {
// @Tags Workspace // @Tags Workspace
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Success 200 {object} dto.Response{data=[]entity.Workspace} // @Success 200 {object} []entity.Workspace
// @Router /workspaces [get] // @Router /workspaces [get]
func (c *WorkspaceController) ListWorkspaces(ctx *fiber.Ctx) error { func (c *WorkspaceController) ListWorkspaces(ctx *fiber.Ctx) error {
// 从上下文获取用户ID // 从上下文获取用户ID
user := c.authService.GetUser(ctx) authUser := c.authService.GetUser(ctx)
userId := user.ID
workspaces, err := c.workspaceService.List(ctx.Context(), userId) workspaces, err := c.workspaceService.List(ctx.Context(), authUser.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(workspaces).Send() return response.Ctx(ctx).Success(workspaces).Send()
} }
// DeleteWorkspace 删除工作空间 // DeleteWorkspace 删除工作空间
@ -118,29 +121,66 @@ func (c *WorkspaceController) ListWorkspaces(ctx *fiber.Ctx) error {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "工作空间ID" // @Param id path int true "工作空间ID"
// @Success 200 {object} dto.Response // @Success 200
// @Failure 404 {object} dto.Response "工作空间不存在" // @Failure 404 {object} dto.Response "工作空间不存在"
// @Router /workspaces/{id} [delete] // @Router /workspaces/{id} [delete]
func (c *WorkspaceController) DeleteWorkspace(ctx *fiber.Ctx) error { func (c *WorkspaceController) DeleteWorkspace(ctx *fiber.Ctx) error {
var params dto.WorkspaceIDParam var params dto.WorkspaceIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
exists, err := c.workspaceService.Exists(ctx.Context(), params.ID) exists, err := c.workspaceService.Exists(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
err = c.workspaceService.DeleteWorkspace(ctx.Context(), params.ID) err = c.workspaceService.DeleteWorkspace(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
}
// GetWorkspaceMembers 获取工作空间的成员
// @Summary 获取工作空间的成员
// @Description 根据工作空间ID获取工作空间的成员
// @Tags Workspace
// @Accept json
// @Produce json
// @Param id path int true "工作空间ID"
// @Success 200 {object} entity.Workspace
// @Failure 404 {object} dto.Response "工作空间不存在"
// @Router /workspaces/{id}/members [get]
func (c *WorkspaceController) GetWorkspaceMembers(ctx *fiber.Ctx) error {
var params dto.WorkspaceIDParam
if err := ctx.ParamsParser(&params); err != nil {
return response.Ctx(ctx).Status(http.StatusBadRequest).Send()
}
exists, err := c.workspaceService.Exists(ctx.Context(), params.ID)
if err != nil {
return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
}
if !exists {
return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
}
workspaceEntity, err := c.workspaceService.Get(ctx.Context(), params.ID)
if err != nil {
return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
}
workspaceMembers, err := c.workspaceService.ListMembers(ctx.Context(), workspaceEntity)
if err != nil {
return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
}
return response.Ctx(ctx).Success(workspaceMembers).Send()
} }
// AddMember 添加工作空间成员 // AddMember 添加工作空间成员
@ -151,51 +191,51 @@ func (c *WorkspaceController) DeleteWorkspace(ctx *fiber.Ctx) error {
// @Produce json // @Produce json
// @Param id path int true "工作空间ID" // @Param id path int true "工作空间ID"
// @Param request body dto.AddWorkspaceMemberRequest true "添加成员请求" // @Param request body dto.AddWorkspaceMemberRequest true "添加成员请求"
// @Success 200 {object} dto.Response{data=entity.WorkspaceMember} // @Success 200 {object} entity.WorkspaceMember
// @Failure 400 {object} dto.Response{data=[]dto.ValidateError} "参数验证失败" // @Failure 400 {object} []dto.ValidateError "参数验证失败"
// @Failure 404 {object} dto.Response "工作空间不存在" // @Failure 404 {object} dto.Response "工作空间不存在"
// @Failure 409 {object} dto.Response "成员已存在" // @Failure 409 {object} dto.Response "成员已存在"
// @Router /workspaces/{id}/members [post] // @Router /workspaces/{id}/members [post]
func (c *WorkspaceController) AddMember(ctx *fiber.Ctx) error { func (c *WorkspaceController) AddMember(ctx *fiber.Ctx) error {
var params dto.WorkspaceIDParam var params dto.WorkspaceIDParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
exists, err := c.workspaceService.Exists(ctx.Context(), params.ID) exists, err := c.workspaceService.Exists(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
var req dto.AddWorkspaceMemberRequest var req dto.AddWorkspaceMemberRequest
if err := ctx.BodyParser(&req); err != nil { if err := ctx.BodyParser(&req); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if validationErrors, ok, err := validator.Struct(req); !ok { if validationErrors, ok, err := validator.Struct(req); !ok {
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send() return response.Ctx(ctx).Data(validationErrors).Status(fiber.StatusBadRequest).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), params.ID) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), params.ID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
member, err := c.workspaceService.AddMember(ctx.Context(), req.UserID, workspace) member, err := c.workspaceService.AddMember(ctx.Context(), req.UserID, workspaceEntity)
if err != nil { if err != nil {
if err == errs.ErrMemberAlreadyExists { if errors.Is(err, errs.ErrMemberAlreadyExists) {
return dto.Ctx(ctx).Error(err).Status(fiber.StatusConflict).Send() return response.Ctx(ctx).Error(err).Status(fiber.StatusConflict).Send()
} }
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(member).Send() return response.Ctx(ctx).Success(member).Send()
} }
// RemoveMember 移除工作空间成员 // RemoveMember 移除工作空间成员
@ -212,29 +252,29 @@ func (c *WorkspaceController) AddMember(ctx *fiber.Ctx) error {
func (c *WorkspaceController) RemoveMember(ctx *fiber.Ctx) error { func (c *WorkspaceController) RemoveMember(ctx *fiber.Ctx) error {
var params dto.WorkspaceMemberParam var params dto.WorkspaceMemberParam
if err := ctx.ParamsParser(&params); err != nil { if err := ctx.ParamsParser(&params); err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
exists, err := c.workspaceService.Exists(ctx.Context(), params.WorkspaceID) exists, err := c.workspaceService.Exists(ctx.Context(), params.WorkspaceID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
if !exists { if !exists {
return dto.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(errs.ErrWorkspaceNotExists).Status(fiber.StatusNotFound).Send()
} }
workspace, err := c.workspaceService.Get(ctx.Context(), params.WorkspaceID) workspaceEntity, err := c.workspaceService.Get(ctx.Context(), params.WorkspaceID)
if err != nil { if err != nil {
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
err = c.workspaceService.RemoveMember(ctx.Context(), user.ID(params.UserID), workspace) err = c.workspaceService.RemoveMember(ctx.Context(), user.ID(params.UserID), workspaceEntity)
if err != nil { if err != nil {
if err == errs.ErrMemberNotExists { if errors.Is(err, errs.ErrMemberNotExists) {
return dto.Ctx(ctx).Error(err).Status(fiber.StatusNotFound).Send() return response.Ctx(ctx).Error(err).Status(fiber.StatusNotFound).Send()
} }
return err return response.Ctx(ctx).Status(http.StatusInternalServerError).Send()
} }
return dto.Ctx(ctx).Success(nil).Send() return response.Ctx(ctx).Success(nil).Send()
} }

View File

@ -1,18 +1,18 @@
package middleware package middleware
import ( import (
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http" "net/http"
"slices" "slices"
"strings" "strings"
"leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/constants"
authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth" authType "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
"leafdev.top/Leaf/leaf-library-3/internal/types/constants" "leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
authType "leafdev.top/Leaf/leaf-library-3/internal/types/user"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"leafdev.top/Leaf/leaf-library-3/internal/base/conf"
authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
) )
type Auth struct { type Auth struct {
@ -33,7 +33,7 @@ func NewAuth(config *conf.Config, authService *authService.Service) *Auth {
func (a *Auth) Handler() fiber.Handler { func (a *Auth) Handler() fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
var r = dto.Ctx(c) var r = response.Ctx(c)
var err error var err error
var token = new(authType.User) var token = new(authType.User)

View File

@ -2,14 +2,15 @@ package middleware
import ( import (
"fmt" "fmt"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http" "net/http"
"strings" "strings"
userPkg "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/base/conf"
"leafdev.top/Leaf/leaf-library-3/internal/services/auth" "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
userPkg "leafdev.top/Leaf/leaf-library-3/internal/types/user"
) )
type RBAC struct { type RBAC struct {
@ -21,11 +22,11 @@ func (m *RBAC) RoutePermission() fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
user, ok := m.authService.GetUserSafe(c) user, ok := m.authService.GetUserSafe(c)
if !ok { if !ok {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
if !user.Valid { if !user.Valid {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
var path = cleanPath(c.Path()) var path = cleanPath(c.Path())
@ -35,7 +36,7 @@ func (m *RBAC) RoutePermission() fiber.Handler {
pass := user.HasPermissions(permissionName) pass := user.HasPermissions(permissionName)
if !pass { if !pass {
return dto.Ctx(c). return response.Ctx(c).
Message(fmt.Sprintf("permission denied, permission name: %s", permissionName)). Message(fmt.Sprintf("permission denied, permission name: %s", permissionName)).
Error(nil). Error(nil).
Status(http.StatusForbidden). Status(http.StatusForbidden).
@ -50,11 +51,11 @@ func (m *RBAC) RequirePermissions(permissions ...string) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
user, ok := m.authService.GetUserSafe(c) user, ok := m.authService.GetUserSafe(c)
if !ok { if !ok {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
if !user.Valid { if !user.Valid {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
var pass = true var pass = true
@ -72,7 +73,7 @@ func (m *RBAC) RequirePermissions(permissions ...string) fiber.Handler {
} }
if !pass { if !pass {
return dto.Ctx(c). return response.Ctx(c).
Message(fmt.Sprintf("permission denied, required permissions: %s, failed permission: %s", Message(fmt.Sprintf("permission denied, required permissions: %s, failed permission: %s",
permissions, failedPermissionName)). permissions, failedPermissionName)).
Error(nil). Error(nil).
@ -88,11 +89,11 @@ func (m *RBAC) RequireRoles(roles ...string) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
user, ok := m.authService.GetUserSafe(c) user, ok := m.authService.GetUserSafe(c)
if !ok { if !ok {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
if !user.Valid { if !user.Valid {
return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send()
} }
var pass = true var pass = true
@ -110,7 +111,7 @@ func (m *RBAC) RequireRoles(roles ...string) fiber.Handler {
} }
if !pass { if !pass {
return dto.Ctx(c). return response.Ctx(c).
Message(fmt.Sprintf("permission denied, required roles: %s, failed role %s", roles, failedRoleName)). Message(fmt.Sprintf("permission denied, required roles: %s, failed role %s", roles, failedRoleName)).
Error(nil). Error(nil).
Status(http.StatusForbidden). Status(http.StatusForbidden).

View File

@ -2,24 +2,25 @@ package server
import ( import (
"errors" "errors"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http" "net/http"
errs2 "leafdev.top/Leaf/leaf-library-3/internal/errs"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"gorm.io/gorm" "gorm.io/gorm"
"leafdev.top/Leaf/leaf-library-3/internal/base/logger" "leafdev.top/Leaf/leaf-library-3/internal/base/logger"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
) )
func errorConverter(logger *logger.Logger, ctx *fiber.Ctx, err error) error { func errorConverter(logger *logger.Logger, ctx *fiber.Ctx, err error) error {
status := http.StatusInternalServerError status := http.StatusInternalServerError
if err == nil { if err == nil {
return dto.Ctx(ctx).Error(errs.ErrInternalServerError).Status(status).Send() return response.Ctx(ctx).Error(errs2.ErrInternalServerError).Status(status).Send()
} }
var errorMsg dto.IError var errorMsg response.IError
switch { switch {
// 404 // 404
@ -31,20 +32,20 @@ func errorConverter(logger *logger.Logger, ctx *fiber.Ctx, err error) error {
status = http.StatusUnprocessableEntity status = http.StatusUnprocessableEntity
errorMsg = err errorMsg = err
case errors.Is(err, errs.ErrPermissionDenied): case errors.Is(err, errs2.ErrPermissionDenied):
status = http.StatusForbidden status = http.StatusForbidden
case errors.Is(err, validator.ErrValidationFailed): case errors.Is(err, validator.ErrValidationFailed):
status = http.StatusBadRequest status = http.StatusBadRequest
case errors.Is(err, gorm.ErrRecordNotFound): case errors.Is(err, gorm.ErrRecordNotFound):
errorMsg = errs.ErrNotFound errorMsg = errs2.ErrNotFound
status = http.StatusNotFound status = http.StatusNotFound
default: default:
logger.Sugar.Errorf("fiber error: %s", err) logger.Sugar.Errorf("fiber error: %s", err)
errorMsg = errs.UnknownError errorMsg = errs2.UnknownError
} }
return dto.Ctx(ctx).Status(status).Error(errorMsg).Send() return response.Ctx(ctx).Status(status).Error(errorMsg).Send()
} }

View File

@ -1,9 +1,12 @@
package server package server
import ( import (
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"net/http" "net/http"
"strings" "strings"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"github.com/ansrivas/fiberprometheus/v2" "github.com/ansrivas/fiberprometheus/v2"
"github.com/bytedance/sonic" "github.com/bytedance/sonic"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
@ -14,8 +17,6 @@ import (
"leafdev.top/Leaf/leaf-library-3/internal/base/logger" "leafdev.top/Leaf/leaf-library-3/internal/base/logger"
"leafdev.top/Leaf/leaf-library-3/internal/router" "leafdev.top/Leaf/leaf-library-3/internal/router"
"leafdev.top/Leaf/leaf-library-3/internal/services/auth" "leafdev.top/Leaf/leaf-library-3/internal/services/auth"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
) )
type HttpServer struct { type HttpServer struct {
@ -83,7 +84,7 @@ func (hs *HttpServer) BizRouter() *fiber.App {
// 404 Route // 404 Route
hs.Fiber.Use(func(ctx *fiber.Ctx) error { hs.Fiber.Use(func(ctx *fiber.Ctx) error {
return dto.Ctx(ctx).Status(fiber.StatusNotFound).Error(errs.RouteNotFound).Send() return response.Ctx(ctx).Status(fiber.StatusNotFound).Error(errs.RouteNotFound).Send()
}) })
return hs.Fiber return hs.Fiber

View File

@ -1,7 +1,7 @@
package constants package constants
import ( import (
"leafdev.top/Leaf/leaf-library-3/internal/types/user" "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
) )
const ( const (

View File

@ -1,7 +1,7 @@
package dto package dto
import ( import (
"leafdev.top/Leaf/leaf-library-3/internal/types/user" "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
) )
type CurrentUserResponse struct { type CurrentUserResponse struct {

View File

@ -1,6 +1,8 @@
package dto package dto
import "leafdev.top/Leaf/leaf-library-3/internal/types/user" import (
"leafdev.top/Leaf/leaf-library-3/internal/dto/user"
)
// CreateWorkspaceRequest 创建工作空间请求 // CreateWorkspaceRequest 创建工作空间请求
type CreateWorkspaceRequest struct { type CreateWorkspaceRequest struct {

View File

@ -2,7 +2,7 @@ package entity
import ( import (
"gorm.io/gorm" "gorm.io/gorm"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto" "leafdev.top/Leaf/leaf-library-3/internal/dto"
) )
type Collection struct { type Collection struct {

View File

@ -2,7 +2,7 @@ package entity
import ( import (
"gorm.io/gorm" "gorm.io/gorm"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto" "leafdev.top/Leaf/leaf-library-3/internal/dto"
) )
type Document struct { type Document struct {

View File

@ -3,7 +3,7 @@ package entity
import ( import (
"time" "time"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto" "leafdev.top/Leaf/leaf-library-3/internal/dto"
) )
// Model 是所有 entity 的基类,后期要将所有的 Base 改成这种形式 // Model 是所有 entity 的基类,后期要将所有的 Base 改成这种形式

View File

@ -2,8 +2,8 @@ package entity
import ( import (
"gorm.io/gorm" "gorm.io/gorm"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto" "leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/user" "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
) )
type Workspace struct { type Workspace struct {

View File

@ -1,4 +1,4 @@
package dto package response
import ( import (
"net/http" "net/http"
@ -18,10 +18,9 @@ type ValidateError struct {
type Body struct { type Body struct {
Message string `json:"message"` Message string `json:"message"`
Error string `json:"error"` Error string `json:"error"`
//ValidationErrors *[]ValidateError `json:"validation_error,omitempty"` Success bool `json:"success"`
Success bool `json:"success"` Data any `json:"data,omitempty"`
Data any `json:"data,omitempty"` Wrap bool `json:"-"`
Wrap bool `json:"-"`
} }
type Response struct { type Response struct {
@ -33,7 +32,7 @@ type Response struct {
func Ctx(c *fiber.Ctx) *Response { func Ctx(c *fiber.Ctx) *Response {
return &Response{ return &Response{
body: &Body{ body: &Body{
Wrap: true, Wrap: false,
}, },
ctx: c, ctx: c,
httpStatus: 0, httpStatus: 0,
@ -50,13 +49,7 @@ func (r *Response) Message(message string) *Response {
return r return r
} }
// WithoutWrap 将不在 body 中包裹 data // Wrap 将在响应中包裹 data
func (r *Response) WithoutWrap() *Response {
r.body.Wrap = false
return r
}
func (r *Response) Wrap() *Response { func (r *Response) Wrap() *Response {
r.body.Wrap = true r.body.Wrap = true
return r return r
@ -108,11 +101,27 @@ func (r *Response) Send() error {
} }
} }
if r.body.Wrap { // if 400 bad request but not have message
return r.ctx.Status(r.httpStatus).JSON(r.body) if r.httpStatus == http.StatusBadRequest {
if r.body.Message == "" {
r.Message("Bad request")
}
} }
return r.ctx.Status(r.httpStatus).JSON(r.body.Data) var rspCtx = r.ctx.Status(r.httpStatus)
var rspErr error
if r.body.Data == nil {
return rspCtx.Send([]byte{})
}
if r.body.Wrap {
rspErr = rspCtx.JSON(r.body)
}
rspErr = rspCtx.JSON(r.body.Data)
return rspErr
} }
func (r *Response) Success(data any) *Response { func (r *Response) Success(data any) *Response {

View File

@ -2,9 +2,9 @@ package validator
import ( import (
"errors" "errors"
"leafdev.top/Leaf/leaf-library-3/internal/pkg/response"
"github.com/gookit/validate" "github.com/gookit/validate"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
) )
var ( var (
@ -27,11 +27,11 @@ func init() {
}) })
} }
func Struct(data interface{}) (validationErrors *[]dto.ValidateError, ok bool, err error) { func Struct(data interface{}) (validationErrors *[]response.ValidateError, ok bool, err error) {
v := validate.Struct(data) v := validate.Struct(data)
var e error var e error
var ves []dto.ValidateError var ves []response.ValidateError
if v.Validate() { if v.Validate() {
return &ves, true, nil // 返回指针 return &ves, true, nil // 返回指针
@ -39,7 +39,7 @@ func Struct(data interface{}) (validationErrors *[]dto.ValidateError, ok bool, e
e = ErrValidationFailed e = ErrValidationFailed
for _, err := range v.Errors { for _, err := range v.Errors {
ves = append(ves, dto.ValidateError{ ves = append(ves, response.ValidateError{
Message: err.String(), Message: err.String(),
}) })
} }

View File

@ -2,10 +2,9 @@ package auth
import ( import (
"context" "context"
"leafdev.top/Leaf/leaf-library-3/internal/constants"
"leafdev.top/Leaf/leaf-library-3/internal/types/constants" "leafdev.top/Leaf/leaf-library-3/internal/dto/user"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs" errs2 "leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/types/user"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
@ -82,24 +81,24 @@ func (a *Service) parseUserJWT(tokenType constants.JwtTokenTypes, jwtToken strin
} else { } else {
token, err := a.jwks.ParseJWT(jwtToken) token, err := a.jwks.ParseJWT(jwtToken)
if err != nil { if err != nil {
return nil, errs.NotValidToken return nil, errs2.NotValidToken
} }
subStr, err := token.Claims.GetSubject() subStr, err := token.Claims.GetSubject()
if err != nil { if err != nil {
return nil, errs.NotValidToken return nil, errs2.NotValidToken
} }
sub = user.ID(subStr) sub = user.ID(subStr)
// 如果 token.Header 中没有 typ // 如果 token.Header 中没有 typ
if token.Header["typ"] == "" { if token.Header["typ"] == "" {
return nil, errs.EmptyResponse return nil, errs2.EmptyResponse
} }
// 验证 token 类型 // 验证 token 类型
if tokenType != "" && tokenType.String() != token.Header["typ"] { if tokenType != "" && tokenType.String() != token.Header["typ"] {
return nil, errs.TokenError return nil, errs2.TokenError
} }
jwtIdToken.Valid = true jwtIdToken.Valid = true

View File

@ -3,9 +3,10 @@ package collection
import ( import (
"context" "context"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/entity" "leafdev.top/Leaf/leaf-library-3/internal/entity"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
) )
func (s *Service) Get(ctx context.Context, collectionId dto.EntityId) (*entity.Collection, error) { func (s *Service) Get(ctx context.Context, collectionId dto.EntityId) (*entity.Collection, error) {

View File

@ -8,8 +8,8 @@ import (
"time" "time"
"gorm.io/gorm" "gorm.io/gorm"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/entity" "leafdev.top/Leaf/leaf-library-3/internal/entity"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
) )
// Get 获取文档 // Get 获取文档

View File

@ -2,10 +2,10 @@ package stream
import ( import (
"context" "context"
"leafdev.top/Leaf/leaf-library-3/internal/events"
"time" "time"
"github.com/segmentio/kafka-go" "github.com/segmentio/kafka-go"
"leafdev.top/Leaf/leaf-library-3/internal/types/events"
) )
//var connections = map[string]*kafka.Conn{} //var connections = map[string]*kafka.Conn{}

View File

@ -3,10 +3,11 @@ package workspace
import ( import (
"context" "context"
"leafdev.top/Leaf/leaf-library-3/internal/dto/user"
"leafdev.top/Leaf/leaf-library-3/internal/errs"
"leafdev.top/Leaf/leaf-library-3/internal/dto"
"leafdev.top/Leaf/leaf-library-3/internal/entity" "leafdev.top/Leaf/leaf-library-3/internal/entity"
"leafdev.top/Leaf/leaf-library-3/internal/types/dto"
"leafdev.top/Leaf/leaf-library-3/internal/types/errs"
"leafdev.top/Leaf/leaf-library-3/internal/types/user"
) )
func (s *Service) Get(ctx context.Context, workspaceId dto.EntityId) (*entity.Workspace, error) { func (s *Service) Get(ctx context.Context, workspaceId dto.EntityId) (*entity.Workspace, error) {
@ -54,6 +55,10 @@ func (s *Service) Create(ctx context.Context, userId user.ID, name string) (*ent
return workspace, nil return workspace, nil
} }
func (s *Service) ListMembers(ctx context.Context, workspaceEntity *entity.Workspace) ([]*entity.WorkspaceMember, error) {
return s.dao.WithContext(ctx).WorkspaceMember.Where(s.dao.WorkspaceMember.WorkspaceId.Eq(workspaceEntity.ID.Uint())).Find()
}
func (s *Service) AddMember(ctx context.Context, userId user.ID, workspaceEntity *entity.Workspace) (*entity.WorkspaceMember, error) { func (s *Service) AddMember(ctx context.Context, userId user.ID, workspaceEntity *entity.Workspace) (*entity.WorkspaceMember, error) {
memberExists, err := s.MemberExists(ctx, userId, workspaceEntity) memberExists, err := s.MemberExists(ctx, userId, workspaceEntity)
if err != nil { if err != nil {