fix: remove legacy knowledge card tables and compatibility code

This commit is contained in:
Eric 1549169735@qq.com
2026-08-20 21:58:04 +08:00
parent ebaf9b0b05
commit 6185e6cd49
36 changed files with 545 additions and 546 deletions

View File

@@ -96,27 +96,22 @@ func (h *Handler) Create(c *gin.Context) {
return
}
var item model.SOP
var version model.SOPVersion
err := h.db.Transaction(func(tx *gorm.DB) error {
item = model.SOP{TenantID: p.TenantID, ScenarioID: scenarioID, Name: input.Name, Description: input.Description, Status: "published", CreatedBy: p.UserID}
item = model.SOP{TenantID: p.TenantID, ScenarioID: scenarioID, Name: input.Name, Description: input.Description, Status: "published", CreatedBy: p.UserID, StartNodeKey: "start"}
if err := tx.Create(&item).Error; err != nil {
return err
}
version = model.SOPVersion{TenantID: p.TenantID, SOPID: item.ID, Version: 1, Status: "published", StartNodeKey: "start", CreatedBy: p.UserID}
if err := tx.Create(&version).Error; err != nil {
return err
}
nodes := []model.SOPNode{
{TenantID: p.TenantID, SOPVersionID: version.ID, NodeKey: "start", Type: "start", Title: "开始", Content: "", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 0},
{TenantID: p.TenantID, SOPVersionID: version.ID, NodeKey: "opening", Type: "message", Title: "开场", Content: "您好,我先了解一下具体情况。", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 120},
{TenantID: p.TenantID, SOPVersionID: version.ID, NodeKey: "finish", Type: "finish", Title: "结束", Content: "本次沟通已完成。", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 240},
{TenantID: p.TenantID, SOPID: item.ID, NodeKey: "start", Type: "start", Title: "开始", Content: "", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 0},
{TenantID: p.TenantID, SOPID: item.ID, NodeKey: "opening", Type: "message", Title: "开场", Content: "您好,我先了解一下具体情况。", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 120},
{TenantID: p.TenantID, SOPID: item.ID, NodeKey: "finish", Type: "finish", Title: "结束", Content: "本次沟通已完成。", Config: datatypes.JSON([]byte(`{}`)), PositionX: 0, PositionY: 240},
}
if err := tx.Create(&nodes).Error; err != nil {
return err
}
edges := []model.SOPEdge{
{TenantID: p.TenantID, SOPVersionID: version.ID, SourceNodeKey: "start", TargetNodeKey: "opening", Condition: datatypes.JSON([]byte(`{}`)), Priority: 0},
{TenantID: p.TenantID, SOPVersionID: version.ID, SourceNodeKey: "opening", TargetNodeKey: "finish", Condition: datatypes.JSON([]byte(`{}`)), Priority: 0},
{TenantID: p.TenantID, SOPID: item.ID, SourceNodeKey: "start", TargetNodeKey: "opening", Condition: datatypes.JSON([]byte(`{}`)), Priority: 0},
{TenantID: p.TenantID, SOPID: item.ID, SourceNodeKey: "opening", TargetNodeKey: "finish", Condition: datatypes.JSON([]byte(`{}`)), Priority: 0},
}
if err := tx.Create(&edges).Error; err != nil {
return err
@@ -128,7 +123,7 @@ func (h *Handler) Create(c *gin.Context) {
return
}
_ = audit.Record(h.db, p, "create", "sop", item.ID, input)
response.Created(c, gin.H{"sop": item, "edit": editState{StartNodeKey: version.StartNodeKey}})
response.Created(c, gin.H{"sop": item, "edit": editState{StartNodeKey: item.StartNodeKey}})
}
func (h *Handler) Get(c *gin.Context) {
@@ -142,10 +137,9 @@ func (h *Handler) Get(c *gin.Context) {
return
}
var item model.SOP
var version model.SOPVersion
var nodes []model.SOPNode
var edges []model.SOPEdge
item, version, nodes, edges, err := h.loadLatest(id, p.TenantID)
item, nodes, edges, err := h.load(id, p.TenantID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
response.Error(c, http.StatusNotFound, "NOT_FOUND", "SOP 不存在")
@@ -154,7 +148,7 @@ func (h *Handler) Get(c *gin.Context) {
}
return
}
response.OK(c, gin.H{"sop": item, "edit": editState{StartNodeKey: version.StartNodeKey}, "nodes": nodes, "edges": edges})
response.OK(c, gin.H{"sop": item, "edit": editState{StartNodeKey: item.StartNodeKey}, "nodes": nodes, "edges": edges})
}
func (h *Handler) SaveGraph(c *gin.Context) {
@@ -172,12 +166,12 @@ func (h *Handler) SaveGraph(c *gin.Context) {
response.Error(c, http.StatusBadRequest, "INVALID_ARGUMENT", "流程配置不完整")
return
}
item, version, _, _, err := h.loadLatest(id, p.TenantID)
item, _, _, err := h.load(id, p.TenantID)
if err != nil {
response.Error(c, http.StatusNotFound, "NOT_FOUND", "SOP 不存在")
return
}
nodes, edges := toModels(p.TenantID, version.ID, input)
nodes, edges := toModels(p.TenantID, id, input)
problems, validationErr := h.validateForPublish(item, input.StartNodeKey, nodes, edges, p.TenantID)
if validationErr != nil {
response.Error(c, http.StatusInternalServerError, "VALIDATION_FAILED", "校验流程失败")
@@ -188,10 +182,10 @@ func (h *Handler) SaveGraph(c *gin.Context) {
return
}
err = h.db.Transaction(func(tx *gorm.DB) error {
if err := tx.Where("sop_version_id = ?", version.ID).Delete(&model.SOPEdge{}).Error; err != nil {
if err := tx.Where("sop_id = ? AND tenant_id = ?", id, p.TenantID).Delete(&model.SOPEdge{}).Error; err != nil {
return err
}
if err := tx.Where("sop_version_id = ?", version.ID).Delete(&model.SOPNode{}).Error; err != nil {
if err := tx.Where("sop_id = ? AND tenant_id = ?", id, p.TenantID).Delete(&model.SOPNode{}).Error; err != nil {
return err
}
if err := tx.Create(&nodes).Error; err != nil {
@@ -202,10 +196,7 @@ func (h *Handler) SaveGraph(c *gin.Context) {
return err
}
}
if err := tx.Model(&model.SOPVersion{}).Where("sop_id = ? AND tenant_id = ? AND id <> ?", id, p.TenantID, version.ID).Update("status", "superseded").Error; err != nil {
return err
}
if err := tx.Model(&version).Updates(map[string]interface{}{"start_node_key": input.StartNodeKey, "status": "published"}).Error; err != nil {
if err := tx.Model(&item).Updates(map[string]interface{}{"start_node_key": input.StartNodeKey, "status": "published"}).Error; err != nil {
return err
}
if err := tx.Model(&item).Update("status", "published").Error; err != nil {
@@ -232,15 +223,14 @@ func (h *Handler) Validate(c *gin.Context) {
return
}
var item model.SOP
var version model.SOPVersion
var nodes []model.SOPNode
var edges []model.SOPEdge
item, version, nodes, edges, err := h.loadLatest(id, p.TenantID)
item, nodes, edges, err := h.load(id, p.TenantID)
if err != nil {
response.Error(c, http.StatusNotFound, "NOT_FOUND", "SOP 不存在")
return
}
problems, err := h.validateForPublish(item, version.StartNodeKey, nodes, edges, p.TenantID)
problems, err := h.validateForPublish(item, item.StartNodeKey, nodes, edges, p.TenantID)
if err != nil {
response.Error(c, http.StatusInternalServerError, "VALIDATION_FAILED", "校验流程失败")
return
@@ -248,24 +238,20 @@ func (h *Handler) Validate(c *gin.Context) {
response.OK(c, gin.H{"valid": len(problems) == 0, "problems": problems})
}
func (h *Handler) loadLatest(sopID, tenantID uint64) (model.SOP, model.SOPVersion, []model.SOPNode, []model.SOPEdge, error) {
func (h *Handler) load(sopID, tenantID uint64) (model.SOP, []model.SOPNode, []model.SOPEdge, error) {
var item model.SOP
if err := h.db.Where("id = ? AND tenant_id = ?", sopID, tenantID).First(&item).Error; err != nil {
return item, model.SOPVersion{}, nil, nil, err
}
var version model.SOPVersion
if err := h.db.Where("sop_id = ? AND tenant_id = ?", sopID, tenantID).Order("version DESC").First(&version).Error; err != nil {
return item, version, nil, nil, err
return item, nil, nil, err
}
nodes := make([]model.SOPNode, 0)
edges := make([]model.SOPEdge, 0)
if err := h.db.Where("sop_version_id = ? AND tenant_id = ?", version.ID, tenantID).Order("position_y, id").Find(&nodes).Error; err != nil {
return item, version, nil, nil, err
if err := h.db.Where("sop_id = ? AND tenant_id = ?", sopID, tenantID).Order("position_y, id").Find(&nodes).Error; err != nil {
return item, nil, nil, err
}
if err := h.db.Where("sop_version_id = ? AND tenant_id = ?", version.ID, tenantID).Order("priority, id").Find(&edges).Error; err != nil {
return item, version, nil, nil, err
if err := h.db.Where("sop_id = ? AND tenant_id = ?", sopID, tenantID).Order("priority, id").Find(&edges).Error; err != nil {
return item, nil, nil, err
}
return item, version, nodes, edges, nil
return item, nodes, edges, nil
}
func (h *Handler) validateForPublish(item model.SOP, startNodeKey string, nodes []model.SOPNode, edges []model.SOPEdge, tenantID uint64) ([]string, error) {
@@ -284,14 +270,14 @@ func (h *Handler) validateForPublish(item model.SOP, startNodeKey string, nodes
return ValidateForPublish(startNodeKey, nodes, edges, ValidationContext{Fields: fields, KnowledgeItems: knowledgeItems, KnowledgeRelations: knowledgeRelations}), nil
}
func toModels(tenantID, versionID uint64, input graphInput) ([]model.SOPNode, []model.SOPEdge) {
func toModels(tenantID, sopID uint64, input graphInput) ([]model.SOPNode, []model.SOPEdge) {
nodes := make([]model.SOPNode, 0, len(input.Nodes))
for _, item := range input.Nodes {
config := item.Config
if len(config) == 0 || !json.Valid(config) {
config = json.RawMessage(`{}`)
}
nodes = append(nodes, model.SOPNode{TenantID: tenantID, SOPVersionID: versionID, NodeKey: item.NodeKey, Type: item.Type, Title: item.Title, Content: item.Content, Config: datatypes.JSON(config), PositionX: item.PositionX, PositionY: item.PositionY})
nodes = append(nodes, model.SOPNode{TenantID: tenantID, SOPID: sopID, NodeKey: item.NodeKey, Type: item.Type, Title: item.Title, Content: item.Content, Config: datatypes.JSON(config), PositionX: item.PositionX, PositionY: item.PositionY})
}
edges := make([]model.SOPEdge, 0, len(input.Edges))
for _, item := range input.Edges {
@@ -299,7 +285,7 @@ func toModels(tenantID, versionID uint64, input graphInput) ([]model.SOPNode, []
if len(condition) == 0 || !json.Valid(condition) {
condition = json.RawMessage(`{}`)
}
edges = append(edges, model.SOPEdge{TenantID: tenantID, SOPVersionID: versionID, SourceNodeKey: item.SourceNodeKey, TargetNodeKey: item.TargetNodeKey, Condition: datatypes.JSON(condition), Priority: item.Priority})
edges = append(edges, model.SOPEdge{TenantID: tenantID, SOPID: sopID, SourceNodeKey: item.SourceNodeKey, TargetNodeKey: item.TargetNodeKey, Condition: datatypes.JSON(condition), Priority: item.Priority})
}
return nodes, edges
}