Files
iqudo-top1/internal/run/detail.go
2026-08-08 22:58:35 +08:00

67 lines
2.8 KiB
Go

package run
import (
"net/http"
"git.iwork-ai.com/xdc/iqudo-top1/internal/auth"
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
"git.iwork-ai.com/xdc/iqudo-top1/internal/response"
"github.com/gin-gonic/gin"
"gorm.io/datatypes"
)
type DetailHeader struct {
model.SOPRun
SOPName string `json:"sop_name"`
ScenarioName string `json:"scenario_name"`
Version int `json:"version"`
OperatorName string `json:"operator_name"`
}
type DetailEvent struct {
model.SOPRunEvent
NodeTitle string `json:"node_title"`
NodeType string `json:"node_type"`
NodeContent string `json:"node_content"`
}
type DetailFeedback struct {
model.SOPFeedback
UserName string `json:"user_name"`
}
func (h *Handler) Detail(c *gin.Context) {
principal, _ := auth.PrincipalFromContext(c)
id, ok := runID(c)
if !ok {
return
}
var header DetailHeader
err := h.db.Table("sop_runs r").Select(
"r.*, s.name AS sop_name, sc.name AS scenario_name, sv.version, u.display_name AS operator_name",
).Joins("JOIN sops s ON s.id = r.sop_id").Joins("JOIN scenarios sc ON sc.id = s.scenario_id").Joins("JOIN sop_versions sv ON sv.id = r.sop_version_id").Joins("JOIN users u ON u.id = r.operator_id").Where("r.id = ? AND r.tenant_id = ?", id, principal.TenantID).Scan(&header).Error
if err != nil || header.ID == 0 || !canViewRun(principal, header.SOPRun) {
response.Error(c, http.StatusNotFound, "NOT_FOUND", "执行记录不存在")
return
}
events := make([]DetailEvent, 0)
if err := h.db.Table("sop_run_events e").Select("e.*, n.title AS node_title, n.type AS node_type, n.content AS node_content").Joins("LEFT JOIN sop_nodes n ON n.sop_version_id = ? AND n.node_key = e.node_key", header.SOPVersionID).Where("e.run_id = ? AND e.tenant_id = ?", id, principal.TenantID).Order("e.created_at, e.id").Scan(&events).Error; err != nil {
response.Error(c, http.StatusInternalServerError, "QUERY_FAILED", "查询执行事件失败")
return
}
feedback := make([]DetailFeedback, 0)
if err := h.db.Table("sop_feedback f").Select("f.*, u.display_name AS user_name").Joins("JOIN users u ON u.id = f.user_id").Where("f.run_id = ? AND f.tenant_id = ?", id, principal.TenantID).Order("f.created_at").Scan(&feedback).Error; err != nil {
response.Error(c, http.StatusInternalServerError, "QUERY_FAILED", "查询执行反馈失败")
return
}
fields := make([]model.ScenarioField, 0)
if err := h.db.Table("scenario_fields sf").Joins("JOIN sops s ON s.scenario_id = sf.scenario_id").Where("s.id = ? AND sf.tenant_id = ?", header.SOPID, principal.TenantID).Order("sf.sort_order, sf.id").Find(&fields).Error; err != nil {
response.Error(c, http.StatusInternalServerError, "QUERY_FAILED", "查询场景字段失败")
return
}
if header.Answers == nil {
header.Answers = datatypes.JSON([]byte(`{}`))
}
response.OK(c, gin.H{"run": header, "events": events, "feedback": feedback, "fields": fields})
}