161 lines
4.6 KiB
Go
161 lines
4.6 KiB
Go
package run
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type NodePresentation struct {
|
|
Summary []PresentationField `json:"summary"`
|
|
Items []PresentationItem `json:"items"`
|
|
Opening *PresentationCopy `json:"opening,omitempty"`
|
|
}
|
|
|
|
type PresentationField struct {
|
|
Key string `json:"key"`
|
|
Label string `json:"label"`
|
|
Kind string `json:"kind"`
|
|
Value interface{} `json:"value"`
|
|
}
|
|
|
|
type PresentationItem struct {
|
|
Fields []PresentationField `json:"fields"`
|
|
}
|
|
|
|
type PresentationCopy struct {
|
|
Title string `json:"title"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
type startNodeConfig struct {
|
|
Presentation *startPresentationConfig `json:"presentation"`
|
|
}
|
|
|
|
type startPresentationConfig struct {
|
|
SummaryFieldKeys []string `json:"summary_field_keys"`
|
|
ItemFieldKeys []string `json:"item_field_keys"`
|
|
ImageFieldKeys []string `json:"image_field_keys"`
|
|
OpeningTitle string `json:"opening_title"`
|
|
OpeningTemplate string `json:"opening_template"`
|
|
}
|
|
|
|
func loadStartPresentation(db *gorm.DB, node model.SOPNode, tenantID uint64, context map[string]interface{}) (*NodePresentation, error) {
|
|
var config startNodeConfig
|
|
if err := json.Unmarshal(node.Config, &config); err != nil {
|
|
return nil, err
|
|
}
|
|
if config.Presentation == nil {
|
|
return nil, nil
|
|
}
|
|
keys := append([]string{}, config.Presentation.SummaryFieldKeys...)
|
|
keys = append(keys, config.Presentation.ItemFieldKeys...)
|
|
fields := make([]model.ScenarioField, 0)
|
|
if len(keys) > 0 {
|
|
if err := db.Table("scenario_fields sf").Select("sf.*").
|
|
Joins("JOIN sops s ON s.scenario_id = sf.scenario_id").
|
|
Joins("JOIN sop_versions sv ON sv.sop_id = s.id").
|
|
Where("sv.id = ? AND sf.tenant_id = ? AND sf.field_key IN ?", node.SOPVersionID, tenantID, keys).
|
|
Find(&fields).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
byKey := make(map[string]model.ScenarioField, len(fields))
|
|
for _, field := range fields {
|
|
byKey[field.FieldKey] = field
|
|
}
|
|
return buildStartPresentation(*config.Presentation, byKey, context), nil
|
|
}
|
|
|
|
func buildStartPresentation(config startPresentationConfig, fields map[string]model.ScenarioField, context map[string]interface{}) *NodePresentation {
|
|
view := &NodePresentation{Summary: []PresentationField{}, Items: []PresentationItem{}}
|
|
imageKeys := make(map[string]bool, len(config.ImageFieldKeys))
|
|
for _, key := range config.ImageFieldKeys {
|
|
imageKeys[key] = true
|
|
}
|
|
for _, key := range config.SummaryFieldKeys {
|
|
value, ok := lookupContextValue(context, "input."+key)
|
|
if !ok || presentationValueEmpty(value) {
|
|
continue
|
|
}
|
|
view.Summary = append(view.Summary, presentationField(key, value, fields, imageKeys))
|
|
}
|
|
itemValues := make(map[string][]interface{}, len(config.ItemFieldKeys))
|
|
itemCount := 0
|
|
for _, key := range config.ItemFieldKeys {
|
|
value, _ := lookupContextValue(context, "input."+key)
|
|
values := presentationValues(value)
|
|
itemValues[key] = values
|
|
if len(values) > itemCount {
|
|
itemCount = len(values)
|
|
}
|
|
}
|
|
for index := 0; index < itemCount; index++ {
|
|
item := PresentationItem{Fields: []PresentationField{}}
|
|
for _, key := range config.ItemFieldKeys {
|
|
values := itemValues[key]
|
|
if index >= len(values) || presentationValueEmpty(values[index]) {
|
|
continue
|
|
}
|
|
item.Fields = append(item.Fields, presentationField(key, values[index], fields, imageKeys))
|
|
}
|
|
if len(item.Fields) > 0 {
|
|
view.Items = append(view.Items, item)
|
|
}
|
|
}
|
|
if config.OpeningTemplate != "" {
|
|
title := config.OpeningTitle
|
|
if title == "" {
|
|
title = "开场话术"
|
|
}
|
|
view.Opening = &PresentationCopy{Title: title, Content: fmt.Sprint(renderKnowledgeValue(config.OpeningTemplate, context))}
|
|
}
|
|
return view
|
|
}
|
|
|
|
func presentationField(key string, value interface{}, fields map[string]model.ScenarioField, imageKeys map[string]bool) PresentationField {
|
|
label := key
|
|
if field, ok := fields[key]; ok && field.FieldName != "" {
|
|
label = field.FieldName
|
|
}
|
|
kind := "text"
|
|
if imageKeys[key] {
|
|
kind = "image"
|
|
}
|
|
return PresentationField{Key: key, Label: label, Kind: kind, Value: value}
|
|
}
|
|
|
|
func presentationValues(value interface{}) []interface{} {
|
|
switch values := value.(type) {
|
|
case []interface{}:
|
|
return values
|
|
case []string:
|
|
result := make([]interface{}, 0, len(values))
|
|
for _, item := range values {
|
|
result = append(result, item)
|
|
}
|
|
return result
|
|
case nil:
|
|
return nil
|
|
default:
|
|
return []interface{}{value}
|
|
}
|
|
}
|
|
|
|
func presentationValueEmpty(value interface{}) bool {
|
|
switch typed := value.(type) {
|
|
case nil:
|
|
return true
|
|
case string:
|
|
return typed == ""
|
|
case []interface{}:
|
|
return len(typed) == 0
|
|
case []string:
|
|
return len(typed) == 0
|
|
default:
|
|
return false
|
|
}
|
|
}
|