Files
geo/server/internal/tenant/transport/router.go
T
root 94f7186cce feat: add image upload functionality for articles
- Implemented image upload API in the article service, allowing users to upload images associated with articles.
- Added validation for image size and type, ensuring only supported formats (PNG, JPG, GIF, WebP) are accepted.
- Created a new Aliyun object storage client to handle image storage and retrieval.
- Updated the article handler to include an endpoint for image uploads.
- Enhanced error handling for image upload failures and added relevant error messages.
- Introduced public URL generation for stored images, allowing access via signed tokens.
- Updated localization files to include new messages related to image upload functionality.
- Added tests for image upload and retrieval processes.
2026-04-05 22:10:05 +08:00

133 lines
5.8 KiB
Go

package transport
import (
"github.com/geo-platform/tenant-api/internal/bootstrap"
"github.com/geo-platform/tenant-api/internal/shared/auth"
"github.com/geo-platform/tenant-api/internal/shared/middleware"
)
func RegisterRoutes(app *bootstrap.App) {
authAPI := app.Engine.Group("/api/auth")
authHandler := NewAuthHandler(app)
authAPI.POST("/login", authHandler.Login)
authAPI.POST("/refresh", authHandler.Refresh)
publicAssets := NewAssetHandler(app)
app.Engine.GET("/api/public/assets/:token", publicAssets.Serve)
pluginHandler := NewMediaHandler(app)
callbacks := app.Engine.Group("/api/callback/plugin")
callbacks.POST("/bind", pluginHandler.PluginBindCallback)
callbacks.POST("/publish", pluginHandler.PluginPublishCallback)
protected := app.Engine.Group("/api")
protected.Use(auth.Middleware(app.JWT, app.Sessions))
protected.Use(middleware.TenantScope())
protected.GET("/auth/me", authHandler.Me)
protected.POST("/auth/logout", authHandler.Logout)
workspace := protected.Group("/tenant/workspace")
wsHandler := NewWorkspaceHandler(app)
workspace.GET("/overview", wsHandler.Overview)
workspace.GET("/recent-articles", wsHandler.RecentArticles)
workspace.GET("/quota-summary", wsHandler.QuotaSummary)
workspace.GET("/template-cards", wsHandler.TemplateCards)
templates := protected.Group("/tenant/templates")
tplHandler := NewTemplateHandler(app)
templates.GET("", tplHandler.List)
templates.GET("/:id", tplHandler.Detail)
templates.POST("/:id/drafts", tplHandler.SaveDraft)
templates.POST("/:id/analyze-tasks", tplHandler.CreateAnalyzeTask)
templates.GET("/:id/analyze_task_result", tplHandler.GetAnalyzeTaskResult)
templates.POST("/:id/title-tasks", tplHandler.CreateTitleTask)
templates.GET("/:id/gen_title_task_result", tplHandler.GetTitleTaskResult)
templates.POST("/:id/outline-tasks", tplHandler.CreateOutlineTask)
templates.GET("/:id/gen_outline_task_result", tplHandler.GetOutlineTaskResult)
templates.POST("/:id/generate", tplHandler.Generate)
articles := protected.Group("/tenant/articles")
artHandler := NewArticleHandler(app)
articles.GET("", artHandler.List)
articles.POST("/generate-from-rule", artHandler.GenerateFromRule)
articles.POST("/:id/images", artHandler.UploadImage)
articles.GET("/:id", artHandler.Detail)
articles.PUT("/:id", artHandler.Update)
articles.GET("/:id/stream", artHandler.Stream)
articles.GET("/:id/versions", artHandler.Versions)
articles.GET("/:id/publish-records", pluginHandler.ListPublishRecords)
articles.POST("/:id/publish-batches", pluginHandler.CreatePublishBatch)
articles.DELETE("/:id", artHandler.Delete)
media := protected.Group("/tenant/media")
media.GET("/platforms", pluginHandler.ListPlatforms)
media.GET("/platform-accounts", pluginHandler.ListPlatformAccounts)
media.POST("/plugin-installations/register", pluginHandler.RegisterPluginInstallation)
media.POST("/plugin-sessions", pluginHandler.CreatePluginSession)
media.DELETE("/platform-accounts/:id", pluginHandler.DeletePlatformAccount)
brands := protected.Group("/tenant/brands")
brandHandler := NewBrandHandler(app)
brands.GET("", brandHandler.List)
brands.POST("", brandHandler.Create)
brands.GET("/:id", brandHandler.Detail)
brands.PUT("/:id", brandHandler.Update)
brands.DELETE("/:id", brandHandler.Delete)
brands.GET("/:id/keywords", brandHandler.ListKeywords)
brands.POST("/:id/keywords", brandHandler.CreateKeyword)
brands.PUT("/:id/keywords/:kid", brandHandler.UpdateKeyword)
brands.DELETE("/:id/keywords/:kid", brandHandler.DeleteKeyword)
brands.GET("/:id/questions", brandHandler.ListQuestions)
brands.POST("/:id/questions", brandHandler.CreateQuestion)
brands.PUT("/:id/questions/:qid", brandHandler.UpdateQuestion)
brands.DELETE("/:id/questions/:qid", brandHandler.DeleteQuestion)
brands.GET("/:id/competitors", brandHandler.ListCompetitors)
brands.POST("/:id/competitors", brandHandler.CreateCompetitor)
brands.PUT("/:id/competitors/:cid", brandHandler.UpdateCompetitor)
brands.DELETE("/:id/competitors/:cid", brandHandler.DeleteCompetitor)
knowledge := protected.Group("/tenant/knowledge")
knowledgeHandler := NewKnowledgeHandler(app)
knowledge.GET("/groups", knowledgeHandler.ListGroups)
knowledge.POST("/groups", knowledgeHandler.CreateGroup)
knowledge.PUT("/groups/:gid", knowledgeHandler.UpdateGroup)
knowledge.DELETE("/groups/:gid", knowledgeHandler.DeleteGroup)
knowledge.GET("/items", knowledgeHandler.ListItems)
knowledge.GET("/items/:id", knowledgeHandler.GetItemDetail)
knowledge.POST("/items/text", knowledgeHandler.CreateTextItem)
knowledge.POST("/items/url", knowledgeHandler.CreateURLItem)
knowledge.POST("/items/file", knowledgeHandler.CreateFileItem)
knowledge.DELETE("/items/:id", knowledgeHandler.DeleteItem)
// Prompt Rules
promptRules := protected.Group("/tenant/prompt-rules")
prHandler := NewPromptRuleHandler(app)
promptRules.GET("", prHandler.List)
promptRules.GET("/simple", prHandler.ListSimple)
promptRules.POST("", prHandler.Create)
promptRules.GET("/:id", prHandler.Detail)
promptRules.PUT("/:id", prHandler.Update)
promptRules.DELETE("/:id", prHandler.Delete)
promptRules.PUT("/:id/status", prHandler.ToggleStatus)
// Prompt Rule Groups
promptRules.GET("/groups", prHandler.ListGroups)
promptRules.POST("/groups", prHandler.CreateGroup)
promptRules.PUT("/groups/:gid", prHandler.UpdateGroup)
promptRules.DELETE("/groups/:gid", prHandler.DeleteGroup)
// Schedule Tasks
schedules := protected.Group("/tenant/schedules")
schHandler := NewScheduleTaskHandler(app)
schedules.GET("", schHandler.List)
schedules.POST("", schHandler.Create)
schedules.GET("/:id", schHandler.Detail)
schedules.PUT("/:id", schHandler.Update)
schedules.DELETE("/:id", schHandler.Delete)
schedules.PUT("/:id/status", schHandler.ToggleStatus)
instantTasks := protected.Group("/tenant/instant-tasks")
instHandler := NewInstantTaskHandler(app)
instantTasks.GET("", instHandler.List)
}