mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-06-04 13:30:32 +08:00
feat: 完善Swagger API文档生成功能
This commit is contained in:
16
Makefile
16
Makefile
@@ -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:
|
||||
|
||||
@@ -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
7408
docs/docs.go
Normal file
File diff suppressed because it is too large
Load Diff
7384
docs/swagger.json
Normal file
7384
docs/swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
4869
docs/swagger.yaml
Normal file
4869
docs/swagger.yaml
Normal file
File diff suppressed because it is too large
Load Diff
12
go.mod
12
go.mod
@@ -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
45
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user