feat: simplify SOP to immediate-effect configuration

This commit is contained in:
Eric 1549169735@qq.com
2026-08-18 16:27:02 +08:00
parent c5ab886b70
commit 8de48fb05e
150 changed files with 6764 additions and 1626 deletions

89
internal/run/rules.go Normal file
View File

@@ -0,0 +1,89 @@
package run
import (
"encoding/json"
"fmt"
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
"gorm.io/gorm"
)
func deriveForScenario(db *gorm.DB, tenantID, scenarioID uint64, input map[string]interface{}) (map[string]interface{}, []string, error) {
rules := make([]model.ScenarioRule, 0)
if err := db.Where("tenant_id = ? AND scenario_id = ? AND status = ?", tenantID, scenarioID, "active").Order("priority, id").Find(&rules).Error; err != nil {
return nil, nil, err
}
return applyScenarioRules(rules, input)
}
type ruleAction struct {
Operation string `json:"operation"`
Field string `json:"field"`
Value interface{} `json:"value"`
ValueFrom string `json:"value_from"`
}
func applyScenarioRules(rules []model.ScenarioRule, input map[string]interface{}) (map[string]interface{}, []string, error) {
derived := map[string]interface{}{}
matched := make([]string, 0)
context := runtimeContext(input, derived, nil)
for _, rule := range rules {
ok, err := matchCondition(json.RawMessage(rule.Condition), context)
if err != nil {
return nil, nil, fmt.Errorf("规则 %s 条件不正确: %w", rule.RuleKey, err)
}
if !ok {
continue
}
var actions []ruleAction
if err := json.Unmarshal(rule.Actions, &actions); err != nil {
return nil, nil, fmt.Errorf("规则 %s 动作不正确", rule.RuleKey)
}
for _, action := range actions {
resolvedValues := []interface{}{action.Value}
valueFromList := false
if action.ValueFrom != "" {
resolved, exists := lookupContextValue(context, action.ValueFrom)
if !exists {
continue
}
if list, ok := resolved.([]interface{}); ok {
resolvedValues = list
valueFromList = true
} else {
resolvedValues = []interface{}{resolved}
}
}
switch action.Operation {
case "set":
if valueFromList {
derived[action.Field] = resolvedValues
} else if len(resolvedValues) == 1 {
derived[action.Field] = resolvedValues[0]
} else {
derived[action.Field] = resolvedValues
}
case "append":
targetValues, _ := derived[action.Field].([]interface{})
for _, value := range resolvedValues {
duplicate := false
for _, existing := range targetValues {
if fmt.Sprint(existing) == fmt.Sprint(value) {
duplicate = true
break
}
}
if !duplicate {
targetValues = append(targetValues, value)
}
}
derived[action.Field] = targetValues
default:
return nil, nil, fmt.Errorf("规则 %s 使用了不支持的动作", rule.RuleKey)
}
}
matched = append(matched, rule.RuleKey)
context = runtimeContext(input, derived, nil)
}
return derived, matched, nil
}