feat: 完善Swagger API文档生成功能

This commit is contained in:
wizardchen
2025-12-16 16:40:13 +08:00
committed by lyingbug
parent 121e9b3e1b
commit a7df6900eb
26 changed files with 20941 additions and 206 deletions

View File

@@ -1,4 +1,4 @@
.PHONY: help build run test clean docker-build-app docker-build-docreader docker-build-frontend docker-build-all docker-run migrate-up migrate-down docker-restart docker-stop start-all stop-all start-ollama stop-ollama build-images build-images-app build-images-docreader build-images-frontend clean-images check-env list-containers pull-images show-platform dev-start dev-stop dev-restart dev-logs dev-status dev-app dev-frontend
.PHONY: help build run test clean docker-build-app docker-build-docreader docker-build-frontend docker-build-all docker-run migrate-up migrate-down docker-restart docker-stop start-all stop-all start-ollama stop-ollama build-images build-images-app build-images-docreader build-images-frontend clean-images check-env list-containers pull-images show-platform dev-start dev-stop dev-restart dev-logs dev-status dev-app dev-frontend docs install-swagger
# Show help
help:
@@ -39,7 +39,8 @@ help:
@echo " fmt 格式化代码"
@echo " lint 代码检查"
@echo " deps 安装依赖"
@echo " docs 生成 API 文档"
@echo " docs 生成 Swagger API 文档"
@echo " install-swagger 安装 swag 工具"
@echo ""
@echo "环境检查:"
@echo " check-env 检查环境配置"
@@ -194,9 +195,16 @@ migrate-goto:
fi
./scripts/migrate.sh goto $(version)
# Generate API documentation
# Generate API documentation (Swagger)
docs:
swag init -g $(MAIN_PATH)/main.go -o ./docs
@echo "生成 Swagger API 文档..."
swag init -g $(MAIN_PATH)/main.go -o ./docs --parseDependency --parseInternal
@echo "文档已生成到 ./docs 目录"
@echo "启动服务后访问 http://localhost:8080/swagger/index.html 查看文档"
# Install swagger tool
install-swagger:
go install github.com/swaggo/swag/cmd/swag@latest
# Format code
fmt:

View File

@@ -1,5 +1,21 @@
// Package main is the main package for the WeKnora server
// It contains the main function and the entry point for the server
//
// @title WeKnora API
// @version 1.0
// @description WeKnora 知识库管理系统 API 文档
// @termsOfService http://swagger.io/terms/
//
// @contact.name WeKnora Github
// @contact.url https://github.com/Tencent/WeKnora
//
// @host localhost:8080
// @BasePath /api/v1
//
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description 输入 Bearer {token} 格式的 JWT 令牌
package main
import (

7408
docs/docs.go Normal file

File diff suppressed because it is too large Load Diff

7384
docs/swagger.json Normal file

File diff suppressed because it is too large Load Diff

4869
docs/swagger.yaml Normal file

File diff suppressed because it is too large Load Diff

12
go.mod
View File

@@ -29,6 +29,9 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.11.1
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.1
github.com/swaggo/swag v1.16.6
github.com/tencentyun/cos-go-sdk-v5 v0.7.65
github.com/yanyiwu/gojieba v1.4.5
go.opentelemetry.io/otel v1.38.0
@@ -47,6 +50,9 @@ require (
)
require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
@@ -70,6 +76,10 @@ require (
github.com/go-json-experiment/json v0.0.0-20250725192818-e39067aee2d2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
@@ -89,6 +99,7 @@ require (
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
@@ -136,5 +147,6 @@ require (
golang.org/x/tools v0.38.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

45
go.sum
View File

@@ -2,10 +2,16 @@ entgo.io/ent v0.14.3 h1:wokAV/kIlH9TeklJWGGS7AYJdVckr0DloWjIcO9iIIQ=
entgo.io/ent v0.14.3/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
@@ -41,6 +47,7 @@ github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -74,6 +81,8 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gin-contrib/cors v1.7.5 h1:cXC9SmofOrRg0w9PigwGlHG3ztswH6bqq4vJVXnvYMk=
github.com/gin-contrib/cors v1.7.5/go.mod h1:4q3yi7xBEDDWKapjT2o1V7mScKDDr8k+jZ0fSquGoy0=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
@@ -87,6 +96,16 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-pg/pg/v10 v10.11.0 h1:CMKJqLgTrfpE/aOVeLdybezR2om071Vh38OLZjsyMI0=
github.com/go-pg/pg/v10 v10.11.0/go.mod h1:4BpHRoxE61y4Onpof3x1a2SQvi9c+q1dJnrNdMjsroA=
github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU=
@@ -156,6 +175,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
@@ -163,8 +184,11 @@ github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdB
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
@@ -173,6 +197,9 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/mark3labs/mcp-go v0.43.0 h1:lgiKcWMddh4sngbU+hoWOZ9iAe/qp/m851RQpj3Y7jA=
@@ -205,6 +232,7 @@ github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSr
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/neo4j/neo4j-go-driver/v6 v6.0.0-alpha.1 h1:nV3ZdYJTi73jel0mm3dpWumNY3i3nwyo25y69SPGwyg=
github.com/neo4j/neo4j-go-driver/v6 v6.0.0-alpha.1/go.mod h1:hzSTfNfM31p1uRSzL1F/BAYOgaiTarE6OAQBajfsm+I=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/ollama/ollama v0.11.4 h1:6xLYLEPTKtw6N20qQecyEL/rrBktPO4o5U05cnvkSmI=
@@ -266,6 +294,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -274,6 +303,12 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY=
github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw=
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
github.com/tencentyun/cos-go-sdk-v5 v0.7.65 h1:+WBbfwThfZSbxpf1Dw6fyMwyzVtWBBExqfDJ5giiR2s=
@@ -356,8 +391,10 @@ golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
@@ -376,6 +413,7 @@ golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -402,6 +440,7 @@ golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@@ -434,9 +473,15 @@ google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94U
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=

View File

@@ -3990,8 +3990,8 @@ func (s *knowledgeService) buildFAQCSV(chunks []*types.Chunk, tagMap map[string]
escapeCSVField(strings.Join(meta.NegativeQuestions, "##")),
escapeCSVField(strings.Join(meta.Answers, "##")),
boolToCSV(meta.AnswerStrategy == types.AnswerStrategyAll),
boolToCSV(!chunk.IsEnabled), // 是否停用:取反
boolToCSV(!chunk.Flags.HasFlag(types.ChunkFlagRecommended)), // 是否禁止被推荐:取反
boolToCSV(!chunk.IsEnabled), // 是否停用:取反
boolToCSV(!chunk.Flags.HasFlag(types.ChunkFlagRecommended)), // 是否禁止被推荐:取反
}
buf.WriteString(strings.Join(row, ","))
buf.WriteString("\n")
@@ -4619,11 +4619,6 @@ func (s *knowledgeService) triggerManualProcessing(ctx context.Context,
if cfg == nil {
logger.GetLogger(ctx).WithField("knowledge_id", knowledge.ID).
Error("triggerManualProcessing enable multimodal but VLM config missing")
knowledge.ParseStatus = "failed"
knowledge.ErrorMessage = "VLM 配置缺失"
knowledge.UpdatedAt = time.Now()
s.repo.UpdateKnowledge(ctx, knowledge)
return
}
vlmConfig = cfg
}

View File

@@ -38,11 +38,16 @@ func NewAuthHandler(configInfo *config.Config,
}
}
// Register handles the HTTP request for user registration
// It deserializes the request body into a registration request object, validates it,
// calls the service to create the user, and returns the result
// Parameters:
// - c: Gin context for the HTTP request
// Register godoc
// @Summary 用户注册
// @Description 注册新用户账号
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body types.RegisterRequest true "注册请求参数"
// @Success 201 {object} types.RegisterResponse
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Router /auth/register [post]
func (h *AuthHandler) Register(c *gin.Context) {
ctx := c.Request.Context()
@@ -88,11 +93,16 @@ func (h *AuthHandler) Register(c *gin.Context) {
c.JSON(http.StatusCreated, response)
}
// Login handles the HTTP request for user login
// It deserializes the request body into a login request object, validates it,
// calls the service to authenticate the user, and returns tokens
// Parameters:
// - c: Gin context for the HTTP request
// Login godoc
// @Summary 用户登录
// @Description 用户登录并获取访问令牌
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body types.LoginRequest true "登录请求参数"
// @Success 200 {object} types.LoginResponse
// @Failure 401 {object} errors.AppError "认证失败"
// @Router /auth/login [post]
func (h *AuthHandler) Login(c *gin.Context) {
ctx := c.Request.Context()
@@ -137,10 +147,16 @@ func (h *AuthHandler) Login(c *gin.Context) {
c.JSON(http.StatusOK, response)
}
// Logout handles the HTTP request for user logout
// It extracts the token from the Authorization header and revokes it
// Parameters:
// - c: Gin context for the HTTP request
// Logout godoc
// @Summary 用户登出
// @Description 撤销当前访问令牌并登出
// @Tags 认证
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "登出成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /auth/logout [post]
func (h *AuthHandler) Logout(c *gin.Context) {
ctx := c.Request.Context()
@@ -182,10 +198,16 @@ func (h *AuthHandler) Logout(c *gin.Context) {
})
}
// RefreshToken handles the HTTP request for refreshing access tokens
// It extracts the refresh token from the request body and generates new tokens
// Parameters:
// - c: Gin context for the HTTP request
// RefreshToken godoc
// @Summary 刷新令牌
// @Description 使用刷新令牌获取新的访问令牌
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body object{refreshToken=string} true "刷新令牌"
// @Success 200 {object} map[string]interface{} "新令牌"
// @Failure 401 {object} errors.AppError "令牌无效"
// @Router /auth/refresh [post]
func (h *AuthHandler) RefreshToken(c *gin.Context) {
ctx := c.Request.Context()
@@ -220,10 +242,16 @@ func (h *AuthHandler) RefreshToken(c *gin.Context) {
})
}
// GetCurrentUser handles the HTTP request for getting current user information
// It extracts the user from the context (set by auth middleware) and returns user info
// Parameters:
// - c: Gin context for the HTTP request
// GetCurrentUser godoc
// @Summary 获取当前用户信息
// @Description 获取当前登录用户的详细信息
// @Tags 认证
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "用户信息"
// @Failure 401 {object} errors.AppError "未授权"
// @Security Bearer
// @Router /auth/me [get]
func (h *AuthHandler) GetCurrentUser(c *gin.Context) {
ctx := c.Request.Context()
@@ -256,10 +284,17 @@ func (h *AuthHandler) GetCurrentUser(c *gin.Context) {
})
}
// ChangePassword handles the HTTP request for changing user password
// It extracts the current user and validates the old password before setting new one
// Parameters:
// - c: Gin context for the HTTP request
// ChangePassword godoc
// @Summary 修改密码
// @Description 修改当前用户的登录密码
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body object{old_password=string,new_password=string} true "密码修改请求"
// @Success 200 {object} map[string]interface{} "修改成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /auth/change-password [post]
func (h *AuthHandler) ChangePassword(c *gin.Context) {
ctx := c.Request.Context()
@@ -302,10 +337,16 @@ func (h *AuthHandler) ChangePassword(c *gin.Context) {
})
}
// ValidateToken handles the HTTP request for validating access tokens
// It extracts the token from the Authorization header and validates it
// Parameters:
// - c: Gin context for the HTTP request
// ValidateToken godoc
// @Summary 验证令牌
// @Description 验证访问令牌是否有效
// @Tags 认证
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "令牌有效"
// @Failure 401 {object} errors.AppError "令牌无效"
// @Security Bearer
// @Router /auth/validate [get]
func (h *AuthHandler) ValidateToken(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -22,7 +22,18 @@ func NewChunkHandler(service interfaces.ChunkService) *ChunkHandler {
return &ChunkHandler{service: service}
}
// GetChunkByIDOnly gets a chunk by its ID only (without requiring knowledge_id)
// GetChunkByIDOnly godoc
// @Summary 通过ID获取分块
// @Description 仅通过分块ID获取分块详情不需要knowledge_id
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param id path string true "分块ID"
// @Success 200 {object} map[string]interface{} "分块详情"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "分块不存在"
// @Security Bearer
// @Router /chunks/by-id/{id} [get]
func (h *ChunkHandler) GetChunkByIDOnly(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start retrieving chunk by ID only")
@@ -79,7 +90,19 @@ func (h *ChunkHandler) GetChunkByIDOnly(c *gin.Context) {
})
}
// ListKnowledgeChunks lists all chunks for a given knowledge ID
// ListKnowledgeChunks godoc
// @Summary 获取知识分块列表
// @Description 获取指定知识下的所有分块列表,支持分页
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param knowledge_id path string true "知识ID"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} map[string]interface{} "分块列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /chunks/{knowledge_id} [get]
func (h *ChunkHandler) ListKnowledgeChunks(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start retrieving knowledge chunks list")
@@ -200,7 +223,20 @@ func (h *ChunkHandler) validateAndGetChunk(c *gin.Context) (*types.Chunk, string
return chunk, knowledgeID, nil
}
// UpdateChunk updates a chunk's properties
// UpdateChunk godoc
// @Summary 更新分块
// @Description 更新指定分块的内容和属性
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param knowledge_id path string true "知识ID"
// @Param id path string true "分块ID"
// @Param request body UpdateChunkRequest true "更新请求"
// @Success 200 {object} map[string]interface{} "更新后的分块"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "分块不存在"
// @Security Bearer
// @Router /chunks/{knowledge_id}/{id} [put]
func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start updating knowledge chunk")
@@ -239,7 +275,19 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
})
}
// DeleteChunk deletes a specific chunk
// DeleteChunk godoc
// @Summary 删除分块
// @Description 删除指定的分块
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param knowledge_id path string true "知识ID"
// @Param id path string true "分块ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "分块不存在"
// @Security Bearer
// @Router /chunks/{knowledge_id}/{id} [delete]
func (h *ChunkHandler) DeleteChunk(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start deleting knowledge chunk")
@@ -263,7 +311,17 @@ func (h *ChunkHandler) DeleteChunk(c *gin.Context) {
})
}
// DeleteChunksByKnowledgeID deletes all chunks for a given knowledge ID
// DeleteChunksByKnowledgeID godoc
// @Summary 删除知识下所有分块
// @Description 删除指定知识下的所有分块
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param knowledge_id path string true "知识ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /chunks/{knowledge_id} [delete]
func (h *ChunkHandler) DeleteChunksByKnowledgeID(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start deleting all chunks under knowledge")
@@ -289,7 +347,19 @@ func (h *ChunkHandler) DeleteChunksByKnowledgeID(c *gin.Context) {
})
}
// DeleteGeneratedQuestion deletes a generated question by its ID
// DeleteGeneratedQuestion godoc
// @Summary 删除生成的问题
// @Description 删除分块中生成的问题
// @Tags 分块管理
// @Accept json
// @Produce json
// @Param id path string true "分块ID"
// @Param request body object{question_id=string} true "问题ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "分块不存在"
// @Security Bearer
// @Router /chunks/by-id/{id}/questions [delete]
func (h *ChunkHandler) DeleteGeneratedQuestion(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start deleting generated question from chunk")

View File

@@ -29,7 +29,17 @@ type EvaluationRequest struct {
RerankModelID string `json:"rerank_id"` // ID of rerank model to use
}
// Evaluation handles evaluation request
// Evaluation godoc
// @Summary 执行评估
// @Description 对知识库进行评估测试
// @Tags 评估
// @Accept json
// @Produce json
// @Param request body EvaluationRequest true "评估请求参数"
// @Success 200 {object} map[string]interface{} "评估任务"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /evaluation/ [post]
func (e *EvaluationHandler) Evaluation(c *gin.Context) {
ctx := c.Request.Context()
@@ -81,7 +91,17 @@ type GetEvaluationRequest struct {
TaskID string `form:"task_id" binding:"required"` // ID of evaluation task
}
// GetEvaluationResult retrieves evaluation result by task ID
// GetEvaluationResult godoc
// @Summary 获取评估结果
// @Description 根据任务ID获取评估结果
// @Tags 评估
// @Accept json
// @Produce json
// @Param task_id query string true "评估任务ID"
// @Success 200 {object} map[string]interface{} "评估结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /evaluation/ [get]
func (e *EvaluationHandler) GetEvaluationResult(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -22,7 +22,21 @@ func NewFAQHandler(knowledgeService interfaces.KnowledgeService) *FAQHandler {
return &FAQHandler{knowledgeService: knowledgeService}
}
// ListEntries lists FAQ entries under a knowledge base.
// ListEntries godoc
// @Summary 获取FAQ条目列表
// @Description 获取知识库下的FAQ条目列表支持分页和筛选
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Param tag_id query string false "标签ID筛选"
// @Param keyword query string false "关键词搜索"
// @Success 200 {object} map[string]interface{} "FAQ列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries [get]
func (h *FAQHandler) ListEntries(c *gin.Context) {
ctx := c.Request.Context()
var page types.Pagination
@@ -48,7 +62,18 @@ func (h *FAQHandler) ListEntries(c *gin.Context) {
})
}
// UpsertEntries appends or replaces FAQ entries in batch asynchronously.
// UpsertEntries godoc
// @Summary 批量更新/插入FAQ条目
// @Description 异步批量更新或插入FAQ条目
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.FAQBatchUpsertPayload true "批量操作请求"
// @Success 200 {object} map[string]interface{} "任务ID"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries [post]
func (h *FAQHandler) UpsertEntries(c *gin.Context) {
ctx := c.Request.Context()
var req types.FAQBatchUpsertPayload
@@ -73,7 +98,18 @@ func (h *FAQHandler) UpsertEntries(c *gin.Context) {
})
}
// CreateEntry creates a single FAQ entry synchronously.
// CreateEntry godoc
// @Summary 创建单个FAQ条目
// @Description 同步创建单个FAQ条目
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.FAQEntryPayload true "FAQ条目"
// @Success 200 {object} map[string]interface{} "创建的FAQ条目"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entry [post]
func (h *FAQHandler) CreateEntry(c *gin.Context) {
ctx := c.Request.Context()
var req types.FAQEntryPayload
@@ -96,7 +132,19 @@ func (h *FAQHandler) CreateEntry(c *gin.Context) {
})
}
// UpdateEntry updates a single FAQ entry.
// UpdateEntry godoc
// @Summary 更新FAQ条目
// @Description 更新指定的FAQ条目
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param entry_id path string true "FAQ条目ID"
// @Param request body types.FAQEntryPayload true "FAQ条目"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries/{entry_id} [put]
func (h *FAQHandler) UpdateEntry(c *gin.Context) {
ctx := c.Request.Context()
var req types.FAQEntryPayload
@@ -118,7 +166,18 @@ func (h *FAQHandler) UpdateEntry(c *gin.Context) {
})
}
// UpdateEntryTagBatch updates tags for FAQ entries in batch.
// UpdateEntryTagBatch godoc
// @Summary 批量更新FAQ标签
// @Description 批量更新FAQ条目的标签
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body object true "标签更新请求"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries/tags [put]
func (h *FAQHandler) UpdateEntryTagBatch(c *gin.Context) {
ctx := c.Request.Context()
var req faqEntryTagBatchRequest
@@ -138,9 +197,18 @@ func (h *FAQHandler) UpdateEntryTagBatch(c *gin.Context) {
})
}
// UpdateEntryFieldsBatch updates multiple fields for FAQ entries in batch.
// This is the unified API for batch updating FAQ entry fields.
// Supports updating is_enabled, is_recommended, tag_id in a single call.
// UpdateEntryFieldsBatch godoc
// @Summary 批量更新FAQ字段
// @Description 批量更新FAQ条目的多个字段is_enabled, is_recommended, tag_id
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.FAQEntryFieldsBatchUpdate true "字段更新请求"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries/fields [put]
func (h *FAQHandler) UpdateEntryFieldsBatch(c *gin.Context) {
ctx := c.Request.Context()
var req types.FAQEntryFieldsBatchUpdate
@@ -170,7 +238,18 @@ type faqEntryTagBatchRequest struct {
Updates map[string]*string `json:"updates" binding:"required,min=1"`
}
// DeleteEntries deletes FAQ entries in batch.
// DeleteEntries godoc
// @Summary 批量删除FAQ条目
// @Description 批量删除指定的FAQ条目
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body object{ids=[]string} true "要删除的FAQ ID列表"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries [delete]
func (h *FAQHandler) DeleteEntries(c *gin.Context) {
ctx := c.Request.Context()
var req faqDeleteRequest
@@ -193,7 +272,18 @@ func (h *FAQHandler) DeleteEntries(c *gin.Context) {
})
}
// SearchFAQ searches FAQ entries using hybrid search.
// SearchFAQ godoc
// @Summary 搜索FAQ
// @Description 使用混合搜索在FAQ中搜索
// @Tags FAQ管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.FAQSearchRequest true "搜索请求"
// @Success 200 {object} map[string]interface{} "搜索结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/search [post]
func (h *FAQHandler) SearchFAQ(c *gin.Context) {
ctx := c.Request.Context()
var req types.FAQSearchRequest
@@ -222,7 +312,17 @@ func (h *FAQHandler) SearchFAQ(c *gin.Context) {
})
}
// ExportEntries exports all FAQ entries as a CSV file.
// ExportEntries godoc
// @Summary 导出FAQ条目
// @Description 将所有FAQ条目导出为CSV文件
// @Tags FAQ管理
// @Accept json
// @Produce text/csv
// @Param id path string true "知识库ID"
// @Success 200 {file} file "CSV文件"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/faq/entries/export [get]
func (h *FAQHandler) ExportEntries(c *gin.Context) {
ctx := c.Request.Context()
kbID := secutils.SanitizeForLog(c.Param("id"))

View File

@@ -205,7 +205,19 @@ type InitializationRequest struct {
} `json:"questionGeneration"`
}
// UpdateKBConfig 根据知识库ID和模型ID更新配置简化版
// UpdateKBConfig godoc
// @Summary 更新知识库配置
// @Description 根据知识库ID更新模型和分块配置
// @Tags 初始化
// @Accept json
// @Produce json
// @Param kbId path string true "知识库ID"
// @Param request body KBModelConfigRequest true "配置请求"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "知识库不存在"
// @Security Bearer
// @Router /initialization/kb/{kbId}/config [put]
func (h *InitializationHandler) UpdateKBConfig(c *gin.Context) {
ctx := c.Request.Context()
kbIdStr := utils.SanitizeForLog(c.Param("kbId"))
@@ -374,7 +386,18 @@ func (h *InitializationHandler) UpdateKBConfig(c *gin.Context) {
})
}
// InitializeByKB 根据知识库ID执行配置更新
// InitializeByKB godoc
// @Summary 初始化知识库配置
// @Description 根据知识库ID执行完整配置更新
// @Tags 初始化
// @Accept json
// @Produce json
// @Param kbId path string true "知识库ID"
// @Param request body object true "初始化请求"
// @Success 200 {object} map[string]interface{} "初始化成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/kb/{kbId} [post]
func (h *InitializationHandler) InitializeByKB(c *gin.Context) {
ctx := c.Request.Context()
kbIdStr := utils.SanitizeForLog(c.Param("kbId"))
@@ -765,7 +788,14 @@ func extractModelIDs(processedModels []*types.Model) (embeddingModelID, llmModel
return
}
// CheckOllamaStatus 检查Ollama服务状态
// CheckOllamaStatus godoc
// @Summary 检查Ollama服务状态
// @Description 检查Ollama服务是否可用
// @Tags 初始化
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "Ollama状态"
// @Router /initialization/ollama/status [get]
func (h *InitializationHandler) CheckOllamaStatus(c *gin.Context) {
ctx := c.Request.Context()
@@ -809,7 +839,17 @@ func (h *InitializationHandler) CheckOllamaStatus(c *gin.Context) {
})
}
// CheckOllamaModels 检查Ollama模型状态
// CheckOllamaModels godoc
// @Summary 检查Ollama模型状态
// @Description 检查指定的Ollama模型是否已安装
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body object{models=[]string} true "模型名称列表"
// @Success 200 {object} map[string]interface{} "模型状态"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/ollama/models/check [post]
func (h *InitializationHandler) CheckOllamaModels(c *gin.Context) {
ctx := c.Request.Context()
@@ -860,7 +900,17 @@ func (h *InitializationHandler) CheckOllamaModels(c *gin.Context) {
})
}
// DownloadOllamaModel 异步下载Ollama模型
// DownloadOllamaModel godoc
// @Summary 下载Ollama模型
// @Description 异步下载指定的Ollama模型
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body object{modelName=string} true "模型名称"
// @Success 200 {object} map[string]interface{} "下载任务信息"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/ollama/models/download [post]
func (h *InitializationHandler) DownloadOllamaModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -961,7 +1011,17 @@ func (h *InitializationHandler) DownloadOllamaModel(c *gin.Context) {
})
}
// GetDownloadProgress 获取下载进度
// GetDownloadProgress godoc
// @Summary 获取下载进度
// @Description 获取Ollama模型下载任务的进度
// @Tags 初始化
// @Accept json
// @Produce json
// @Param taskId path string true "任务ID"
// @Success 200 {object} map[string]interface{} "下载进度"
// @Failure 404 {object} errors.AppError "任务不存在"
// @Security Bearer
// @Router /initialization/ollama/download/{taskId} [get]
func (h *InitializationHandler) GetDownloadProgress(c *gin.Context) {
taskID := c.Param("taskId")
@@ -985,7 +1045,15 @@ func (h *InitializationHandler) GetDownloadProgress(c *gin.Context) {
})
}
// ListDownloadTasks 列出所有下载任务
// ListDownloadTasks godoc
// @Summary 列出下载任务
// @Description 列出所有Ollama模型下载任务
// @Tags 初始化
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "任务列表"
// @Security Bearer
// @Router /initialization/ollama/download/tasks [get]
func (h *InitializationHandler) ListDownloadTasks(c *gin.Context) {
tasksMutex.RLock()
tasks := make([]*DownloadTask, 0, len(downloadTasks))
@@ -1000,7 +1068,16 @@ func (h *InitializationHandler) ListDownloadTasks(c *gin.Context) {
})
}
// ListOllamaModels 列出已安装的 Ollama 模型
// ListOllamaModels godoc
// @Summary 列出Ollama模型
// @Description 列出已安装的Ollama模型
// @Tags 初始化
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "模型列表"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /initialization/ollama/models [get]
func (h *InitializationHandler) ListOllamaModels(c *gin.Context) {
ctx := c.Request.Context()
@@ -1128,7 +1205,17 @@ func (h *InitializationHandler) updateTaskStatus(
}
}
// GetCurrentConfigByKB 根据知识库ID获取配置信息
// GetCurrentConfigByKB godoc
// @Summary 获取知识库配置
// @Description 根据知识库ID获取当前配置信息
// @Tags 初始化
// @Accept json
// @Produce json
// @Param kbId path string true "知识库ID"
// @Success 200 {object} map[string]interface{} "配置信息"
// @Failure 404 {object} errors.AppError "知识库不存在"
// @Security Bearer
// @Router /initialization/kb/{kbId}/config [get]
func (h *InitializationHandler) GetCurrentConfigByKB(c *gin.Context) {
ctx := c.Request.Context()
kbIdStr := utils.SanitizeForLog(c.Param("kbId"))
@@ -1332,7 +1419,17 @@ type RemoteModelCheckRequest struct {
APIKey string `json:"apiKey"`
}
// CheckRemoteModel 检查远程API模型连接
// CheckRemoteModel godoc
// @Summary 检查远程模型
// @Description 检查远程API模型连接是否正常
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body RemoteModelCheckRequest true "模型检查请求"
// @Success 200 {object} map[string]interface{} "检查结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/models/remote/check [post]
func (h *InitializationHandler) CheckRemoteModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -1377,7 +1474,17 @@ func (h *InitializationHandler) CheckRemoteModel(c *gin.Context) {
})
}
// TestEmbeddingModel 测试 Embedding 接口(本地或远程)是否可用
// TestEmbeddingModel godoc
// @Summary 测试Embedding模型
// @Description 测试Embedding接口是否可用并返回向量维度
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body object true "Embedding测试请求"
// @Success 200 {object} map[string]interface{} "测试结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/models/embedding/test [post]
func (h *InitializationHandler) TestEmbeddingModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -1530,7 +1637,17 @@ func (h *InitializationHandler) checkRerankModelConnection(ctx context.Context,
}
}
// CheckRerankModel 检查Rerank模型连接和功能
// CheckRerankModel godoc
// @Summary 检查Rerank模型
// @Description 检查Rerank模型连接和功能是否正常
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body object true "Rerank检查请求"
// @Success 200 {object} map[string]interface{} "检查结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/models/rerank/check [post]
func (h *InitializationHandler) CheckRerankModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -1598,7 +1715,22 @@ type testMultimodalForm struct {
SeparatorsRaw string `form:"separators"`
}
// TestMultimodalFunction 测试多模态功能
// TestMultimodalFunction godoc
// @Summary 测试多模态功能
// @Description 上传图片测试多模态处理功能
// @Tags 初始化
// @Accept multipart/form-data
// @Produce json
// @Param image formData file true "测试图片"
// @Param vlm_model formData string true "VLM模型名称"
// @Param vlm_base_url formData string true "VLM Base URL"
// @Param vlm_api_key formData string false "VLM API Key"
// @Param vlm_interface_type formData string false "VLM接口类型"
// @Param storage_type formData string true "存储类型(cos/minio)"
// @Success 200 {object} map[string]interface{} "测试结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/multimodal/test [post]
func (h *InitializationHandler) TestMultimodalFunction(c *gin.Context) {
ctx := c.Request.Context()
@@ -1857,7 +1989,17 @@ type TextRelationExtractionResponse struct {
Relations []*types.GraphRelation `json:"relations"`
}
// ExtractTextRelations extracts text relations from text
// ExtractTextRelations godoc
// @Summary 提取文本关系
// @Description 从文本中提取实体和关系
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body TextRelationExtractionRequest true "提取请求"
// @Success 200 {object} map[string]interface{} "提取结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/extract/relations [post]
func (h *InitializationHandler) ExtractTextRelations(c *gin.Context) {
ctx := c.Request.Context()
@@ -1951,7 +2093,17 @@ type FabriTextResponse struct {
Text string `json:"text"`
}
// FabriText generates example text
// FabriText godoc
// @Summary 生成示例文本
// @Description 根据标签生成示例文本
// @Tags 初始化
// @Accept json
// @Produce json
// @Param request body FabriTextRequest true "生成请求"
// @Success 200 {object} map[string]interface{} "生成的文本"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /initialization/fabri/text [post]
func (h *InitializationHandler) FabriText(c *gin.Context) {
ctx := c.Request.Context()
@@ -2024,7 +2176,14 @@ var tagOptions = []string{
"内容", "文化", "人物", "事件", "时间", "地点", "作品", "作者", "关系", "属性",
}
// FabriTag generates tags
// FabriTag godoc
// @Summary 生成随机标签
// @Description 随机生成一组标签
// @Tags 初始化
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "生成的标签"
// @Router /initialization/fabri/tag [get]
func (h *InitializationHandler) FabriTag(c *gin.Context) {
tagRandom := RandomSelect(tagOptions, rand.Intn(len(tagOptions)-1)+1)
c.JSON(http.StatusOK, gin.H{

View File

@@ -82,7 +82,22 @@ func (h *KnowledgeHandler) handleDuplicateKnowledgeError(c *gin.Context,
return false
}
// CreateKnowledgeFromFile handles requests to create knowledge from an uploaded file
// CreateKnowledgeFromFile godoc
// @Summary 从文件创建知识
// @Description 上传文件并创建知识条目
// @Tags 知识管理
// @Accept multipart/form-data
// @Produce json
// @Param id path string true "知识库ID"
// @Param file formData file true "上传的文件"
// @Param fileName formData string false "自定义文件名"
// @Param metadata formData string false "元数据JSON"
// @Param enable_multimodel formData bool false "启用多模态处理"
// @Success 200 {object} map[string]interface{} "创建的知识"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 409 {object} map[string]interface{} "文件重复"
// @Security Bearer
// @Router /knowledge-bases/{id}/knowledge/file [post]
func (h *KnowledgeHandler) CreateKnowledgeFromFile(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start creating knowledge from file")
@@ -167,7 +182,19 @@ func (h *KnowledgeHandler) CreateKnowledgeFromFile(c *gin.Context) {
})
}
// CreateKnowledgeFromURL handles requests to create knowledge from a URL
// CreateKnowledgeFromURL godoc
// @Summary 从URL创建知识
// @Description 从指定URL抓取内容并创建知识条目
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body object{url=string,enable_multimodel=bool,title=string} true "URL请求"
// @Success 201 {object} map[string]interface{} "创建的知识"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 409 {object} map[string]interface{} "URL重复"
// @Security Bearer
// @Router /knowledge-bases/{id}/knowledge/url [post]
func (h *KnowledgeHandler) CreateKnowledgeFromURL(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start creating knowledge from URL")
@@ -223,7 +250,18 @@ func (h *KnowledgeHandler) CreateKnowledgeFromURL(c *gin.Context) {
})
}
// CreateManualKnowledge handles manual Markdown knowledge creation
// CreateManualKnowledge godoc
// @Summary 手工创建知识
// @Description 手工录入Markdown格式的知识内容
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.ManualKnowledgePayload true "手工知识内容"
// @Success 200 {object} map[string]interface{} "创建的知识"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/knowledge/manual [post]
func (h *KnowledgeHandler) CreateManualKnowledge(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start creating manual knowledge")
@@ -262,7 +300,18 @@ func (h *KnowledgeHandler) CreateManualKnowledge(c *gin.Context) {
})
}
// GetKnowledge retrieves a knowledge entry by its ID
// GetKnowledge godoc
// @Summary 获取知识详情
// @Description 根据ID获取知识条目详情
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识ID"
// @Success 200 {object} map[string]interface{} "知识详情"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "知识不存在"
// @Security Bearer
// @Router /knowledge/{id} [get]
func (h *KnowledgeHandler) GetKnowledge(c *gin.Context) {
ctx := c.Request.Context()
@@ -296,7 +345,22 @@ func (h *KnowledgeHandler) GetKnowledge(c *gin.Context) {
})
}
// ListKnowledge retrieves a paginated list of knowledge entries from a knowledge base
// ListKnowledge godoc
// @Summary 获取知识列表
// @Description 获取知识库下的知识列表,支持分页和筛选
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Param tag_id query string false "标签ID筛选"
// @Param keyword query string false "关键词搜索"
// @Param file_type query string false "文件类型筛选"
// @Success 200 {object} map[string]interface{} "知识列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/knowledge [get]
func (h *KnowledgeHandler) ListKnowledge(c *gin.Context) {
ctx := c.Request.Context()
@@ -356,7 +420,17 @@ func (h *KnowledgeHandler) ListKnowledge(c *gin.Context) {
})
}
// DeleteKnowledge handles requests to delete a knowledge entry by its ID
// DeleteKnowledge godoc
// @Summary 删除知识
// @Description 根据ID删除知识条目
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/{id} [delete]
func (h *KnowledgeHandler) DeleteKnowledge(c *gin.Context) {
ctx := c.Request.Context()
@@ -385,7 +459,17 @@ func (h *KnowledgeHandler) DeleteKnowledge(c *gin.Context) {
})
}
// DownloadKnowledgeFile handles requests to download a file associated with a knowledge entry
// DownloadKnowledgeFile godoc
// @Summary 下载知识文件
// @Description 下载知识条目关联的原始文件
// @Tags 知识管理
// @Accept json
// @Produce application/octet-stream
// @Param id path string true "知识ID"
// @Success 200 {file} file "文件内容"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/{id}/download [get]
func (h *KnowledgeHandler) DownloadKnowledgeFile(c *gin.Context) {
ctx := c.Request.Context()
@@ -442,7 +526,17 @@ type GetKnowledgeBatchRequest struct {
IDs []string `form:"ids" binding:"required"` // List of knowledge IDs
}
// GetKnowledgeBatch handles requests to retrieve multiple knowledge entries in a batch
// GetKnowledgeBatch godoc
// @Summary 批量获取知识
// @Description 根据ID列表批量获取知识条目
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param ids query []string true "知识ID列表"
// @Success 200 {object} map[string]interface{} "知识列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/batch [get]
func (h *KnowledgeHandler) GetKnowledgeBatch(c *gin.Context) {
ctx := c.Request.Context()
@@ -489,6 +583,18 @@ func (h *KnowledgeHandler) GetKnowledgeBatch(c *gin.Context) {
})
}
// UpdateKnowledge godoc
// @Summary 更新知识
// @Description 更新知识条目信息
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识ID"
// @Param request body types.Knowledge true "知识信息"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/{id} [put]
func (h *KnowledgeHandler) UpdateKnowledge(c *gin.Context) {
ctx := c.Request.Context()
// Get knowledge ID from URL path parameter
@@ -519,7 +625,18 @@ func (h *KnowledgeHandler) UpdateKnowledge(c *gin.Context) {
})
}
// UpdateManualKnowledge handles manual Markdown knowledge updates
// UpdateManualKnowledge godoc
// @Summary 更新手工知识
// @Description 更新手工录入的Markdown知识内容
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识ID"
// @Param request body types.ManualKnowledgePayload true "手工知识内容"
// @Success 200 {object} map[string]interface{} "更新后的知识"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/manual/{id} [put]
func (h *KnowledgeHandler) UpdateManualKnowledge(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start updating manual knowledge")
@@ -562,7 +679,17 @@ type knowledgeTagBatchRequest struct {
Updates map[string]*string `json:"updates" binding:"required,min=1"`
}
// UpdateKnowledgeTagBatch updates tags for knowledge items in batch.
// UpdateKnowledgeTagBatch godoc
// @Summary 批量更新知识标签
// @Description 批量更新知识条目的标签
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param request body object true "标签更新请求"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/tags [put]
func (h *KnowledgeHandler) UpdateKnowledgeTagBatch(c *gin.Context) {
ctx := c.Request.Context()
var req knowledgeTagBatchRequest
@@ -581,7 +708,19 @@ func (h *KnowledgeHandler) UpdateKnowledgeTagBatch(c *gin.Context) {
})
}
// UpdateImageInfo updates a chunk's properties
// UpdateImageInfo godoc
// @Summary 更新图像信息
// @Description 更新知识分块的图像信息
// @Tags 知识管理
// @Accept json
// @Produce json
// @Param id path string true "知识ID"
// @Param chunk_id path string true "分块ID"
// @Param request body object{image_info=string} true "图像信息"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge/image/{id}/{chunk_id} [put]
func (h *KnowledgeHandler) UpdateImageInfo(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start updating image info")

View File

@@ -27,7 +27,18 @@ func NewKnowledgeBaseHandler(
return &KnowledgeBaseHandler{service: service, knowledgeService: knowledgeService}
}
// HybridSearch handles requests to perform hybrid vector and keyword search on a knowledge base
// HybridSearch godoc
// @Summary 混合搜索
// @Description 在知识库中执行向量和关键词混合搜索
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body types.SearchParams true "搜索参数"
// @Success 200 {object} map[string]interface{} "搜索结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/hybrid-search [get]
func (h *KnowledgeBaseHandler) HybridSearch(c *gin.Context) {
ctx := c.Request.Context()
@@ -68,7 +79,17 @@ func (h *KnowledgeBaseHandler) HybridSearch(c *gin.Context) {
})
}
// CreateKnowledgeBase handles requests to create a new knowledge base
// CreateKnowledgeBase godoc
// @Summary 创建知识库
// @Description 创建新的知识库
// @Tags 知识库
// @Accept json
// @Produce json
// @Param request body types.KnowledgeBase true "知识库信息"
// @Success 201 {object} map[string]interface{} "创建的知识库"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases [post]
func (h *KnowledgeBaseHandler) CreateKnowledgeBase(c *gin.Context) {
ctx := c.Request.Context()
@@ -144,7 +165,18 @@ func (h *KnowledgeBaseHandler) validateAndGetKnowledgeBase(c *gin.Context) (*typ
return kb, id, nil
}
// GetKnowledgeBase handles requests to retrieve a knowledge base by ID
// GetKnowledgeBase godoc
// @Summary 获取知识库详情
// @Description 根据ID获取知识库详情
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Success 200 {object} map[string]interface{} "知识库详情"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "知识库不存在"
// @Security Bearer
// @Router /knowledge-bases/{id} [get]
func (h *KnowledgeBaseHandler) GetKnowledgeBase(c *gin.Context) {
// Validate and get the knowledge base
kb, _, err := h.validateAndGetKnowledgeBase(c)
@@ -158,7 +190,16 @@ func (h *KnowledgeBaseHandler) GetKnowledgeBase(c *gin.Context) {
})
}
// ListKnowledgeBases handles requests to list all knowledge bases for a tenant
// ListKnowledgeBases godoc
// @Summary 获取知识库列表
// @Description 获取当前租户的所有知识库
// @Tags 知识库
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "知识库列表"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /knowledge-bases [get]
func (h *KnowledgeBaseHandler) ListKnowledgeBases(c *gin.Context) {
ctx := c.Request.Context()
@@ -183,7 +224,18 @@ type UpdateKnowledgeBaseRequest struct {
Config *types.KnowledgeBaseConfig `json:"config" binding:"required"`
}
// UpdateKnowledgeBase handles requests to update an existing knowledge base
// UpdateKnowledgeBase godoc
// @Summary 更新知识库
// @Description 更新知识库的名称、描述和配置
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body UpdateKnowledgeBaseRequest true "更新请求"
// @Success 200 {object} map[string]interface{} "更新后的知识库"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id} [put]
func (h *KnowledgeBaseHandler) UpdateKnowledgeBase(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start updating knowledge base")
@@ -222,7 +274,17 @@ func (h *KnowledgeBaseHandler) UpdateKnowledgeBase(c *gin.Context) {
})
}
// DeleteKnowledgeBase handles requests to delete a knowledge base
// DeleteKnowledgeBase godoc
// @Summary 删除知识库
// @Description 删除指定的知识库及其所有内容
// @Tags 知识库
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id} [delete]
func (h *KnowledgeBaseHandler) DeleteKnowledgeBase(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start deleting knowledge base")
@@ -257,6 +319,17 @@ type CopyKnowledgeBaseRequest struct {
TargetID string `json:"target_id"`
}
// CopyKnowledgeBase godoc
// @Summary 复制知识库
// @Description 将一个知识库的内容复制到另一个知识库
// @Tags 知识库
// @Accept json
// @Produce json
// @Param request body CopyKnowledgeBaseRequest true "复制请求"
// @Success 200 {object} map[string]interface{} "复制成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/copy [post]
func (h *KnowledgeBaseHandler) CopyKnowledgeBase(c *gin.Context) {
ctx := c.Request.Context()
var req CopyKnowledgeBaseRequest

View File

@@ -23,8 +23,17 @@ func NewMCPServiceHandler(mcpServiceService interfaces.MCPServiceService) *MCPSe
}
}
// CreateMCPService creates a new MCP service
// POST /api/mcp-services
// CreateMCPService godoc
// @Summary 创建MCP服务
// @Description 创建新的MCP服务配置
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param request body types.MCPService true "MCP服务配置"
// @Success 200 {object} map[string]interface{} "创建的MCP服务"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /mcp-services [post]
func (h *MCPServiceHandler) CreateMCPService(c *gin.Context) {
ctx := c.Request.Context()
@@ -55,8 +64,16 @@ func (h *MCPServiceHandler) CreateMCPService(c *gin.Context) {
})
}
// ListMCPServices lists all MCP services for a tenant
// GET /api/mcp-services
// ListMCPServices godoc
// @Summary 获取MCP服务列表
// @Description 获取当前租户的所有MCP服务
// @Tags MCP服务
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "MCP服务列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /mcp-services [get]
func (h *MCPServiceHandler) ListMCPServices(c *gin.Context) {
ctx := c.Request.Context()
@@ -80,8 +97,17 @@ func (h *MCPServiceHandler) ListMCPServices(c *gin.Context) {
})
}
// GetMCPService retrieves a single MCP service
// GET /api/mcp-services/:id
// GetMCPService godoc
// @Summary 获取MCP服务详情
// @Description 根据ID获取MCP服务详情
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Success 200 {object} map[string]interface{} "MCP服务详情"
// @Failure 404 {object} errors.AppError "服务不存在"
// @Security Bearer
// @Router /mcp-services/{id} [get]
func (h *MCPServiceHandler) GetMCPService(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))
@@ -106,8 +132,18 @@ func (h *MCPServiceHandler) GetMCPService(c *gin.Context) {
})
}
// UpdateMCPService updates an MCP service
// PUT /api/mcp-services/:id
// UpdateMCPService godoc
// @Summary 更新MCP服务
// @Description 更新MCP服务配置
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Param request body object true "更新字段"
// @Success 200 {object} map[string]interface{} "更新后的MCP服务"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /mcp-services/{id} [put]
func (h *MCPServiceHandler) UpdateMCPService(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))
@@ -227,8 +263,17 @@ func (h *MCPServiceHandler) UpdateMCPService(c *gin.Context) {
})
}
// DeleteMCPService deletes an MCP service
// DELETE /api/mcp-services/:id
// DeleteMCPService godoc
// @Summary 删除MCP服务
// @Description 删除指定的MCP服务
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /mcp-services/{id} [delete]
func (h *MCPServiceHandler) DeleteMCPService(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))
@@ -253,8 +298,17 @@ func (h *MCPServiceHandler) DeleteMCPService(c *gin.Context) {
})
}
// TestMCPService tests connection to an MCP service
// POST /api/mcp-services/:id/test
// TestMCPService godoc
// @Summary 测试MCP服务连接
// @Description 测试MCP服务是否可以正常连接
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Success 200 {object} map[string]interface{} "测试结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /mcp-services/{id}/test [post]
func (h *MCPServiceHandler) TestMCPService(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))
@@ -288,8 +342,17 @@ func (h *MCPServiceHandler) TestMCPService(c *gin.Context) {
})
}
// GetMCPServiceTools retrieves tools from an MCP service
// GET /api/mcp-services/:id/tools
// GetMCPServiceTools godoc
// @Summary 获取MCP服务工具列表
// @Description 获取MCP服务提供的工具列表
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Success 200 {object} map[string]interface{} "工具列表"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /mcp-services/{id}/tools [get]
func (h *MCPServiceHandler) GetMCPServiceTools(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))
@@ -314,8 +377,17 @@ func (h *MCPServiceHandler) GetMCPServiceTools(c *gin.Context) {
})
}
// GetMCPServiceResources retrieves resources from an MCP service
// GET /api/mcp-services/:id/resources
// GetMCPServiceResources godoc
// @Summary 获取MCP服务资源列表
// @Description 获取MCP服务提供的资源列表
// @Tags MCP服务
// @Accept json
// @Produce json
// @Param id path string true "MCP服务ID"
// @Success 200 {object} map[string]interface{} "资源列表"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /mcp-services/{id}/resources [get]
func (h *MCPServiceHandler) GetMCPServiceResources(c *gin.Context) {
ctx := c.Request.Context()
serviceID := secutils.SanitizeForLog(c.Param("id"))

View File

@@ -30,9 +30,19 @@ func NewMessageHandler(messageService interfaces.MessageService) *MessageHandler
}
}
// LoadMessages handles requests to load message history
// It supports both loading recent messages and loading messages before a specific timestamp
// This endpoint is used for scrolling through conversation history
// LoadMessages godoc
// @Summary 加载消息历史
// @Description 加载会话的消息历史,支持分页和时间筛选
// @Tags 消息
// @Accept json
// @Produce json
// @Param session_id path string true "会话ID"
// @Param limit query int false "返回数量" default(20)
// @Param before_time query string false "在此时间之前的消息RFC3339Nano格式"
// @Success 200 {object} map[string]interface{} "消息列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /messages/{session_id}/load [get]
func (h *MessageHandler) LoadMessages(c *gin.Context) {
ctx := c.Request.Context()
@@ -108,8 +118,18 @@ func (h *MessageHandler) LoadMessages(c *gin.Context) {
})
}
// DeleteMessage handles requests to delete a message from a session
// It requires both session ID and message ID to identify the specific message to delete
// DeleteMessage godoc
// @Summary 删除消息
// @Description 从会话中删除指定消息
// @Tags 消息
// @Accept json
// @Produce json
// @Param session_id path string true "会话ID"
// @Param id path string true "消息ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /messages/{session_id}/{id} [delete]
func (h *MessageHandler) DeleteMessage(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -68,11 +68,17 @@ type CreateModelRequest struct {
Parameters types.ModelParameters `json:"parameters" binding:"required"`
}
// CreateModel handles the HTTP request to create a new model
// It validates the request, processes it using the model service,
// and returns the created model to the client
// Parameters:
// - c: Gin context for the HTTP request
// CreateModel godoc
// @Summary 创建模型
// @Description 创建新的模型配置
// @Tags 模型管理
// @Accept json
// @Produce json
// @Param request body CreateModelRequest true "模型信息"
// @Success 201 {object} map[string]interface{} "创建的模型"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /models [post]
func (h *ModelHandler) CreateModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -125,11 +131,17 @@ func (h *ModelHandler) CreateModel(c *gin.Context) {
})
}
// GetModel handles the HTTP request to retrieve a model by its ID
// It fetches the model from the service and returns it to the client,
// or returns appropriate error messages if the model cannot be found
// Parameters:
// - c: Gin context for the HTTP request
// GetModel godoc
// @Summary 获取模型详情
// @Description 根据ID获取模型详情
// @Tags 模型管理
// @Accept json
// @Produce json
// @Param id path string true "模型ID"
// @Success 200 {object} map[string]interface{} "模型详情"
// @Failure 404 {object} errors.AppError "模型不存在"
// @Security Bearer
// @Router /models/{id} [get]
func (h *ModelHandler) GetModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -169,10 +181,16 @@ func (h *ModelHandler) GetModel(c *gin.Context) {
})
}
// ListModels handles the HTTP request to retrieve all models for a tenant
// It validates the tenant ID, fetches models from the service, and returns them to the client
// Parameters:
// - c: Gin context for the HTTP request
// ListModels godoc
// @Summary 获取模型列表
// @Description 获取当前租户的所有模型
// @Tags 模型管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "模型列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /models [get]
func (h *ModelHandler) ListModels(c *gin.Context) {
ctx := c.Request.Context()
@@ -219,11 +237,18 @@ type UpdateModelRequest struct {
Type types.ModelType `json:"type"`
}
// UpdateModel handles the HTTP request to update an existing model
// It validates the request, retrieves the current model, applies changes,
// and updates the model in the service
// Parameters:
// - c: Gin context for the HTTP request
// UpdateModel godoc
// @Summary 更新模型
// @Description 更新模型配置信息
// @Tags 模型管理
// @Accept json
// @Produce json
// @Param id path string true "模型ID"
// @Param request body UpdateModelRequest true "更新信息"
// @Success 200 {object} map[string]interface{} "更新后的模型"
// @Failure 404 {object} errors.AppError "模型不存在"
// @Security Bearer
// @Router /models/{id} [put]
func (h *ModelHandler) UpdateModel(c *gin.Context) {
ctx := c.Request.Context()
@@ -285,11 +310,17 @@ func (h *ModelHandler) UpdateModel(c *gin.Context) {
})
}
// DeleteModel handles the HTTP request to delete a model by its ID
// It validates the model ID, attempts to delete the model through the service,
// and returns appropriate status and messages
// Parameters:
// - c: Gin context for the HTTP request
// DeleteModel godoc
// @Summary 删除模型
// @Description 删除指定的模型
// @Tags 模型管理
// @Accept json
// @Produce json
// @Param id path string true "模型ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 404 {object} errors.AppError "模型不存在"
// @Security Bearer
// @Router /models/{id} [delete]
func (h *ModelHandler) DeleteModel(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -39,7 +39,17 @@ func NewHandler(
}
}
// CreateSession handles the creation of a new conversation session
// CreateSession godoc
// @Summary 创建会话
// @Description 创建新的对话会话
// @Tags 会话
// @Accept json
// @Produce json
// @Param request body CreateSessionRequest true "会话创建请求"
// @Success 201 {object} map[string]interface{} "创建的会话"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions [post]
func (h *Handler) CreateSession(c *gin.Context) {
ctx := c.Request.Context()
// Parse and validate the request body
@@ -187,7 +197,17 @@ func (h *Handler) applyConversationDefaults(ctx context.Context, session *types.
session.SummaryParameters = h.createDefaultSummaryConfig(ctx)
}
// GetSession retrieves a session by its ID
// GetSession godoc
// @Summary 获取会话详情
// @Description 根据ID获取会话详情
// @Tags 会话
// @Accept json
// @Produce json
// @Param id path string true "会话ID"
// @Success 200 {object} map[string]interface{} "会话详情"
// @Failure 404 {object} errors.AppError "会话不存在"
// @Security Bearer
// @Router /sessions/{id} [get]
func (h *Handler) GetSession(c *gin.Context) {
ctx := c.Request.Context()
@@ -223,7 +243,18 @@ func (h *Handler) GetSession(c *gin.Context) {
})
}
// GetSessionsByTenant retrieves all sessions for the current tenant with pagination
// GetSessionsByTenant godoc
// @Summary 获取会话列表
// @Description 获取当前租户的会话列表,支持分页
// @Tags 会话
// @Accept json
// @Produce json
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} map[string]interface{} "会话列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions [get]
func (h *Handler) GetSessionsByTenant(c *gin.Context) {
ctx := c.Request.Context()
@@ -253,7 +284,18 @@ func (h *Handler) GetSessionsByTenant(c *gin.Context) {
})
}
// UpdateSession updates an existing session's properties
// UpdateSession godoc
// @Summary 更新会话
// @Description 更新会话属性
// @Tags 会话
// @Accept json
// @Produce json
// @Param id path string true "会话ID"
// @Param request body types.Session true "会话信息"
// @Success 200 {object} map[string]interface{} "更新后的会话"
// @Failure 404 {object} errors.AppError "会话不存在"
// @Security Bearer
// @Router /sessions/{id} [put]
func (h *Handler) UpdateSession(c *gin.Context) {
ctx := c.Request.Context()
@@ -304,7 +346,17 @@ func (h *Handler) UpdateSession(c *gin.Context) {
})
}
// DeleteSession deletes a session by its ID
// DeleteSession godoc
// @Summary 删除会话
// @Description 删除指定的会话
// @Tags 会话
// @Accept json
// @Produce json
// @Param id path string true "会话ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 404 {object} errors.AppError "会话不存在"
// @Security Bearer
// @Router /sessions/{id} [delete]
func (h *Handler) DeleteSession(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -16,7 +16,17 @@ import (
"github.com/gin-gonic/gin"
)
// SearchKnowledge performs knowledge base search without LLM summarization
// SearchKnowledge godoc
// @Summary 知识搜索
// @Description 在知识库中搜索不使用LLM总结
// @Tags 问答
// @Accept json
// @Produce json
// @Param request body SearchKnowledgeRequest true "搜索请求"
// @Success 200 {object} map[string]interface{} "搜索结果"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions/search [post]
func (h *Handler) SearchKnowledge(c *gin.Context) {
ctx := logger.CloneContext(c.Request.Context())
@@ -67,7 +77,18 @@ func (h *Handler) SearchKnowledge(c *gin.Context) {
})
}
// KnowledgeQA handles knowledge base question answering requests with LLM summarization
// KnowledgeQA godoc
// @Summary 知识问答
// @Description 基于知识库的问答使用LLM总结支持SSE流式响应
// @Tags 问答
// @Accept json
// @Produce text/event-stream
// @Param session_id path string true "会话ID"
// @Param request body CreateKnowledgeQARequest true "问答请求"
// @Success 200 {object} map[string]interface{} "问答结果SSE流"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions/{session_id}/knowledge-qa [post]
func (h *Handler) KnowledgeQA(c *gin.Context) {
ctx := logger.CloneContext(c.Request.Context())
@@ -136,7 +157,18 @@ func (h *Handler) KnowledgeQA(c *gin.Context) {
assistantMessage, true, secutils.SanitizeForLog(request.SummaryModelID), request.WebSearchEnabled)
}
// AgentQA handles agent-based question answering with conversation history and streaming
// AgentQA godoc
// @Summary Agent问答
// @Description 基于Agent的智能问答支持多轮对话和SSE流式响应
// @Tags 问答
// @Accept json
// @Produce text/event-stream
// @Param session_id path string true "会话ID"
// @Param request body CreateKnowledgeQARequest true "问答请求"
// @Success 200 {object} map[string]interface{} "问答结果SSE流"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions/{session_id}/agent-qa [post]
func (h *Handler) AgentQA(c *gin.Context) {
ctx := logger.CloneContext(c.Request.Context())
logger.Info(ctx, "Start processing agent QA request")

View File

@@ -15,7 +15,18 @@ import (
"github.com/gin-gonic/gin"
)
// ContinueStream handles continued streaming of an active response stream
// ContinueStream godoc
// @Summary 继续流式响应
// @Description 继续获取正在进行的流式响应
// @Tags 问答
// @Accept json
// @Produce text/event-stream
// @Param session_id path string true "会话ID"
// @Param message_id query string true "消息ID"
// @Success 200 {object} map[string]interface{} "流式响应"
// @Failure 404 {object} errors.AppError "会话或消息不存在"
// @Security Bearer
// @Router /sessions/{session_id}/continue [get]
func (h *Handler) ContinueStream(c *gin.Context) {
ctx := c.Request.Context()
@@ -163,7 +174,18 @@ func (h *Handler) ContinueStream(c *gin.Context) {
}
}
// StopSession handles the stop generation request
// StopSession godoc
// @Summary 停止生成
// @Description 停止当前正在进行的生成任务
// @Tags 问答
// @Accept json
// @Produce json
// @Param session_id path string true "会话ID"
// @Param request body StopSessionRequest true "停止请求"
// @Success 200 {object} map[string]interface{} "停止成功"
// @Failure 404 {object} errors.AppError "会话或消息不存在"
// @Security Bearer
// @Router /sessions/{session_id}/stop [post]
func (h *Handler) StopSession(c *gin.Context) {
ctx := logger.CloneContext(c.Request.Context())
sessionID := secutils.SanitizeForLog(c.Param("session_id"))

View File

@@ -8,7 +8,18 @@ import (
"github.com/gin-gonic/gin"
)
// GenerateTitle generates a title for a session based on message content
// GenerateTitle godoc
// @Summary 生成会话标题
// @Description 根据消息内容自动生成会话标题
// @Tags 会话
// @Accept json
// @Produce json
// @Param session_id path string true "会话ID"
// @Param request body GenerateTitleRequest true "生成请求"
// @Success 200 {object} map[string]interface{} "生成的标题"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /sessions/{session_id}/title [post]
func (h *Handler) GenerateTitle(c *gin.Context) {
ctx := c.Request.Context()

View File

@@ -44,7 +44,14 @@ var (
GoVersion = "unknown"
)
// GetSystemInfo gets system information including version and commit ID
// GetSystemInfo godoc
// @Summary 获取系统信息
// @Description 获取系统版本、构建信息和引擎配置
// @Tags 系统
// @Accept json
// @Produce json
// @Success 200 {object} GetSystemInfoResponse "系统信息"
// @Router /system/info [get]
func (h *SystemHandler) GetSystemInfo(c *gin.Context) {
ctx := logger.CloneContext(c.Request.Context())

View File

@@ -22,7 +22,20 @@ func NewTagHandler(tagService interfaces.KnowledgeTagService) *TagHandler {
return &TagHandler{tagService: tagService}
}
// ListTags returns all tags under a knowledge base with statistics.
// ListTags godoc
// @Summary 获取标签列表
// @Description 获取知识库下的所有标签及统计信息
// @Tags 标签管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Param keyword query string false "关键词搜索"
// @Success 200 {object} map[string]interface{} "标签列表"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/tags [get]
func (h *TagHandler) ListTags(c *gin.Context) {
ctx := c.Request.Context()
kbID := secutils.SanitizeForLog(c.Param("id"))
@@ -55,7 +68,18 @@ type createTagRequest struct {
SortOrder int `json:"sort_order"`
}
// CreateTag creates a new tag.
// CreateTag godoc
// @Summary 创建标签
// @Description 在知识库下创建新标签
// @Tags 标签管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param request body object{name=string,color=string,sort_order=int} true "标签信息"
// @Success 200 {object} map[string]interface{} "创建的标签"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/tags [post]
func (h *TagHandler) CreateTag(c *gin.Context) {
ctx := c.Request.Context()
kbID := secutils.SanitizeForLog(c.Param("id"))
@@ -89,7 +113,19 @@ type updateTagRequest struct {
SortOrder *int `json:"sort_order"`
}
// UpdateTag updates an existing tag.
// UpdateTag godoc
// @Summary 更新标签
// @Description 更新标签信息
// @Tags 标签管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param tag_id path string true "标签ID"
// @Param request body object true "标签更新信息"
// @Success 200 {object} map[string]interface{} "更新后的标签"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/tags/{tag_id} [put]
func (h *TagHandler) UpdateTag(c *gin.Context) {
ctx := c.Request.Context()
@@ -116,7 +152,19 @@ func (h *TagHandler) UpdateTag(c *gin.Context) {
})
}
// DeleteTag deletes a tag. Use query param force=true to force delete even if referenced.
// DeleteTag godoc
// @Summary 删除标签
// @Description 删除标签可使用force=true强制删除被引用的标签
// @Tags 标签管理
// @Accept json
// @Produce json
// @Param id path string true "知识库ID"
// @Param tag_id path string true "标签ID"
// @Param force query bool false "强制删除"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /knowledge-bases/{id}/tags/{tag_id} [delete]
func (h *TagHandler) DeleteTag(c *gin.Context) {
ctx := c.Request.Context()
tagID := secutils.SanitizeForLog(c.Param("tag_id"))

View File

@@ -40,11 +40,17 @@ func NewTenantHandler(service interfaces.TenantService, userService interfaces.U
}
}
// CreateTenant handles the HTTP request for creating a new tenant
// It deserializes the request body into a tenant object, validates it,
// calls the service to create the tenant, and returns the result
// Parameters:
// - c: Gin context for the HTTP request
// CreateTenant godoc
// @Summary 创建租户
// @Description 创建新的租户
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param request body types.Tenant true "租户信息"
// @Success 201 {object} map[string]interface{} "创建的租户"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants [post]
func (h *TenantHandler) CreateTenant(c *gin.Context) {
ctx := c.Request.Context()
@@ -85,11 +91,18 @@ func (h *TenantHandler) CreateTenant(c *gin.Context) {
})
}
// GetTenant handles the HTTP request for retrieving a tenant by ID
// It extracts and validates the tenant ID from the URL parameter,
// retrieves the tenant from the service, and returns it in the response
// Parameters:
// - c: Gin context for the HTTP request
// GetTenant godoc
// @Summary 获取租户详情
// @Description 根据ID获取租户详情
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param id path int true "租户ID"
// @Success 200 {object} map[string]interface{} "租户详情"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Failure 404 {object} errors.AppError "租户不存在"
// @Security Bearer
// @Router /tenants/{id} [get]
func (h *TenantHandler) GetTenant(c *gin.Context) {
ctx := c.Request.Context()
@@ -119,11 +132,18 @@ func (h *TenantHandler) GetTenant(c *gin.Context) {
})
}
// UpdateTenant handles the HTTP request for updating an existing tenant
// It extracts the tenant ID from the URL parameter, deserializes the request body,
// validates the data, updates the tenant through the service, and returns the result
// Parameters:
// - c: Gin context for the HTTP request
// UpdateTenant godoc
// @Summary 更新租户
// @Description 更新租户信息
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param id path int true "租户ID"
// @Param request body types.Tenant true "租户信息"
// @Success 200 {object} map[string]interface{} "更新后的租户"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants/{id} [put]
func (h *TenantHandler) UpdateTenant(c *gin.Context) {
ctx := c.Request.Context()
@@ -171,11 +191,17 @@ func (h *TenantHandler) UpdateTenant(c *gin.Context) {
})
}
// DeleteTenant handles the HTTP request for deleting a tenant
// It extracts and validates the tenant ID from the URL parameter,
// calls the service to delete the tenant, and returns the result
// Parameters:
// - c: Gin context for the HTTP request
// DeleteTenant godoc
// @Summary 删除租户
// @Description 删除指定的租户
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param id path int true "租户ID"
// @Success 200 {object} map[string]interface{} "删除成功"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants/{id} [delete]
func (h *TenantHandler) DeleteTenant(c *gin.Context) {
ctx := c.Request.Context()
@@ -209,10 +235,16 @@ func (h *TenantHandler) DeleteTenant(c *gin.Context) {
})
}
// ListTenants handles the HTTP request for retrieving a list of all tenants
// It calls the service to fetch the tenant list and returns it in the response
// Parameters:
// - c: Gin context for the HTTP request
// ListTenants godoc
// @Summary 获取租户列表
// @Description 获取当前用户可访问的租户列表
// @Tags 租户管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "租户列表"
// @Failure 500 {object} errors.AppError "服务器错误"
// @Security Bearer
// @Router /tenants [get]
func (h *TenantHandler) ListTenants(c *gin.Context) {
ctx := c.Request.Context()
@@ -237,10 +269,16 @@ func (h *TenantHandler) ListTenants(c *gin.Context) {
})
}
// ListAllTenants handles the HTTP request for retrieving a list of all tenants
// This endpoint requires cross-tenant access permission
// Parameters:
// - c: Gin context for the HTTP request
// ListAllTenants godoc
// @Summary 获取所有租户列表
// @Description 获取系统中所有租户(需要跨租户访问权限)
// @Tags 租户管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "所有租户列表"
// @Failure 403 {object} errors.AppError "权限不足"
// @Security Bearer
// @Router /tenants/all [get]
func (h *TenantHandler) ListAllTenants(c *gin.Context) {
ctx := c.Request.Context()
@@ -287,13 +325,20 @@ func (h *TenantHandler) ListAllTenants(c *gin.Context) {
})
}
// SearchTenants handles the HTTP request for searching tenants with pagination
// This endpoint requires cross-tenant access permission
// Query parameters:
// - keyword: search keyword (optional)
// - tenant_id: filter by tenant ID (optional)
// - page: page number (default: 1)
// - page_size: page size (default: 20)
// SearchTenants godoc
// @Summary 搜索租户
// @Description 分页搜索租户(需要跨租户访问权限)
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param keyword query string false "搜索关键词"
// @Param tenant_id query int false "租户ID筛选"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(20)
// @Success 200 {object} map[string]interface{} "搜索结果"
// @Failure 403 {object} errors.AppError "权限不足"
// @Security Bearer
// @Router /tenants/search [get]
func (h *TenantHandler) SearchTenants(c *gin.Context) {
ctx := c.Request.Context()
@@ -381,8 +426,16 @@ type AgentConfigRequest struct {
UseCustomPrompt *bool `json:"use_custom_system_prompt"`
}
// GetTenantAgentConfig retrieves the agent configuration for a tenant
// This is the global agent configuration that applies to all sessions by default
// GetTenantAgentConfig godoc
// @Summary 获取租户Agent配置
// @Description 获取租户的全局Agent配置默认应用于所有会话
// @Tags 租户管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "Agent配置"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants/kv/agent-config [get]
func (h *TenantHandler) GetTenantAgentConfig(c *gin.Context) {
ctx := c.Request.Context()
tenant := ctx.Value(types.TenantInfoContextKey).(*types.Tenant)
@@ -528,10 +581,17 @@ func (h *TenantHandler) updateTenantAgentConfigInternal(c *gin.Context) {
})
}
// GetTenantKV provides a generic KV-style getter for tenant-level configurations
// Supported keys:
// - "agent-config": returns tenant.AgentConfig with additional available_* fields
// - "web-search-config": returns masked tenant.WebSearchConfig (API key masked)
// GetTenantKV godoc
// @Summary 获取租户KV配置
// @Description 获取租户级别的KV配置支持agent-config、web-search-config、conversation-config
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param key path string true "配置键名"
// @Success 200 {object} map[string]interface{} "配置值"
// @Failure 400 {object} errors.AppError "不支持的键"
// @Security Bearer
// @Router /tenants/kv/{key} [get]
func (h *TenantHandler) GetTenantKV(c *gin.Context) {
ctx := c.Request.Context()
key := secutils.SanitizeForLog(c.Param("key"))
@@ -553,8 +613,18 @@ func (h *TenantHandler) GetTenantKV(c *gin.Context) {
}
}
// UpdateTenantKV provides a generic KV-style updater for tenant-level configurations
// Body is the JSON value to set for the key.
// UpdateTenantKV godoc
// @Summary 更新租户KV配置
// @Description 更新租户级别的KV配置支持agent-config、web-search-config、conversation-config
// @Tags 租户管理
// @Accept json
// @Produce json
// @Param key path string true "配置键名"
// @Param request body object true "配置值"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} errors.AppError "不支持的键"
// @Security Bearer
// @Router /tenants/kv/{key} [put]
func (h *TenantHandler) UpdateTenantKV(c *gin.Context) {
ctx := c.Request.Context()
key := secutils.SanitizeForLog(c.Param("key"))
@@ -620,7 +690,16 @@ func (h *TenantHandler) updateTenantWebSearchConfigInternal(c *gin.Context) {
})
}
// GetTenantWebSearchConfig returns the web search configuration for a tenant
// GetTenantWebSearchConfig godoc
// @Summary 获取租户网络搜索配置
// @Description 获取租户的网络搜索配置
// @Tags 租户管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "网络搜索配置"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants/kv/web-search-config [get]
func (h *TenantHandler) GetTenantWebSearchConfig(c *gin.Context) {
ctx := c.Request.Context()
logger.Info(ctx, "Start getting tenant web search config")
@@ -696,8 +775,16 @@ func validateConversationConfig(req *types.ConversationConfig) error {
return nil
}
// GetTenantConversationConfig retrieves the conversation configuration for a tenant
// This is the global conversation configuration that applies to normal mode sessions by default
// GetTenantConversationConfig godoc
// @Summary 获取租户对话配置
// @Description 获取租户的全局对话配置(默认应用于普通模式会话)
// @Tags 租户管理
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{} "对话配置"
// @Failure 400 {object} errors.AppError "请求参数错误"
// @Security Bearer
// @Router /tenants/kv/conversation-config [get]
func (h *TenantHandler) GetTenantConversationConfig(c *gin.Context) {
ctx := c.Request.Context()
tenant := ctx.Value(types.TenantInfoContextKey).(*types.Tenant)

View File

@@ -5,6 +5,8 @@ import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"go.uber.org/dig"
"github.com/Tencent/WeKnora/internal/config"
@@ -12,6 +14,8 @@ import (
"github.com/Tencent/WeKnora/internal/handler/session"
"github.com/Tencent/WeKnora/internal/middleware"
"github.com/Tencent/WeKnora/internal/types/interfaces"
_ "github.com/Tencent/WeKnora/docs" // swagger docs
)
// RouterParams 路由参数
@@ -59,21 +63,31 @@ func NewRouter(params RouterParams) *gin.Engine {
MaxAge: 12 * time.Hour,
}))
// 其他中间件
// 基础中间件(不需要认证)
r.Use(middleware.RequestID())
r.Use(middleware.Logger())
r.Use(middleware.Recovery())
r.Use(middleware.ErrorHandler())
// 健康检查(不需要认证)
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// Swagger API 文档(不需要认证)
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler,
ginSwagger.DefaultModelsExpandDepth(-1), // 默认折叠 Models
ginSwagger.DocExpansion("list"), // 展开模式: "list"(展开标签), "full"(全部展开), "none"(全部折叠)
ginSwagger.DeepLinking(true), // 启用深度链接
ginSwagger.PersistAuthorization(true), // 持久化认证信息
))
// 认证中间件
r.Use(middleware.Auth(params.TenantService, params.UserService, params.Config))
// 添加OpenTelemetry追踪中间件
r.Use(middleware.TracingMiddleware())
// 健康检查
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// 需要认证的API路由
v1 := r.Group("/api/v1")
{