feat: 第五轮开发 - 14项未来路线图功能完整实现
W1-W14 全部完成: - W1: 消息搜索 (ILIKE全文检索 + SearchModal) - W2: 对话导出 (JSON/Markdown/TXT三格式) - W3: 记忆时间线 DevTools 可视化 - W4: 通知推送系统 (WebSocket + Browser Notification API) - W5: 定时提醒 (30s轮询 + 重复提醒 + WebSocket推送) - W6: 每日简报 (08:00自动生成: 天气+新闻+提醒+AI摘要) - W7: IoT场景自动化 (规则引擎 10s轮询 + 条件评估 + 场景执行) - W8: 语音输入 (浏览器 Speech Recognition API) - W9: STT服务 (voice-service + whisper.cpp) - W10: TTS服务 (浏览器 Speech Synthesis + edge-tts三档回退) - W11: 文件管理 (上传/下载/缩略图/纯Go bilinear缩放) - W12: 知识库RAG (PostgreSQL tsvector + 文档分块 + 检索) - W13: 多模态 (图片上传+分析: Vision API + 本地Go分析回退) - W14: PWA (Service Worker + 离线页 + install prompt) 总计: 6个Go微服务 + 10+前端组件 + 10+ PostgreSQL表 + 4个后台调度器
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/config"
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/engine"
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/handler"
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/middleware"
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/store"
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// Setup 注册所有路由
|
||||
func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.SessionStore) {
|
||||
func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.SessionStore, reminderStore *store.ReminderStore, briefingStore *store.BriefingStore, automationStore *store.AutomationStore, fileStore *store.FileStore, ruleEngine *engine.RuleEngine, knowledgeStore *store.KnowledgeStore, imageHandler *handler.ImageHandler) {
|
||||
// 限流器
|
||||
rateLimiter := middleware.NewRateLimiter(10, 20) // 每秒10个请求,突发20
|
||||
|
||||
@@ -24,6 +25,16 @@ func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.S
|
||||
memoryHandler := handler.NewMemoryHandler(cfg.MemoryServiceURL)
|
||||
chatHandler := handler.NewChatHandler(cfg, hub)
|
||||
webhookHandler := handler.NewWebhookHandler(cfg, hub)
|
||||
notificationHandler := handler.NewNotificationHandler(cfg, hub)
|
||||
reminderHandler := handler.NewReminderHandler(reminderStore, hub)
|
||||
briefingHandler := handler.NewBriefingHandler(cfg, hub, briefingStore, reminderStore)
|
||||
voiceHandler := handler.NewVoiceHandler(cfg.VoiceServiceURL)
|
||||
fileHandler := handler.NewFileHandler(fileStore)
|
||||
automationHandler := handler.NewAutomationHandler(automationStore, ruleEngine)
|
||||
knowledgeHandler := handler.NewKnowledgeHandler(knowledgeStore, fileStore)
|
||||
if imageHandler == nil {
|
||||
imageHandler = handler.NewImageHandler(cfg, fileStore)
|
||||
}
|
||||
|
||||
// ========== 公开路由 ==========
|
||||
api := r.Group("/api/v1")
|
||||
@@ -62,8 +73,12 @@ func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.S
|
||||
sessions.DELETE("/:id", sessionHandler.Delete) // DELETE /api/v1/sessions/:id
|
||||
sessions.GET("/:id/messages", sessionHandler.GetMessages) // GET /api/v1/sessions/:id/messages?limit=50
|
||||
sessions.DELETE("/:id/messages", sessionHandler.ClearMessages) // DELETE /api/v1/sessions/:id/messages
|
||||
sessions.GET("/:id/export", sessionHandler.ExportSession) // GET /api/v1/sessions/:id/export?format=json|markdown|txt
|
||||
}
|
||||
|
||||
// 消息搜索
|
||||
protected.GET("/messages/search", sessionHandler.SearchMessages) // GET /api/v1/messages/search?q=xxx&user_id=xxx&limit=50&offset=0
|
||||
|
||||
// 记忆管理
|
||||
memory := protected.Group("/memory")
|
||||
{
|
||||
@@ -73,6 +88,103 @@ func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.S
|
||||
memory.DELETE("", memoryHandler.Delete)
|
||||
}
|
||||
|
||||
// 通知推送 (需要认证)
|
||||
notifications := protected.Group("/notifications")
|
||||
{
|
||||
notifications.POST("/push", notificationHandler.Push)
|
||||
}
|
||||
|
||||
// 提醒管理 (需要认证)
|
||||
reminders := protected.Group("/reminders")
|
||||
{
|
||||
reminders.GET("", reminderHandler.List) // GET /api/v1/reminders?user_id=xxx&status=pending&limit=50
|
||||
reminders.POST("", reminderHandler.Create) // POST /api/v1/reminders
|
||||
reminders.PUT("/:id", reminderHandler.Update) // PUT /api/v1/reminders/:id
|
||||
reminders.DELETE("/:id", reminderHandler.Delete) // DELETE /api/v1/reminders/:id
|
||||
}
|
||||
|
||||
// 每日简报 (需要认证)
|
||||
briefings := protected.Group("/briefings")
|
||||
{
|
||||
briefings.GET("", briefingHandler.GetBriefing) // GET /api/v1/briefings?user_id=xxx&date=2024-01-01
|
||||
briefings.GET("/latest", briefingHandler.GetLatestBriefings) // GET /api/v1/briefings/latest?user_id=xxx&limit=7
|
||||
briefings.POST("/generate", briefingHandler.Generate) // POST /api/v1/briefings/generate
|
||||
}
|
||||
|
||||
// 语音识别 + TTS (需要认证)
|
||||
voice := protected.Group("/voice")
|
||||
{
|
||||
voice.POST("/transcribe", voiceHandler.Transcribe)
|
||||
voice.POST("/tts", voiceHandler.TTSSynthesize)
|
||||
voice.GET("/tts/voices", voiceHandler.TTSVoices)
|
||||
voice.GET("/tts/status", voiceHandler.TTSStatus)
|
||||
voice.GET("/status", voiceHandler.VoiceStatus)
|
||||
}
|
||||
|
||||
// 文件管理 (需要认证)
|
||||
files := protected.Group("/files")
|
||||
{
|
||||
files.POST("/upload", fileHandler.Upload)
|
||||
files.GET("", fileHandler.List)
|
||||
files.GET("/:id", fileHandler.Get)
|
||||
files.GET("/:id/download", fileHandler.Download)
|
||||
files.GET("/:id/thumbnail", fileHandler.Thumbnail)
|
||||
files.DELETE("/:id", fileHandler.Delete)
|
||||
}
|
||||
|
||||
// 自动化 (需要认证)
|
||||
automation := protected.Group("/automation")
|
||||
{
|
||||
// 规则
|
||||
rules := automation.Group("/rules")
|
||||
{
|
||||
rules.GET("", automationHandler.ListRules) // GET /api/v1/automation/rules
|
||||
rules.POST("", automationHandler.CreateRule) // POST /api/v1/automation/rules
|
||||
rules.GET("/:id", automationHandler.GetRule) // GET /api/v1/automation/rules/:id
|
||||
rules.PUT("/:id", automationHandler.UpdateRule) // PUT /api/v1/automation/rules/:id
|
||||
rules.DELETE("/:id", automationHandler.DeleteRule) // DELETE /api/v1/automation/rules/:id
|
||||
rules.POST("/:id/trigger", automationHandler.TriggerRule) // POST /api/v1/automation/rules/:id/trigger
|
||||
}
|
||||
|
||||
// 场景
|
||||
scenes := automation.Group("/scenes")
|
||||
{
|
||||
scenes.GET("", automationHandler.ListScenes) // GET /api/v1/automation/scenes
|
||||
scenes.POST("", automationHandler.CreateScene) // POST /api/v1/automation/scenes
|
||||
scenes.GET("/:id", automationHandler.GetScene) // GET /api/v1/automation/scenes/:id
|
||||
scenes.PUT("/:id", automationHandler.UpdateScene) // PUT /api/v1/automation/scenes/:id
|
||||
scenes.DELETE("/:id", automationHandler.DeleteScene) // DELETE /api/v1/automation/scenes/:id
|
||||
scenes.POST("/:id/execute", automationHandler.ExecuteScene) // POST /api/v1/automation/scenes/:id/execute
|
||||
}
|
||||
}
|
||||
|
||||
// 知识库管理 (需要认证)
|
||||
knowledge := protected.Group("/knowledge")
|
||||
{
|
||||
// 知识库 CRUD
|
||||
knowledge.POST("/bases", knowledgeHandler.CreateKB) // POST /api/v1/knowledge/bases
|
||||
knowledge.GET("/bases", knowledgeHandler.ListKBs) // GET /api/v1/knowledge/bases
|
||||
knowledge.GET("/bases/:id", knowledgeHandler.GetKB) // GET /api/v1/knowledge/bases/:id
|
||||
knowledge.PUT("/bases/:id", knowledgeHandler.UpdateKB) // PUT /api/v1/knowledge/bases/:id
|
||||
knowledge.DELETE("/bases/:id", knowledgeHandler.DeleteKB) // DELETE /api/v1/knowledge/bases/:id
|
||||
|
||||
// 文档管理
|
||||
knowledge.POST("/bases/:id/documents", knowledgeHandler.AddDocument) // POST /api/v1/knowledge/bases/:id/documents
|
||||
knowledge.GET("/bases/:id/documents", knowledgeHandler.ListDocuments) // GET /api/v1/knowledge/bases/:id/documents
|
||||
knowledge.GET("/documents/:id", knowledgeHandler.GetDocument) // GET /api/v1/knowledge/documents/:id
|
||||
knowledge.DELETE("/documents/:id", knowledgeHandler.DeleteDocument) // DELETE /api/v1/knowledge/documents/:id
|
||||
|
||||
// 搜索
|
||||
knowledge.POST("/search", knowledgeHandler.Search) // POST /api/v1/knowledge/search
|
||||
}
|
||||
|
||||
// 图片分析 (需要认证)
|
||||
images := protected.Group("/images")
|
||||
{
|
||||
images.POST("/analyze", imageHandler.Analyze) // POST /api/v1/images/analyze
|
||||
images.GET("/analyze/:file_id", imageHandler.AnalyzeByID) // GET /api/v1/images/analyze/:file_id
|
||||
}
|
||||
|
||||
// Admin 路由 (需要管理员权限)
|
||||
admin := protected.Group("/admin")
|
||||
admin.Use(adminAuth())
|
||||
@@ -83,6 +195,13 @@ func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.S
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 内部服务路由 (使用 Internal Service Token 认证) ==========
|
||||
internal := r.Group("/api/v1/internal")
|
||||
internal.Use(notificationHandler.InternalNotifyAuth())
|
||||
{
|
||||
internal.POST("/notify", notificationHandler.InternalNotify)
|
||||
}
|
||||
|
||||
// ========== WebSocket路由 ==========
|
||||
// WebSocket升级在HTTP层,token通过query参数或Header传递
|
||||
wsGroup := r.Group("/ws")
|
||||
|
||||
Reference in New Issue
Block a user