metric_process_config.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package service
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "text/template"
  11. "time"
  12. "github.com/tidwall/gjson"
  13. "newaterobot-process/entity"
  14. "newaterobot-process/model"
  15. "newaterobot-process/utils"
  16. )
  17. // MetricProcessConfigService 指标处理配置服务
  18. type MetricProcessConfigService struct {
  19. configModel *model.MetricProcessConfigModel
  20. httpClient *http.Client
  21. }
  22. // NewMetricProcessConfigService 创建指标处理配置服务实例
  23. func NewMetricProcessConfigService() *MetricProcessConfigService {
  24. return &MetricProcessConfigService{
  25. configModel: &model.MetricProcessConfigModel{},
  26. httpClient: &http.Client{
  27. Timeout: 30 * time.Second,
  28. },
  29. }
  30. }
  31. // ProcessMetric 处理指标
  32. func (s *MetricProcessConfigService) ProcessMetric(inputData entity.MetricProcessRequest) (entity.MetricProcessResponse, error) {
  33. ret := entity.MetricProcessResponse{}
  34. // 根据指标类型获取配置
  35. configs, err := s.configModel.GetByMetricType(inputData.MetricType, inputData.Intent)
  36. if err != nil {
  37. return ret, err
  38. }
  39. configsMap := make(map[string]entity.MetricProcessConfig)
  40. for _, config := range configs {
  41. key := fmt.Sprintf("%d_%d", config.Intent, config.MetricType)
  42. configsMap[key] = config
  43. }
  44. key := fmt.Sprintf("%d_%d", inputData.Intent, inputData.MetricType)
  45. var config entity.MetricProcessConfig
  46. var ok bool
  47. // 未配置该处理分支直接返回,在dify中处理
  48. if config, ok = configsMap[key]; !ok {
  49. ret.Flag = entity.NoExecute
  50. return ret, nil
  51. }
  52. if config.MetricType == 24 {
  53. inputData.STime = time.Now().Format("2006-01-02") + " 00:00:00"
  54. inputData.ETime = time.Now().Format("2006-01-02") + " 23:59:59"
  55. } else if config.MetricType == 29 {
  56. inputData.STime = time.Now().Format("2006-01")
  57. } else if config.MetricType == 30 {
  58. inputData.STime = time.Now().Format("2006-01-02") + " 00:00:00"
  59. } else if config.MetricType == 33 {
  60. inputData.STime = time.Now().Format("2006-01-02")
  61. inputData.ETime = time.Now().AddDate(0, 0, 180).Format("2006-01-02")
  62. } else if config.MetricType == 59 {
  63. inputData.DateTime = strings.Split(inputData.DateTime, " ")[0]
  64. }
  65. // 直接回复分支
  66. templateVarMap := s.objToMap(inputData)
  67. if config.Type == 1 {
  68. contextTemplate := config.ContextTemplate
  69. if inputData.IsEnglish == 1 {
  70. contextTemplate = config.EngContextTemplate
  71. }
  72. replyContext, err := s.parseTemplate(contextTemplate, templateVarMap)
  73. if err != nil {
  74. return ret, err
  75. }
  76. ret.ReplyContext = replyContext
  77. return ret, nil
  78. }
  79. // 发送http 请求
  80. var responseData string
  81. if strings.Contains(config.URLTemplate, ";") {
  82. urlList := strings.Split(config.URLTemplate, ";")
  83. pamList := strings.Split(config.QueryTemplate, ";")
  84. for idx, url := range urlList {
  85. config.URLTemplate = url
  86. config.QueryTemplate = pamList[idx]
  87. if strings.HasPrefix(pamList[idx], "{") {
  88. config.HTTPMethod = 1
  89. } else {
  90. config.HTTPMethod = 0
  91. }
  92. response, err := s.sendHTTPRequest(&config, templateVarMap, inputData.JwtToken)
  93. if err != nil {
  94. return ret, err
  95. }
  96. responseData = responseData + response + "#@#@#@"
  97. }
  98. responseData = strings.TrimRight(responseData, "#@#@#@")
  99. } else {
  100. responseData, err = s.sendHTTPRequest(&config, templateVarMap, inputData.JwtToken)
  101. if err != nil {
  102. return ret, err
  103. }
  104. }
  105. // 抽取字段
  106. responseExtract := make(map[string]string)
  107. err = json.Unmarshal([]byte(config.ResponseExtract), &responseExtract)
  108. if err != nil {
  109. return ret, err
  110. }
  111. // 额外逻辑处理
  112. switch config.MetricType {
  113. case 2:
  114. responseData, _ = TransformType2(responseData)
  115. case 4:
  116. responseData, _ = TransformType4(responseData)
  117. case 5:
  118. responseData, _ = TransformType5(responseData)
  119. case 6:
  120. responseData, _ = TransformType6(responseData)
  121. case 8:
  122. responseData, _ = TransformType8(responseData)
  123. case 15:
  124. responseData, _ = TransformType15(responseData)
  125. case 17:
  126. responseData, _ = TransformType17(responseData)
  127. case 19:
  128. responseData, _ = TransformType19(responseData)
  129. case 21:
  130. responseData, _ = TransformType21(responseData)
  131. case 22:
  132. responseData, _ = TransformType22(responseData)
  133. case 23:
  134. responseData, _ = TransformType23(responseData)
  135. case 24:
  136. responseData, _ = TransformType24(responseData)
  137. case 25, 26, 27:
  138. responseData, _ = TransformType25(responseData, inputData.IsEnglish)
  139. case 28:
  140. responseData, _ = TransformType28(responseData, inputData.IsEnglish)
  141. case 29:
  142. responseData, _ = TransformType29(responseData)
  143. case 30:
  144. responseData, _ = TransformType30(responseData)
  145. case 35:
  146. responseData, _ = TransformType35(responseData)
  147. case 36:
  148. responseData, _ = TransformType36(responseData)
  149. case 38:
  150. responseData, _ = TransformType38(responseData)
  151. case 39:
  152. responseData, _ = TransformType39(responseData)
  153. case 42:
  154. responseData, _ = TransformType42(responseData)
  155. case 51:
  156. responseData, _ = TransformType51(responseData)
  157. case 59:
  158. responseData, _ = TransformType59(responseData, inputData.IsEnglish, inputData.DateTime)
  159. }
  160. extractMap := s.extractFields(responseExtract, responseData)
  161. for k, v := range extractMap {
  162. templateVarMap[k] = v
  163. }
  164. // 解析返回模板
  165. replyContext, err := s.parseTemplate(config.ContextTemplate, templateVarMap)
  166. if err != nil {
  167. return ret, err
  168. }
  169. ret.Flag = entity.HttpReply
  170. ret.ReplyContext = replyContext
  171. return ret, nil
  172. }
  173. func (s *MetricProcessConfigService) objToMap(req entity.MetricProcessRequest) map[string]interface{} {
  174. ret := make(map[string]interface{})
  175. ret["name"] = req.Name
  176. ret["think_str"] = entity.ThinkStr
  177. ret["date_src"] = req.DateSrc
  178. ret["s_time"] = req.STime
  179. ret["e_time"] = req.ETime
  180. ret["local_url"] = req.LocalUrl
  181. ret["id"] = req.ID
  182. ret["datetime"] = req.DateTime
  183. return ret
  184. }
  185. // sendHTTPRequest 发送HTTP请求
  186. func (s *MetricProcessConfigService) sendHTTPRequest(config *entity.MetricProcessConfig, inputData map[string]interface{}, jwtToken string) (string, error) {
  187. // 解析URL模板
  188. reqUrl, err := s.parseTemplate(config.URLTemplate, inputData)
  189. if err != nil {
  190. return "", fmt.Errorf("解析URL模板失败: %v", err)
  191. }
  192. var req *http.Request
  193. switch config.HTTPMethod {
  194. case 0: // GET
  195. // 解析查询参数模板
  196. query, err := s.parseTemplate(config.QueryTemplate, inputData)
  197. if err != nil {
  198. return "", fmt.Errorf("解析查询参数模板失败: %v", err)
  199. }
  200. // 对查询参数进行urlencode处理
  201. if query != "" {
  202. pairs := strings.Split(query, "&")
  203. encodedQuery := ""
  204. for i, pair := range pairs {
  205. if i > 0 {
  206. encodedQuery += "&"
  207. }
  208. // 分割键值对
  209. kv := strings.Split(pair, "=")
  210. if len(kv) == 2 {
  211. // 对键和值都进行urlencode
  212. encodedKey := url.QueryEscape(kv[0])
  213. encodedValue := url.QueryEscape(kv[1])
  214. encodedQuery += encodedKey + "=" + encodedValue
  215. }
  216. }
  217. reqUrl += "?" + encodedQuery
  218. }
  219. req, err = http.NewRequest("GET", reqUrl, nil)
  220. if err != nil {
  221. return "", fmt.Errorf("创建GET请求失败: %v", err)
  222. }
  223. case 1: // POST
  224. // 解析请求体模板
  225. bodyStr, err := s.parseTemplate(config.QueryTemplate, inputData)
  226. if err != nil {
  227. return "", fmt.Errorf("解析请求体模板失败: %v", err)
  228. }
  229. body := strings.NewReader(bodyStr)
  230. req, err = http.NewRequest("POST", reqUrl, body)
  231. if err != nil {
  232. return "", fmt.Errorf("创建POST请求失败: %v", err)
  233. }
  234. // 设置默认内容类型
  235. req.Header.Set("Content-Type", "application/json")
  236. default:
  237. return "", fmt.Errorf("不支持的HTTP方法: %d", config.HTTPMethod)
  238. }
  239. req.Header.Set("JWT-TOKEN", jwtToken)
  240. // 发送请求
  241. resp, err := s.httpClient.Do(req)
  242. if err != nil {
  243. return "", fmt.Errorf("发送请求失败: %v", err)
  244. }
  245. defer resp.Body.Close()
  246. // 读取响应
  247. body, err := io.ReadAll(resp.Body)
  248. if err != nil {
  249. return "", fmt.Errorf("读取响应失败: %v", err)
  250. }
  251. responseString := string(body)
  252. if resp.StatusCode != http.StatusOK {
  253. return "", fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, responseString)
  254. }
  255. return responseString, nil
  256. }
  257. // extractFields 提取指定字段
  258. func (s *MetricProcessConfigService) extractFields(rules map[string]string, responseBody string) map[string]interface{} {
  259. ret := make(map[string]interface{})
  260. for field, rule := range rules {
  261. result := gjson.Get(responseBody, rule)
  262. ret[field] = result.Value()
  263. }
  264. return ret
  265. }
  266. // parseTemplate 解析模板
  267. func (s *MetricProcessConfigService) parseTemplate(tpl string, data map[string]interface{}) (string, error) {
  268. if tpl == "" {
  269. return "", nil
  270. }
  271. funcMap := template.FuncMap{
  272. "SplitAndFetch": utils.SplitAndFetch,
  273. }
  274. // 创建模板
  275. t, err := template.New("").Funcs(funcMap).Parse(tpl)
  276. if err != nil {
  277. return "", fmt.Errorf("解析模板失败: %v", err)
  278. }
  279. // 执行模板
  280. var buf bytes.Buffer
  281. if err := t.Execute(&buf, data); err != nil {
  282. return "", fmt.Errorf("执行模板失败: %v", err)
  283. }
  284. return buf.String(), nil
  285. }