80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
package run
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
|
||
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
|
||
)
|
||
|
||
func validateKnowledgeSelections(node model.SOPNode, run model.SOPRun, answers map[string]interface{}) error {
|
||
if node.Type != "knowledge" {
|
||
return nil
|
||
}
|
||
var config knowledgeNodeConfig
|
||
if json.Unmarshal(node.Config, &config) != nil || config.KnowledgeCollection == nil {
|
||
return nil
|
||
}
|
||
snapshot, err := parseKnowledgeSnapshot(run.KnowledgeSnapshot)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
itemsByID := map[uint64]model.KnowledgeItem{}
|
||
itemsByName := map[string]model.KnowledgeItem{}
|
||
for _, item := range snapshot.Items {
|
||
if item.Status == "active" {
|
||
itemsByID[item.ID] = item
|
||
itemsByName[item.Name] = item
|
||
}
|
||
}
|
||
relations := map[uint64]map[string]map[uint64]bool{}
|
||
for _, rel := range snapshot.Relations {
|
||
if relations[rel.FromKnowledgeID] == nil {
|
||
relations[rel.FromKnowledgeID] = map[string]map[uint64]bool{}
|
||
}
|
||
if relations[rel.FromKnowledgeID][rel.RelationType] == nil {
|
||
relations[rel.FromKnowledgeID][rel.RelationType] = map[uint64]bool{}
|
||
}
|
||
relations[rel.FromKnowledgeID][rel.RelationType][rel.ToKnowledgeID] = true
|
||
}
|
||
selected := map[string][]model.KnowledgeItem{}
|
||
derived := map[string]interface{}{}
|
||
_ = json.Unmarshal(run.Derived, &derived)
|
||
rootCandidates := map[string]bool{}
|
||
if config.KnowledgeSelector != nil {
|
||
for _, value := range stringSlice(derived[config.KnowledgeSelector.DerivedField]) {
|
||
rootCandidates[value] = true
|
||
}
|
||
}
|
||
for _, step := range config.KnowledgeCollection.Steps {
|
||
values, _ := stringValues(answers[step.FieldKey])
|
||
for _, value := range values {
|
||
item, ok := itemsByName[value]
|
||
if !ok {
|
||
return fmt.Errorf("%s包含不存在的知识选项:%s", step.Name, value)
|
||
}
|
||
if step.Root {
|
||
if len(step.KnowledgeTypes) > 0 && !containsString(step.KnowledgeTypes, item.Type) {
|
||
return fmt.Errorf("%s的知识类型不正确:%s", step.Name, value)
|
||
}
|
||
if step.CandidateScope != "all" && !rootCandidates[item.Name] && !rootCandidates[item.ItemKey] {
|
||
return fmt.Errorf("%s不属于本次订单推断结果:%s", step.Name, value)
|
||
}
|
||
} else {
|
||
valid := false
|
||
for _, parent := range selected[step.FromField] {
|
||
if relations[parent.ID][step.RelationType][item.ID] {
|
||
valid = true
|
||
break
|
||
}
|
||
}
|
||
if !valid {
|
||
return fmt.Errorf("%s与已选择的上级知识不关联:%s", step.Name, value)
|
||
}
|
||
}
|
||
selected[step.FieldKey] = append(selected[step.FieldKey], item)
|
||
}
|
||
}
|
||
return nil
|
||
}
|