mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-04-21 02:06:46 +02:00
309 lines
8.6 KiB
Go
309 lines
8.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"cyberstrike-ai/internal/database"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// GroupHandler 分组处理器
|
|
type GroupHandler struct {
|
|
db *database.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewGroupHandler 创建新的分组处理器
|
|
func NewGroupHandler(db *database.DB, logger *zap.Logger) *GroupHandler {
|
|
return &GroupHandler{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// CreateGroupRequest 创建分组请求
|
|
type CreateGroupRequest struct {
|
|
Name string `json:"name"`
|
|
Icon string `json:"icon"`
|
|
}
|
|
|
|
// CreateGroup 创建分组
|
|
func (h *GroupHandler) CreateGroup(c *gin.Context) {
|
|
var req CreateGroupRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if req.Name == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "分组名称不能为空"})
|
|
return
|
|
}
|
|
|
|
group, err := h.db.CreateGroup(req.Name, req.Icon)
|
|
if err != nil {
|
|
h.logger.Error("创建分组失败", zap.Error(err))
|
|
// 如果是名称重复错误,返回400状态码
|
|
if err.Error() == "分组名称已存在" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "分组名称已存在"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, group)
|
|
}
|
|
|
|
// ListGroups 列出所有分组
|
|
func (h *GroupHandler) ListGroups(c *gin.Context) {
|
|
groups, err := h.db.ListGroups()
|
|
if err != nil {
|
|
h.logger.Error("获取分组列表失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, groups)
|
|
}
|
|
|
|
// GetGroup 获取分组
|
|
func (h *GroupHandler) GetGroup(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
group, err := h.db.GetGroup(id)
|
|
if err != nil {
|
|
h.logger.Error("获取分组失败", zap.Error(err))
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "分组不存在"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, group)
|
|
}
|
|
|
|
// UpdateGroupRequest 更新分组请求
|
|
type UpdateGroupRequest struct {
|
|
Name string `json:"name"`
|
|
Icon string `json:"icon"`
|
|
}
|
|
|
|
// UpdateGroup 更新分组
|
|
func (h *GroupHandler) UpdateGroup(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
var req UpdateGroupRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if req.Name == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "分组名称不能为空"})
|
|
return
|
|
}
|
|
|
|
if err := h.db.UpdateGroup(id, req.Name, req.Icon); err != nil {
|
|
h.logger.Error("更新分组失败", zap.Error(err))
|
|
// 如果是名称重复错误,返回400状态码
|
|
if err.Error() == "分组名称已存在" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "分组名称已存在"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
group, err := h.db.GetGroup(id)
|
|
if err != nil {
|
|
h.logger.Error("获取更新后的分组失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, group)
|
|
}
|
|
|
|
// DeleteGroup 删除分组
|
|
func (h *GroupHandler) DeleteGroup(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
if err := h.db.DeleteGroup(id); err != nil {
|
|
h.logger.Error("删除分组失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
|
|
}
|
|
|
|
// AddConversationToGroupRequest 添加对话到分组请求
|
|
type AddConversationToGroupRequest struct {
|
|
ConversationID string `json:"conversationId"`
|
|
GroupID string `json:"groupId"`
|
|
}
|
|
|
|
// AddConversationToGroup 将对话添加到分组
|
|
func (h *GroupHandler) AddConversationToGroup(c *gin.Context) {
|
|
var req AddConversationToGroupRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.db.AddConversationToGroup(req.ConversationID, req.GroupID); err != nil {
|
|
h.logger.Error("添加对话到分组失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "添加成功"})
|
|
}
|
|
|
|
// RemoveConversationFromGroup 从分组中移除对话
|
|
func (h *GroupHandler) RemoveConversationFromGroup(c *gin.Context) {
|
|
conversationID := c.Param("conversationId")
|
|
groupID := c.Param("id")
|
|
|
|
if err := h.db.RemoveConversationFromGroup(conversationID, groupID); err != nil {
|
|
h.logger.Error("从分组中移除对话失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "移除成功"})
|
|
}
|
|
|
|
// GroupConversation 分组对话响应结构
|
|
type GroupConversation struct {
|
|
ID string `json:"id"`
|
|
Title string `json:"title"`
|
|
Pinned bool `json:"pinned"`
|
|
GroupPinned bool `json:"groupPinned"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
}
|
|
|
|
// GetGroupConversations 获取分组中的所有对话
|
|
func (h *GroupHandler) GetGroupConversations(c *gin.Context) {
|
|
groupID := c.Param("id")
|
|
searchQuery := c.Query("search") // 获取搜索参数
|
|
|
|
var conversations []*database.Conversation
|
|
var err error
|
|
|
|
// 如果有搜索关键词,使用搜索方法;否则使用普通方法
|
|
if searchQuery != "" {
|
|
conversations, err = h.db.SearchConversationsByGroup(groupID, searchQuery)
|
|
} else {
|
|
conversations, err = h.db.GetConversationsByGroup(groupID)
|
|
}
|
|
|
|
if err != nil {
|
|
h.logger.Error("获取分组对话失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// 获取每个对话在分组中的置顶状态
|
|
groupConvs := make([]GroupConversation, 0, len(conversations))
|
|
for _, conv := range conversations {
|
|
// 查询分组内置顶状态
|
|
var groupPinned int
|
|
err := h.db.QueryRow(
|
|
"SELECT COALESCE(pinned, 0) FROM conversation_group_mappings WHERE conversation_id = ? AND group_id = ?",
|
|
conv.ID, groupID,
|
|
).Scan(&groupPinned)
|
|
if err != nil {
|
|
h.logger.Warn("查询分组内置顶状态失败", zap.String("conversationId", conv.ID), zap.Error(err))
|
|
groupPinned = 0
|
|
}
|
|
|
|
groupConvs = append(groupConvs, GroupConversation{
|
|
ID: conv.ID,
|
|
Title: conv.Title,
|
|
Pinned: conv.Pinned,
|
|
GroupPinned: groupPinned != 0,
|
|
CreatedAt: conv.CreatedAt,
|
|
UpdatedAt: conv.UpdatedAt,
|
|
})
|
|
}
|
|
|
|
c.JSON(http.StatusOK, groupConvs)
|
|
}
|
|
|
|
// UpdateConversationPinnedRequest 更新对话置顶状态请求
|
|
type UpdateConversationPinnedRequest struct {
|
|
Pinned bool `json:"pinned"`
|
|
}
|
|
|
|
// UpdateConversationPinned 更新对话置顶状态
|
|
func (h *GroupHandler) UpdateConversationPinned(c *gin.Context) {
|
|
conversationID := c.Param("id")
|
|
|
|
var req UpdateConversationPinnedRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.db.UpdateConversationPinned(conversationID, req.Pinned); err != nil {
|
|
h.logger.Error("更新对话置顶状态失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
|
|
}
|
|
|
|
// UpdateGroupPinnedRequest 更新分组置顶状态请求
|
|
type UpdateGroupPinnedRequest struct {
|
|
Pinned bool `json:"pinned"`
|
|
}
|
|
|
|
// UpdateGroupPinned 更新分组置顶状态
|
|
func (h *GroupHandler) UpdateGroupPinned(c *gin.Context) {
|
|
groupID := c.Param("id")
|
|
|
|
var req UpdateGroupPinnedRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.db.UpdateGroupPinned(groupID, req.Pinned); err != nil {
|
|
h.logger.Error("更新分组置顶状态失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
|
|
}
|
|
|
|
// UpdateConversationPinnedInGroupRequest 更新分组对话置顶状态请求
|
|
type UpdateConversationPinnedInGroupRequest struct {
|
|
Pinned bool `json:"pinned"`
|
|
}
|
|
|
|
// UpdateConversationPinnedInGroup 更新对话在分组中的置顶状态
|
|
func (h *GroupHandler) UpdateConversationPinnedInGroup(c *gin.Context) {
|
|
groupID := c.Param("id")
|
|
conversationID := c.Param("conversationId")
|
|
|
|
var req UpdateConversationPinnedInGroupRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.db.UpdateConversationPinnedInGroup(conversationID, groupID, req.Pinned); err != nil {
|
|
h.logger.Error("更新分组对话置顶状态失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
|
|
}
|