package handler import ( "net/http" "time" "github.com/gin-gonic/gin" "kefu-sys/server/internal/middleware" "kefu-sys/server/internal/model" ) type SessionHandler struct{} func NewSessionHandler() *SessionHandler { return &SessionHandler{} } type SendMessageReq struct { Content string `json:"content" binding:"required"` Type string `json:"type"` } func (h *SessionHandler) SendMessage(c *gin.Context) { tenantID := middleware.GetTenantID(c) userID := middleware.GetUserID(c) id := c.Param("id") var req SendMessageReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } if req.Type == "" { req.Type = "text" } var session model.Session if err := model.DB.Where("id = ? AND tenant_id = ?", id, tenantID).First(&session).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "会话不存在"}) return } var maxSeq int model.DB.Model(&model.Message{}).Where("session_id = ?", session.ID).Select("COALESCE(MAX(seq), 0)").Scan(&maxSeq) msg := model.Message{ SessionID: session.ID, SenderType: "agent", SenderID: &userID, Content: req.Content, Type: req.Type, Seq: maxSeq + 1, SentAt: time.Now(), } if err := model.DB.Create(&msg).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "发送失败"}) return } middleware.JSON(c, msg) } type CreateSessionReq struct { ChannelID uint `json:"channel_id"` CustomerID uint `json:"customer_id"` Priority string `json:"priority"` } type AssignSessionReq struct { AgentID uint `json:"agent_id" binding:"required"` } func (h *SessionHandler) List(c *gin.Context) { tenantID := middleware.GetTenantID(c) page, pageSize := middleware.GetPageParams(c) status := c.Query("status") priority := c.Query("priority") var sessions []model.Session var total int64 query := model.DB.Where("tenant_id = ?", tenantID) if status != "" { query = query.Where("status = ?", status) } if priority != "" { query = query.Where("priority = ?", priority) } query.Model(&model.Session{}).Count(&total) query.Order("created_at desc").Offset((page - 1) * pageSize).Limit(pageSize).Find(&sessions) middleware.JSONList(c, sessions, total, page, pageSize) } func (h *SessionHandler) Get(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") var session model.Session if err := model.DB.Where("id = ? AND tenant_id = ?", id, tenantID).First(&session).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "会话不存在"}) return } var messages []model.Message model.DB.Where("session_id = ?", session.ID).Order("seq asc").Find(&messages) middleware.JSON(c, gin.H{"session": session, "messages": messages}) } func (h *SessionHandler) Create(c *gin.Context) { var req CreateSessionReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } session := model.Session{ TenantID: middleware.GetTenantID(c), ChannelID: req.ChannelID, CustomerID: req.CustomerID, Priority: req.Priority, Status: "waiting", } if session.Priority == "" { session.Priority = "normal" } if err := model.DB.Create(&session).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "创建会话失败"}) return } middleware.JSON(c, session) } func (h *SessionHandler) Assign(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") var req AssignSessionReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } result := model.DB.Model(&model.Session{}). Where("id = ? AND tenant_id = ? AND status = ?", id, tenantID, "waiting"). Updates(map[string]interface{}{"agent_id": req.AgentID, "status": "active"}) if result.RowsAffected == 0 { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "会话不存在或已被分配"}) return } middleware.JSON(c, gin.H{"message": "分配成功"}) } func (h *SessionHandler) Transfer(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") var req AssignSessionReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "参数错误"}) return } model.DB.Model(&model.Session{}). Where("id = ? AND tenant_id = ?", id, tenantID). Update("agent_id", req.AgentID) model.DB.Create(&model.SessionEvent{ SessionID: parseID(id), OperatorID: middleware.GetUserID(c), Action: "transfer", Detail: "会话转接", }) middleware.JSON(c, gin.H{"message": "转接成功"}) } func (h *SessionHandler) End(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") reason := c.Query("reason") result := model.DB.Model(&model.Session{}). Where("id = ? AND tenant_id = ?", id, tenantID). Updates(map[string]interface{}{"status": "ended", "end_reason": reason}) if result.RowsAffected == 0 { c.JSON(http.StatusNotFound, gin.H{"code": 404, "message": "会话不存在"}) return } model.DB.Create(&model.SessionEvent{ SessionID: parseID(id), OperatorID: middleware.GetUserID(c), Action: "end", Detail: "结束会话: " + reason, }) middleware.JSON(c, gin.H{"message": "已结束"}) } func (h *SessionHandler) UpdatePriority(c *gin.Context) { tenantID := middleware.GetTenantID(c) id := c.Param("id") priority := c.Query("priority") model.DB.Model(&model.Session{}). Where("id = ? AND tenant_id = ?", id, tenantID). Update("priority", priority) middleware.JSON(c, gin.H{"message": "已更新"}) } func parseID(s string) uint { var id uint for _, c := range s { if c >= '0' && c <= '9' { id = id*10 + uint(c-'0') } } return id }