Files
xk-ai-agent/internal/handler/history_handler.go
2026-08-15 17:05:22 +08:00

104 lines
3.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"net/http"
"strconv"
"tcm-agent/internal/dao"
"github.com/gin-gonic/gin"
)
// ========================================================================
// HistoryHandler —— AI 生成历史DB 长期数据)只读查询
// ========================================================================
// 暴露 3 个端点(前缀 /api/v1/agent
// GET /history 分页列表(场景/状态/via_agent/供应商/日期筛选)
// GET /history/:id 单条详情 + 步骤时间线
// GET /history/scenes 出现过的场景列表(前端筛选下拉)
//
// 与 /agent/runs 的区别:
// - runs内存环形缓冲最近 200 条,含守卫拦截等"没到 PHP"的运行,重启清零
// - history读 PHP 落库的 xk_ai_generation(_step),长期审计视角,只读
// ========================================================================
// HistoryHandler 历史查询处理器
type HistoryHandler struct{}
// NewHistoryHandler 构造
func NewHistoryHandler() *HistoryHandler {
return &HistoryHandler{}
}
// List 分页查询历史
// GET /api/v1/agent/history?page=1&size=20&scene=&status=-1&via_agent=-1&is_archived=-1&is_correct=-1&provider=&date_start=0&date_end=0
func (h *HistoryHandler) List(c *gin.Context) {
filter := dao.AIGenerationListFilter{
Page: queryInt(c, "page", 1),
Size: queryInt(c, "size", 20),
Scene: c.Query("scene"),
Status: queryInt(c, "status", -1),
ViaAgent: queryInt(c, "via_agent", -1),
Provider: c.Query("provider"),
IsArchived: queryInt(c, "is_archived", -1),
IsCorrect: queryInt(c, "is_correct", -1),
}
filter.DateStart = int64(queryInt(c, "date_start", 0))
filter.DateEnd = int64(queryInt(c, "date_end", 0))
rows, total, err := dao.AIGenerationList(filter)
if err != nil {
c.JSON(http.StatusOK, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{
"list": rows,
"total": total,
"page": filter.Page,
"size": filter.Size,
}})
}
// Detail 单条详情 + 步骤
// GET /api/v1/agent/history/:id
func (h *HistoryHandler) Detail(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil || id == 0 {
c.JSON(http.StatusOK, gin.H{"code": 400, "message": "id 参数无效"})
return
}
row, steps, err := dao.AIGenerationGet(uint(id))
if err != nil {
c.JSON(http.StatusOK, gin.H{"code": 404, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{
"generation": row,
"steps": steps,
}})
}
// Scenes 场景下拉数据
// GET /api/v1/agent/history/scenes
func (h *HistoryHandler) Scenes(c *gin.Context) {
scenes, err := dao.AIGenerationScenes()
if err != nil {
c.JSON(http.StatusOK, gin.H{"code": 500, "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"code": 200, "data": scenes})
}
// queryInt 读取整型 query 参数,缺失或非法时返回默认值
func queryInt(c *gin.Context, key string, def int) int {
v := c.Query(key)
if v == "" {
return def
}
n, err := strconv.Atoi(v)
if err != nil {
return def
}
return n
}