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:
2026-05-19 12:01:09 +08:00
parent 78e3f450c2
commit bcf4d4e621
69 changed files with 14599 additions and 150 deletions
+120 -1
View File
@@ -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")