package knowledge import ( "encoding/json" "net/http" "strconv" "git.iwork-ai.com/xdc/iqudo-top1/internal/audit" "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" "gorm.io/gorm" ) type Handler struct{ db *gorm.DB } func NewHandler(db *gorm.DB) *Handler { return &Handler{db: db} } type input struct { ScenarioID uint64 `json:"scenario_id" binding:"required"` Title string `json:"title" binding:"required,max=128"` Content map[string]interface{} `json:"content" binding:"required"` } func (h *Handler) List(c *gin.Context) { p, _ := auth.PrincipalFromContext(c) type row struct { model.KnowledgeCard Content datatypes.JSON `json:"content"` } var items []row err := h.db.Table("knowledge_cards kc").Select("kc.*, kcv.content").Joins("LEFT JOIN knowledge_card_versions kcv ON kcv.knowledge_card_id = kc.id AND kcv.status = ?", "published").Where("kc.tenant_id = ?", p.TenantID).Order("kc.updated_at DESC").Scan(&items).Error if err != nil { response.Error(c, http.StatusInternalServerError, "QUERY_FAILED", "查询知识卡失败") return } response.OK(c, gin.H{"items": items, "total": len(items)}) } func (h *Handler) Create(c *gin.Context) { p, _ := auth.PrincipalFromContext(c) var body input if err := c.ShouldBindJSON(&body); err != nil { response.Error(c, http.StatusBadRequest, "INVALID_ARGUMENT", "知识卡内容不完整") return } content, _ := json.Marshal(body.Content) var card model.KnowledgeCard err := h.db.Transaction(func(tx *gorm.DB) error { card = model.KnowledgeCard{TenantID: p.TenantID, ScenarioID: body.ScenarioID, Title: body.Title, Status: "published", CreatedBy: p.UserID} if err := tx.Create(&card).Error; err != nil { return err } return tx.Create(&model.KnowledgeCardVersion{TenantID: p.TenantID, KnowledgeCardID: card.ID, Version: 1, Content: datatypes.JSON(content), Status: "published"}).Error }) if err != nil { response.Error(c, http.StatusInternalServerError, "CREATE_FAILED", "创建知识卡失败") return } _ = audit.Record(h.db, p, "create", "knowledge_card", card.ID, body) response.Created(c, card) } func (h *Handler) Delete(c *gin.Context) { p, _ := auth.PrincipalFromContext(c) id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Error(c, http.StatusBadRequest, "INVALID_ID", "知识卡 ID 不正确") return } result := h.db.Model(&model.KnowledgeCard{}).Where("id = ? AND tenant_id = ?", id, p.TenantID).Update("status", "archived") if result.Error != nil || result.RowsAffected == 0 { response.Error(c, http.StatusNotFound, "NOT_FOUND", "知识卡不存在") return } response.OK(c, gin.H{"id": id}) }