mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-11 02:08:51 +02:00
Add files via upload
This commit is contained in:
3 files changed
+101
-1
No files matched your search
@@ -661,6 +661,7 @@ func setupRoutes(
|
|||||||
protected.POST("/conversations", conversationHandler.CreateConversation)
|
protected.POST("/conversations", conversationHandler.CreateConversation)
|
||||||
protected.GET("/conversations", conversationHandler.ListConversations)
|
protected.GET("/conversations", conversationHandler.ListConversations)
|
||||||
protected.GET("/conversations/:id", conversationHandler.GetConversation)
|
protected.GET("/conversations/:id", conversationHandler.GetConversation)
|
||||||
|
protected.GET("/messages/:id/process-details", conversationHandler.GetMessageProcessDetails)
|
||||||
protected.PUT("/conversations/:id", conversationHandler.UpdateConversation)
|
protected.PUT("/conversations/:id", conversationHandler.UpdateConversation)
|
||||||
protected.DELETE("/conversations/:id", conversationHandler.DeleteConversation)
|
protected.DELETE("/conversations/:id", conversationHandler.DeleteConversation)
|
||||||
protected.PUT("/conversations/:id/pinned", groupHandler.UpdateConversationPinned)
|
protected.PUT("/conversations/:id/pinned", groupHandler.UpdateConversationPinned)
|
||||||
|
|||||||
@@ -256,6 +256,53 @@ func (db *DB) GetConversation(id string) (*Conversation, error) {
|
|||||||
return &conv, nil
|
return &conv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConversationLite 获取对话(轻量版):包含 messages,但不加载 process_details。
|
||||||
|
// 用于历史会话快速切换,避免一次性把大体量过程详情灌到前端导致卡顿。
|
||||||
|
func (db *DB) GetConversationLite(id string) (*Conversation, error) {
|
||||||
|
var conv Conversation
|
||||||
|
var createdAt, updatedAt string
|
||||||
|
var pinned int
|
||||||
|
|
||||||
|
err := db.QueryRow(
|
||||||
|
"SELECT id, title, pinned, created_at, updated_at FROM conversations WHERE id = ?",
|
||||||
|
id,
|
||||||
|
).Scan(&conv.ID, &conv.Title, &pinned, &createdAt, &updatedAt)
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, fmt.Errorf("对话不存在")
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("查询对话失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试多种时间格式解析
|
||||||
|
var err1, err2 error
|
||||||
|
conv.CreatedAt, err1 = time.Parse("2006-01-02 15:04:05.999999999-07:00", createdAt)
|
||||||
|
if err1 != nil {
|
||||||
|
conv.CreatedAt, err1 = time.Parse("2006-01-02 15:04:05", createdAt)
|
||||||
|
}
|
||||||
|
if err1 != nil {
|
||||||
|
conv.CreatedAt, _ = time.Parse(time.RFC3339, createdAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.UpdatedAt, err2 = time.Parse("2006-01-02 15:04:05.999999999-07:00", updatedAt)
|
||||||
|
if err2 != nil {
|
||||||
|
conv.UpdatedAt, err2 = time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||||
|
}
|
||||||
|
if err2 != nil {
|
||||||
|
conv.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.Pinned = pinned != 0
|
||||||
|
|
||||||
|
// 加载消息(不加载 process_details)
|
||||||
|
messages, err := db.GetMessages(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("加载消息失败: %w", err)
|
||||||
|
}
|
||||||
|
conv.Messages = messages
|
||||||
|
return &conv, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListConversations 列出所有对话
|
// ListConversations 列出所有对话
|
||||||
func (db *DB) ListConversations(limit, offset int, search string) ([]*Conversation, error) {
|
func (db *DB) ListConversations(limit, offset int, search string) ([]*Conversation, error) {
|
||||||
var rows *sql.Rows
|
var rows *sql.Rows
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@@ -78,7 +79,20 @@ func (h *ConversationHandler) ListConversations(c *gin.Context) {
|
|||||||
func (h *ConversationHandler) GetConversation(c *gin.Context) {
|
func (h *ConversationHandler) GetConversation(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
|
|
||||||
conv, err := h.db.GetConversation(id)
|
// 默认轻量加载,只有用户需要展开详情时再按需拉取
|
||||||
|
// include_process_details=1/true 时返回全量 processDetails(兼容旧行为)
|
||||||
|
includeStr := c.DefaultQuery("include_process_details", "0")
|
||||||
|
include := includeStr == "1" || includeStr == "true" || includeStr == "yes"
|
||||||
|
|
||||||
|
var (
|
||||||
|
conv *database.Conversation
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if include {
|
||||||
|
conv, err = h.db.GetConversation(id)
|
||||||
|
} else {
|
||||||
|
conv, err = h.db.GetConversationLite(id)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Error("获取对话失败", zap.Error(err))
|
h.logger.Error("获取对话失败", zap.Error(err))
|
||||||
c.JSON(http.StatusNotFound, gin.H{"error": "对话不存在"})
|
c.JSON(http.StatusNotFound, gin.H{"error": "对话不存在"})
|
||||||
@@ -88,6 +102,44 @@ func (h *ConversationHandler) GetConversation(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, conv)
|
c.JSON(http.StatusOK, conv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMessageProcessDetails 获取指定消息的过程详情(按需加载)
|
||||||
|
func (h *ConversationHandler) GetMessageProcessDetails(c *gin.Context) {
|
||||||
|
messageID := c.Param("id")
|
||||||
|
if messageID == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "message id required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
details, err := h.db.GetProcessDetails(messageID)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("获取过程详情失败", zap.Error(err))
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为前端期望的 JSON 结构(与 GetConversation 中 processDetails 结构一致)
|
||||||
|
out := make([]map[string]interface{}, 0, len(details))
|
||||||
|
for _, d := range details {
|
||||||
|
var data interface{}
|
||||||
|
if d.Data != "" {
|
||||||
|
if err := json.Unmarshal([]byte(d.Data), &data); err != nil {
|
||||||
|
h.logger.Warn("解析过程详情数据失败", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out = append(out, map[string]interface{}{
|
||||||
|
"id": d.ID,
|
||||||
|
"messageId": d.MessageID,
|
||||||
|
"conversationId": d.ConversationID,
|
||||||
|
"eventType": d.EventType,
|
||||||
|
"message": d.Message,
|
||||||
|
"data": data,
|
||||||
|
"createdAt": d.CreatedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"processDetails": out})
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateConversationRequest 更新对话请求
|
// UpdateConversationRequest 更新对话请求
|
||||||
type UpdateConversationRequest struct {
|
type UpdateConversationRequest struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
|
|||||||
Reference in new issue
Block a user