override.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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
  12. Value string `json:"value"` // 匹配的值
  13. }
  14. type ParamOperation struct {
  15. Path string `json:"path"`
  16. Mode string `json:"mode"` // delete, set, move, prepend, append
  17. Value interface{} `json:"value"`
  18. KeepOrigin bool `json:"keep_origin"`
  19. From string `json:"from,omitempty"`
  20. To string `json:"to,omitempty"`
  21. Conditions []ConditionOperation `json:"conditions,omitempty"` // 条件列表
  22. Logic string `json:"logic,omitempty"` // AND, OR (默认OR)
  23. }
  24. func ApplyParamOverride(jsonData []byte, paramOverride map[string]interface{}) ([]byte, error) {
  25. if len(paramOverride) == 0 {
  26. return jsonData, nil
  27. }
  28. // 尝试断言为操作格式
  29. if operations, ok := tryParseOperations(paramOverride); ok {
  30. // 使用新方法
  31. result, err := applyOperations(string(jsonData), operations)
  32. if err != nil {
  33. // 新方法失败,回退到旧方法
  34. return applyOperationsLegacy(jsonData, paramOverride)
  35. }
  36. return []byte(result), nil
  37. }
  38. // 直接使用旧方法
  39. return applyOperationsLegacy(jsonData, paramOverride)
  40. }
  41. func tryParseOperations(paramOverride map[string]interface{}) ([]ParamOperation, bool) {
  42. // 检查是否包含 "operations" 字段
  43. if opsValue, exists := paramOverride["operations"]; exists {
  44. if opsSlice, ok := opsValue.([]interface{}); ok {
  45. var operations []ParamOperation
  46. for _, op := range opsSlice {
  47. if opMap, ok := op.(map[string]interface{}); ok {
  48. operation := ParamOperation{}
  49. // 断言必要字段
  50. if path, ok := opMap["path"].(string); ok {
  51. operation.Path = path
  52. }
  53. if mode, ok := opMap["mode"].(string); ok {
  54. operation.Mode = mode
  55. } else {
  56. return nil, false // mode 是必需的
  57. }
  58. // 可选字段
  59. if value, exists := opMap["value"]; exists {
  60. operation.Value = value
  61. }
  62. if keepOrigin, ok := opMap["keep_origin"].(bool); ok {
  63. operation.KeepOrigin = keepOrigin
  64. }
  65. if from, ok := opMap["from"].(string); ok {
  66. operation.From = from
  67. }
  68. if to, ok := opMap["to"].(string); ok {
  69. operation.To = to
  70. }
  71. if logic, ok := opMap["logic"].(string); ok {
  72. operation.Logic = logic
  73. } else {
  74. operation.Logic = "OR" // 默认为OR
  75. }
  76. // 解析条件
  77. if conditions, exists := opMap["conditions"]; exists {
  78. if condSlice, ok := conditions.([]interface{}); ok {
  79. for _, cond := range condSlice {
  80. if condMap, ok := cond.(map[string]interface{}); ok {
  81. condition := ConditionOperation{}
  82. if path, ok := condMap["path"].(string); ok {
  83. condition.Path = path
  84. }
  85. if mode, ok := condMap["mode"].(string); ok {
  86. condition.Mode = mode
  87. }
  88. if value, ok := condMap["value"].(string); ok {
  89. condition.Value = value
  90. }
  91. operation.Conditions = append(operation.Conditions, condition)
  92. }
  93. }
  94. }
  95. }
  96. operations = append(operations, operation)
  97. } else {
  98. return nil, false
  99. }
  100. }
  101. return operations, true
  102. }
  103. }
  104. return nil, false
  105. }
  106. func checkConditions(jsonStr string, conditions []ConditionOperation, logic string) bool {
  107. if len(conditions) == 0 {
  108. return true // 没有条件,直接通过
  109. }
  110. results := make([]bool, len(conditions))
  111. for i, condition := range conditions {
  112. results[i] = checkSingleCondition(jsonStr, condition)
  113. }
  114. if strings.ToUpper(logic) == "AND" {
  115. for _, result := range results {
  116. if !result {
  117. return false
  118. }
  119. }
  120. return true
  121. } else {
  122. for _, result := range results {
  123. if result {
  124. return true
  125. }
  126. }
  127. return false
  128. }
  129. }
  130. func checkSingleCondition(jsonStr string, condition ConditionOperation) bool {
  131. value := gjson.Get(jsonStr, condition.Path)
  132. if !value.Exists() {
  133. return false
  134. }
  135. valueStr := value.String()
  136. targetStr := condition.Value
  137. switch strings.ToLower(condition.Mode) {
  138. case "full":
  139. return valueStr == targetStr
  140. case "prefix":
  141. return strings.HasPrefix(valueStr, targetStr)
  142. case "suffix":
  143. return strings.HasSuffix(valueStr, targetStr)
  144. case "contains":
  145. return strings.Contains(valueStr, targetStr)
  146. default:
  147. return valueStr == targetStr // 默认精准匹配
  148. }
  149. }
  150. // applyOperationsLegacy 原参数覆盖方法
  151. func applyOperationsLegacy(jsonData []byte, paramOverride map[string]interface{}) ([]byte, error) {
  152. reqMap := make(map[string]interface{})
  153. err := json.Unmarshal(jsonData, &reqMap)
  154. if err != nil {
  155. return nil, err
  156. }
  157. for key, value := range paramOverride {
  158. reqMap[key] = value
  159. }
  160. return json.Marshal(reqMap)
  161. }
  162. func applyOperations(jsonStr string, operations []ParamOperation) (string, error) {
  163. result := jsonStr
  164. for _, op := range operations {
  165. // 检查条件是否满足
  166. if !checkConditions(result, op.Conditions, op.Logic) {
  167. continue // 条件不满足,跳过当前操作
  168. }
  169. var err error
  170. switch op.Mode {
  171. case "delete":
  172. result, err = sjson.Delete(result, op.Path)
  173. case "set":
  174. if op.KeepOrigin && gjson.Get(result, op.Path).Exists() {
  175. continue
  176. }
  177. result, err = sjson.Set(result, op.Path, op.Value)
  178. case "move":
  179. result, err = moveValue(result, op.From, op.To)
  180. case "prepend":
  181. result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, true)
  182. case "append":
  183. result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, false)
  184. default:
  185. return "", fmt.Errorf("unknown operation: %s", op.Mode)
  186. }
  187. if err != nil {
  188. return "", fmt.Errorf("operation %s failed: %v", op.Mode, err)
  189. }
  190. }
  191. return result, nil
  192. }
  193. func moveValue(jsonStr, fromPath, toPath string) (string, error) {
  194. sourceValue := gjson.Get(jsonStr, fromPath)
  195. if !sourceValue.Exists() {
  196. return jsonStr, fmt.Errorf("source path does not exist: %s", fromPath)
  197. }
  198. result, err := sjson.Set(jsonStr, toPath, sourceValue.Value())
  199. if err != nil {
  200. return "", err
  201. }
  202. return sjson.Delete(result, fromPath)
  203. }
  204. func modifyValue(jsonStr, path string, value interface{}, keepOrigin, isPrepend bool) (string, error) {
  205. current := gjson.Get(jsonStr, path)
  206. switch {
  207. case current.IsArray():
  208. return modifyArray(jsonStr, path, value, isPrepend)
  209. case current.Type == gjson.String:
  210. return modifyString(jsonStr, path, value, isPrepend)
  211. case current.Type == gjson.JSON:
  212. return mergeObjects(jsonStr, path, value, keepOrigin)
  213. }
  214. return jsonStr, fmt.Errorf("operation not supported for type: %v", current.Type)
  215. }
  216. func modifyArray(jsonStr, path string, value interface{}, isPrepend bool) (string, error) {
  217. current := gjson.Get(jsonStr, path)
  218. var newArray []interface{}
  219. // 添加新值
  220. addValue := func() {
  221. if arr, ok := value.([]interface{}); ok {
  222. newArray = append(newArray, arr...)
  223. } else {
  224. newArray = append(newArray, value)
  225. }
  226. }
  227. // 添加原值
  228. addOriginal := func() {
  229. current.ForEach(func(_, val gjson.Result) bool {
  230. newArray = append(newArray, val.Value())
  231. return true
  232. })
  233. }
  234. if isPrepend {
  235. addValue()
  236. addOriginal()
  237. } else {
  238. addOriginal()
  239. addValue()
  240. }
  241. return sjson.Set(jsonStr, path, newArray)
  242. }
  243. func modifyString(jsonStr, path string, value interface{}, isPrepend bool) (string, error) {
  244. current := gjson.Get(jsonStr, path)
  245. valueStr := fmt.Sprintf("%v", value)
  246. var newStr string
  247. if isPrepend {
  248. newStr = valueStr + current.String()
  249. } else {
  250. newStr = current.String() + valueStr
  251. }
  252. return sjson.Set(jsonStr, path, newStr)
  253. }
  254. func mergeObjects(jsonStr, path string, value interface{}, keepOrigin bool) (string, error) {
  255. current := gjson.Get(jsonStr, path)
  256. var currentMap, newMap map[string]interface{}
  257. // 解析当前值
  258. if err := json.Unmarshal([]byte(current.Raw), &currentMap); err != nil {
  259. return "", err
  260. }
  261. // 解析新值
  262. switch v := value.(type) {
  263. case map[string]interface{}:
  264. newMap = v
  265. default:
  266. jsonBytes, _ := json.Marshal(v)
  267. if err := json.Unmarshal(jsonBytes, &newMap); err != nil {
  268. return "", err
  269. }
  270. }
  271. // 合并
  272. result := make(map[string]interface{})
  273. for k, v := range currentMap {
  274. result[k] = v
  275. }
  276. for k, v := range newMap {
  277. if !keepOrigin || result[k] == nil {
  278. result[k] = v
  279. }
  280. }
  281. return sjson.Set(jsonStr, path, result)
  282. }