override.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package common
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/tidwall/gjson"
  6. "github.com/tidwall/sjson"
  7. "strings"
  8. )
  9. type ConditionOperation struct {
  10. Path string `json:"path"` // JSON路径
  11. Mode string `json:"mode"` // full, prefix, suffix, contains, gt, gte, lt, lte
  12. Value interface{} `json:"value"` // 匹配的值
  13. Invert bool `json:"invert"` // 反选功能,true表示取反结果
  14. PassMissingKey bool `json:"pass_missing_key"` // 未获取到json key时的行为
  15. }
  16. type ParamOperation struct {
  17. Path string `json:"path"`
  18. Mode string `json:"mode"` // delete, set, move, prepend, append
  19. Value interface{} `json:"value"`
  20. KeepOrigin bool `json:"keep_origin"`
  21. From string `json:"from,omitempty"`
  22. To string `json:"to,omitempty"`
  23. Conditions []ConditionOperation `json:"conditions,omitempty"` // 条件列表
  24. Logic string `json:"logic,omitempty"` // AND, OR (默认OR)
  25. }
  26. func ApplyParamOverride(jsonData []byte, paramOverride map[string]interface{}) ([]byte, error) {
  27. if len(paramOverride) == 0 {
  28. return jsonData, nil
  29. }
  30. // 尝试断言为操作格式
  31. if operations, ok := tryParseOperations(paramOverride); ok {
  32. // 使用新方法
  33. result, err := applyOperations(string(jsonData), operations)
  34. return []byte(result), err
  35. }
  36. // 直接使用旧方法
  37. return applyOperationsLegacy(jsonData, paramOverride)
  38. }
  39. func tryParseOperations(paramOverride map[string]interface{}) ([]ParamOperation, bool) {
  40. // 检查是否包含 "operations" 字段
  41. if opsValue, exists := paramOverride["operations"]; exists {
  42. if opsSlice, ok := opsValue.([]interface{}); ok {
  43. var operations []ParamOperation
  44. for _, op := range opsSlice {
  45. if opMap, ok := op.(map[string]interface{}); ok {
  46. operation := ParamOperation{}
  47. // 断言必要字段
  48. if path, ok := opMap["path"].(string); ok {
  49. operation.Path = path
  50. }
  51. if mode, ok := opMap["mode"].(string); ok {
  52. operation.Mode = mode
  53. } else {
  54. return nil, false // mode 是必需的
  55. }
  56. // 可选字段
  57. if value, exists := opMap["value"]; exists {
  58. operation.Value = value
  59. }
  60. if keepOrigin, ok := opMap["keep_origin"].(bool); ok {
  61. operation.KeepOrigin = keepOrigin
  62. }
  63. if from, ok := opMap["from"].(string); ok {
  64. operation.From = from
  65. }
  66. if to, ok := opMap["to"].(string); ok {
  67. operation.To = to
  68. }
  69. if logic, ok := opMap["logic"].(string); ok {
  70. operation.Logic = logic
  71. } else {
  72. operation.Logic = "OR" // 默认为OR
  73. }
  74. // 解析条件
  75. if conditions, exists := opMap["conditions"]; exists {
  76. if condSlice, ok := conditions.([]interface{}); ok {
  77. for _, cond := range condSlice {
  78. if condMap, ok := cond.(map[string]interface{}); ok {
  79. condition := ConditionOperation{}
  80. if path, ok := condMap["path"].(string); ok {
  81. condition.Path = path
  82. }
  83. if mode, ok := condMap["mode"].(string); ok {
  84. condition.Mode = mode
  85. }
  86. if value, ok := condMap["value"]; ok {
  87. condition.Value = value
  88. }
  89. if invert, ok := condMap["invert"].(bool); ok {
  90. condition.Invert = invert
  91. }
  92. if passMissingKey, ok := condMap["pass_missing_key"].(bool); ok {
  93. condition.PassMissingKey = passMissingKey
  94. }
  95. operation.Conditions = append(operation.Conditions, condition)
  96. }
  97. }
  98. }
  99. }
  100. operations = append(operations, operation)
  101. } else {
  102. return nil, false
  103. }
  104. }
  105. return operations, true
  106. }
  107. }
  108. return nil, false
  109. }
  110. func checkConditions(jsonStr string, conditions []ConditionOperation, logic string) (bool, error) {
  111. if len(conditions) == 0 {
  112. return true, nil // 没有条件,直接通过
  113. }
  114. results := make([]bool, len(conditions))
  115. for i, condition := range conditions {
  116. result, err := checkSingleCondition(jsonStr, condition)
  117. if err != nil {
  118. return false, err
  119. }
  120. results[i] = result
  121. }
  122. if strings.ToUpper(logic) == "AND" {
  123. for _, result := range results {
  124. if !result {
  125. return false, nil
  126. }
  127. }
  128. return true, nil
  129. } else {
  130. for _, result := range results {
  131. if result {
  132. return true, nil
  133. }
  134. }
  135. return false, nil
  136. }
  137. }
  138. func checkSingleCondition(jsonStr string, condition ConditionOperation) (bool, error) {
  139. value := gjson.Get(jsonStr, condition.Path)
  140. if !value.Exists() {
  141. if condition.PassMissingKey {
  142. return true, nil
  143. }
  144. return false, nil
  145. }
  146. // 利用gjson的类型解析
  147. targetBytes, err := json.Marshal(condition.Value)
  148. if err != nil {
  149. return false, fmt.Errorf("failed to marshal condition value: %v", err)
  150. }
  151. targetValue := gjson.ParseBytes(targetBytes)
  152. result, err := compareGjsonValues(value, targetValue, strings.ToLower(condition.Mode))
  153. if err != nil {
  154. return false, fmt.Errorf("comparison failed for path %s: %v", condition.Path, err)
  155. }
  156. if condition.Invert {
  157. result = !result
  158. }
  159. return result, nil
  160. }
  161. // compareGjsonValues 直接比较两个gjson.Result,支持所有比较模式
  162. func compareGjsonValues(jsonValue, targetValue gjson.Result, mode string) (bool, error) {
  163. switch mode {
  164. case "full":
  165. return compareEqual(jsonValue, targetValue)
  166. case "prefix":
  167. return strings.HasPrefix(jsonValue.String(), targetValue.String()), nil
  168. case "suffix":
  169. return strings.HasSuffix(jsonValue.String(), targetValue.String()), nil
  170. case "contains":
  171. return strings.Contains(jsonValue.String(), targetValue.String()), nil
  172. case "gt":
  173. return compareNumeric(jsonValue, targetValue, "gt")
  174. case "gte":
  175. return compareNumeric(jsonValue, targetValue, "gte")
  176. case "lt":
  177. return compareNumeric(jsonValue, targetValue, "lt")
  178. case "lte":
  179. return compareNumeric(jsonValue, targetValue, "lte")
  180. default:
  181. return false, fmt.Errorf("unsupported comparison mode: %s", mode)
  182. }
  183. }
  184. func compareEqual(jsonValue, targetValue gjson.Result) (bool, error) {
  185. // 对布尔值特殊处理
  186. if (jsonValue.Type == gjson.True || jsonValue.Type == gjson.False) &&
  187. (targetValue.Type == gjson.True || targetValue.Type == gjson.False) {
  188. return jsonValue.Bool() == targetValue.Bool(), nil
  189. }
  190. // 如果类型不同,报错
  191. if jsonValue.Type != targetValue.Type {
  192. return false, fmt.Errorf("compare for different types, got %v and %v", jsonValue.Type, targetValue.Type)
  193. }
  194. switch jsonValue.Type {
  195. case gjson.True, gjson.False:
  196. return jsonValue.Bool() == targetValue.Bool(), nil
  197. case gjson.Number:
  198. return jsonValue.Num == targetValue.Num, nil
  199. case gjson.String:
  200. return jsonValue.String() == targetValue.String(), nil
  201. default:
  202. return jsonValue.String() == targetValue.String(), nil
  203. }
  204. }
  205. func compareNumeric(jsonValue, targetValue gjson.Result, operator string) (bool, error) {
  206. // 只有数字类型才支持数值比较
  207. if jsonValue.Type != gjson.Number || targetValue.Type != gjson.Number {
  208. return false, fmt.Errorf("numeric comparison requires both values to be numbers, got %v and %v", jsonValue.Type, targetValue.Type)
  209. }
  210. jsonNum := jsonValue.Num
  211. targetNum := targetValue.Num
  212. switch operator {
  213. case "gt":
  214. return jsonNum > targetNum, nil
  215. case "gte":
  216. return jsonNum >= targetNum, nil
  217. case "lt":
  218. return jsonNum < targetNum, nil
  219. case "lte":
  220. return jsonNum <= targetNum, nil
  221. default:
  222. return false, fmt.Errorf("unsupported numeric operator: %s", operator)
  223. }
  224. }
  225. // applyOperationsLegacy 原参数覆盖方法
  226. func applyOperationsLegacy(jsonData []byte, paramOverride map[string]interface{}) ([]byte, error) {
  227. reqMap := make(map[string]interface{})
  228. err := json.Unmarshal(jsonData, &reqMap)
  229. if err != nil {
  230. return nil, err
  231. }
  232. for key, value := range paramOverride {
  233. reqMap[key] = value
  234. }
  235. return json.Marshal(reqMap)
  236. }
  237. func applyOperations(jsonStr string, operations []ParamOperation) (string, error) {
  238. result := jsonStr
  239. for _, op := range operations {
  240. // 检查条件是否满足
  241. ok, err := checkConditions(result, op.Conditions, op.Logic)
  242. if err != nil {
  243. return "", err
  244. }
  245. if !ok {
  246. continue // 条件不满足,跳过当前操作
  247. }
  248. switch op.Mode {
  249. case "delete":
  250. result, err = sjson.Delete(result, op.Path)
  251. case "set":
  252. if op.KeepOrigin && gjson.Get(result, op.Path).Exists() {
  253. continue
  254. }
  255. result, err = sjson.Set(result, op.Path, op.Value)
  256. case "move":
  257. result, err = moveValue(result, op.From, op.To)
  258. case "prepend":
  259. result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, true)
  260. case "append":
  261. result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, false)
  262. default:
  263. return "", fmt.Errorf("unknown operation: %s", op.Mode)
  264. }
  265. if err != nil {
  266. return "", fmt.Errorf("operation %s failed: %v", op.Mode, err)
  267. }
  268. }
  269. return result, nil
  270. }
  271. func moveValue(jsonStr, fromPath, toPath string) (string, error) {
  272. sourceValue := gjson.Get(jsonStr, fromPath)
  273. if !sourceValue.Exists() {
  274. return jsonStr, fmt.Errorf("source path does not exist: %s", fromPath)
  275. }
  276. result, err := sjson.Set(jsonStr, toPath, sourceValue.Value())
  277. if err != nil {
  278. return "", err
  279. }
  280. return sjson.Delete(result, fromPath)
  281. }
  282. func modifyValue(jsonStr, path string, value interface{}, keepOrigin, isPrepend bool) (string, error) {
  283. current := gjson.Get(jsonStr, path)
  284. switch {
  285. case current.IsArray():
  286. return modifyArray(jsonStr, path, value, isPrepend)
  287. case current.Type == gjson.String:
  288. return modifyString(jsonStr, path, value, isPrepend)
  289. case current.Type == gjson.JSON:
  290. return mergeObjects(jsonStr, path, value, keepOrigin)
  291. }
  292. return jsonStr, fmt.Errorf("operation not supported for type: %v", current.Type)
  293. }
  294. func modifyArray(jsonStr, path string, value interface{}, isPrepend bool) (string, error) {
  295. current := gjson.Get(jsonStr, path)
  296. var newArray []interface{}
  297. // 添加新值
  298. addValue := func() {
  299. if arr, ok := value.([]interface{}); ok {
  300. newArray = append(newArray, arr...)
  301. } else {
  302. newArray = append(newArray, value)
  303. }
  304. }
  305. // 添加原值
  306. addOriginal := func() {
  307. current.ForEach(func(_, val gjson.Result) bool {
  308. newArray = append(newArray, val.Value())
  309. return true
  310. })
  311. }
  312. if isPrepend {
  313. addValue()
  314. addOriginal()
  315. } else {
  316. addOriginal()
  317. addValue()
  318. }
  319. return sjson.Set(jsonStr, path, newArray)
  320. }
  321. func modifyString(jsonStr, path string, value interface{}, isPrepend bool) (string, error) {
  322. current := gjson.Get(jsonStr, path)
  323. valueStr := fmt.Sprintf("%v", value)
  324. var newStr string
  325. if isPrepend {
  326. newStr = valueStr + current.String()
  327. } else {
  328. newStr = current.String() + valueStr
  329. }
  330. return sjson.Set(jsonStr, path, newStr)
  331. }
  332. func mergeObjects(jsonStr, path string, value interface{}, keepOrigin bool) (string, error) {
  333. current := gjson.Get(jsonStr, path)
  334. var currentMap, newMap map[string]interface{}
  335. // 解析当前值
  336. if err := json.Unmarshal([]byte(current.Raw), &currentMap); err != nil {
  337. return "", err
  338. }
  339. // 解析新值
  340. switch v := value.(type) {
  341. case map[string]interface{}:
  342. newMap = v
  343. default:
  344. jsonBytes, _ := json.Marshal(v)
  345. if err := json.Unmarshal(jsonBytes, &newMap); err != nil {
  346. return "", err
  347. }
  348. }
  349. // 合并
  350. result := make(map[string]interface{})
  351. for k, v := range currentMap {
  352. result[k] = v
  353. }
  354. for k, v := range newMap {
  355. if !keepOrigin || result[k] == nil {
  356. result[k] = v
  357. }
  358. }
  359. return sjson.Set(jsonStr, path, result)
  360. }