优化实时聊天:稳定 WS、按 seq 增量同步,并修复访客评价推送
- 客服/访客 WebSocket 不再因切换会话反复重连,断线自动恢复 - 新增 after_seq 增量拉取,重连与消息空洞时 catch-up - 结束会话同时推送给访客,预览页可弹出评价并支持兜底状态同步
This commit is contained in:
@@ -479,15 +479,61 @@ func (h *WidgetHandler) GetMessages(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "会话参数错误"})
|
||||
return
|
||||
}
|
||||
if _, ok := loadVisitorSession(c, uint(sessionID), visitorTokenFromRequest(c, "")); !ok {
|
||||
session, ok := loadVisitorSession(c, uint(sessionID), visitorTokenFromRequest(c, ""))
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
afterSeq := 0
|
||||
if raw := strings.TrimSpace(c.Query("after_seq")); raw != "" {
|
||||
parsed, err := strconv.Atoi(raw)
|
||||
if err != nil || parsed < 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "after_seq 无效"})
|
||||
return
|
||||
}
|
||||
afterSeq = parsed
|
||||
}
|
||||
|
||||
limit := 200
|
||||
if raw := strings.TrimSpace(c.Query("limit")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 {
|
||||
if parsed > 500 {
|
||||
parsed = 500
|
||||
}
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
|
||||
query := model.DB.Where("session_id = ?", sessionID)
|
||||
if afterSeq > 0 {
|
||||
query = query.Where("seq > ?", afterSeq)
|
||||
}
|
||||
|
||||
var messages []model.Message
|
||||
if err := model.DB.Where("session_id = ?", sessionID).Order("seq asc").Find(&messages).Error; err != nil {
|
||||
if err := query.Order("seq asc").Limit(limit).Find(&messages).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "查询消息失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "data": messages})
|
||||
var maxSeq int
|
||||
if err := model.DB.Model(&model.Message{}).
|
||||
Where("session_id = ?", sessionID).
|
||||
Select("COALESCE(MAX(seq), 0)").
|
||||
Scan(&maxSeq).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "查询消息失败"})
|
||||
return
|
||||
}
|
||||
|
||||
hasMore := len(messages) >= limit && (len(messages) == 0 || messages[len(messages)-1].Seq < maxSeq)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": gin.H{
|
||||
"messages": messages,
|
||||
"after_seq": afterSeq,
|
||||
"max_seq": maxSeq,
|
||||
"has_more": hasMore,
|
||||
"session_status": session.Status,
|
||||
"satisfaction_score": session.SatisfactionScore,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user