feats:use the types of gjson,the error expection,the invert of the condition

This commit is contained in:
Nekohy
2025-08-16 16:31:17 +08:00
parent b591b4ebdf
commit cbce487362

View File

@@ -9,9 +9,11 @@ import (
) )
type ConditionOperation struct { type ConditionOperation struct {
Path string `json:"path"` // JSON路径 Path string `json:"path"` // JSON路径
Mode string `json:"mode"` // full, prefix, suffix, contains Mode string `json:"mode"` // full, prefix, suffix, contains, gt, gte, lt, lte
Value string `json:"value"` // 匹配的值 Value interface{} `json:"value"` // 匹配的值
Invert bool `json:"invert"` // 反选功能true表示取反结果
} }
type ParamOperation struct { type ParamOperation struct {
@@ -34,11 +36,7 @@ func ApplyParamOverride(jsonData []byte, paramOverride map[string]interface{}) (
if operations, ok := tryParseOperations(paramOverride); ok { if operations, ok := tryParseOperations(paramOverride); ok {
// 使用新方法 // 使用新方法
result, err := applyOperations(string(jsonData), operations) result, err := applyOperations(string(jsonData), operations)
if err != nil { return []byte(result), err
// 新方法失败,回退到旧方法
return applyOperationsLegacy(jsonData, paramOverride)
}
return []byte(result), nil
} }
// 直接使用旧方法 // 直接使用旧方法
@@ -95,9 +93,12 @@ func tryParseOperations(paramOverride map[string]interface{}) ([]ParamOperation,
if mode, ok := condMap["mode"].(string); ok { if mode, ok := condMap["mode"].(string); ok {
condition.Mode = mode condition.Mode = mode
} }
if value, ok := condMap["value"].(string); ok { if value, ok := condMap["value"]; ok {
condition.Value = value condition.Value = value
} }
if invert, ok := condMap["invert"].(bool); ok {
condition.Invert = invert
}
operation.Conditions = append(operation.Conditions, condition) operation.Conditions = append(operation.Conditions, condition)
} }
} }
@@ -116,52 +117,122 @@ func tryParseOperations(paramOverride map[string]interface{}) ([]ParamOperation,
return nil, false return nil, false
} }
func checkConditions(jsonStr string, conditions []ConditionOperation, logic string) bool { func checkConditions(jsonStr string, conditions []ConditionOperation, logic string) (bool, error) {
if len(conditions) == 0 { if len(conditions) == 0 {
return true // 没有条件,直接通过 return true, nil // 没有条件,直接通过
} }
results := make([]bool, len(conditions)) results := make([]bool, len(conditions))
for i, condition := range conditions { for i, condition := range conditions {
results[i] = checkSingleCondition(jsonStr, condition) result, err := checkSingleCondition(jsonStr, condition)
if err != nil {
return false, err
}
results[i] = result
} }
if strings.ToUpper(logic) == "AND" { if strings.ToUpper(logic) == "AND" {
for _, result := range results { for _, result := range results {
if !result { if !result {
return false return false, nil
} }
} }
return true return true, nil
} else { } else {
for _, result := range results { for _, result := range results {
if result { if result {
return true return true, nil
} }
} }
return false return false, nil
} }
} }
func checkSingleCondition(jsonStr string, condition ConditionOperation) bool { func checkSingleCondition(jsonStr string, condition ConditionOperation) (bool, error) {
value := gjson.Get(jsonStr, condition.Path) value := gjson.Get(jsonStr, condition.Path)
if !value.Exists() { if !value.Exists() {
return false return false, nil
} }
valueStr := value.String() // 利用gjson的类型解析
targetStr := condition.Value targetBytes, err := json.Marshal(condition.Value)
if err != nil {
return false, fmt.Errorf("failed to marshal condition value: %v", err)
}
targetValue := gjson.ParseBytes(targetBytes)
switch strings.ToLower(condition.Mode) { result, err := compareGjsonValues(value, targetValue, strings.ToLower(condition.Mode))
if err != nil {
return false, fmt.Errorf("comparison failed for path %s: %v", condition.Path, err)
}
if condition.Invert {
result = !result
}
return result, nil
}
// compareGjsonValues 直接比较两个gjson.Result支持所有比较模式
func compareGjsonValues(jsonValue, targetValue gjson.Result, mode string) (bool, error) {
switch mode {
case "full": case "full":
return valueStr == targetStr return compareEqual(jsonValue, targetValue)
case "prefix": case "prefix":
return strings.HasPrefix(valueStr, targetStr) return strings.HasPrefix(jsonValue.String(), targetValue.String()), nil
case "suffix": case "suffix":
return strings.HasSuffix(valueStr, targetStr) return strings.HasSuffix(jsonValue.String(), targetValue.String()), nil
case "contains": case "contains":
return strings.Contains(valueStr, targetStr) return strings.Contains(jsonValue.String(), targetValue.String()), nil
case "gt":
return compareNumeric(jsonValue, targetValue, "gt")
case "gte":
return compareNumeric(jsonValue, targetValue, "gte")
case "lt":
return compareNumeric(jsonValue, targetValue, "lt")
case "lte":
return compareNumeric(jsonValue, targetValue, "lte")
default: default:
return valueStr == targetStr // 默认精准匹配 return false, fmt.Errorf("unsupported comparison mode: %s", mode)
}
}
func compareEqual(jsonValue, targetValue gjson.Result) (bool, error) {
// 如果类型不同,报错
if jsonValue.Type != targetValue.Type {
return false, fmt.Errorf("compare for different types, got %v and %v", jsonValue.Type, targetValue.Type)
}
switch jsonValue.Type {
case gjson.True, gjson.False:
return jsonValue.Bool() == targetValue.Bool(), nil
case gjson.Number:
return jsonValue.Num == targetValue.Num, nil
case gjson.String:
return jsonValue.String() == targetValue.String(), nil
default:
return jsonValue.String() == targetValue.String(), nil
}
}
func compareNumeric(jsonValue, targetValue gjson.Result, operator string) (bool, error) {
// 只有数字类型才支持数值比较
if jsonValue.Type != gjson.Number || targetValue.Type != gjson.Number {
return false, fmt.Errorf("numeric comparison requires both values to be numbers, got %v and %v", jsonValue.Type, targetValue.Type)
}
jsonNum := jsonValue.Num
targetNum := targetValue.Num
switch operator {
case "gt":
return jsonNum > targetNum, nil
case "gte":
return jsonNum >= targetNum, nil
case "lt":
return jsonNum < targetNum, nil
case "lte":
return jsonNum <= targetNum, nil
default:
return false, fmt.Errorf("unsupported numeric operator: %s", operator)
} }
} }
@@ -184,11 +255,14 @@ func applyOperations(jsonStr string, operations []ParamOperation) (string, error
result := jsonStr result := jsonStr
for _, op := range operations { for _, op := range operations {
// 检查条件是否满足 // 检查条件是否满足
if !checkConditions(result, op.Conditions, op.Logic) { ok, err := checkConditions(result, op.Conditions, op.Logic)
if err != nil {
return "", err
}
if !ok {
continue // 条件不满足,跳过当前操作 continue // 条件不满足,跳过当前操作
} }
var err error
switch op.Mode { switch op.Mode {
case "delete": case "delete":
result, err = sjson.Delete(result, op.Path) result, err = sjson.Delete(result, op.Path)