| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- package service
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "github.com/tidwall/gjson"
- "io"
- "net/http"
- "net/url"
- "newaterobot-process/entity"
- "newaterobot-process/model"
- "newaterobot-process/utils"
- "strings"
- "text/template"
- "time"
- )
- // MetricProcessConfigService 指标处理配置服务
- type MetricProcessConfigService struct {
- configModel *model.MetricProcessConfigModel
- httpClient *http.Client
- }
- // NewMetricProcessConfigService 创建指标处理配置服务实例
- func NewMetricProcessConfigService() *MetricProcessConfigService {
- return &MetricProcessConfigService{
- configModel: &model.MetricProcessConfigModel{},
- httpClient: &http.Client{
- Timeout: 30 * time.Second,
- },
- }
- }
- // ProcessMetric 处理指标
- func (s *MetricProcessConfigService) ProcessMetric(inputData entity.MetricProcessRequest) (entity.MetricProcessResponse, error) {
- ret := entity.MetricProcessResponse{}
- // 根据指标类型获取配置
- configs, err := s.configModel.GetByMetricType(inputData.MetricType, inputData.Intent)
- if err != nil {
- return ret, err
- }
- configsMap := make(map[string]entity.MetricProcessConfig)
- for _, config := range configs {
- key := fmt.Sprintf("%d_%d", config.Intent, config.MetricType)
- configsMap[key] = config
- }
- key := fmt.Sprintf("%d_%d", inputData.Intent, inputData.MetricType)
- var config entity.MetricProcessConfig
- var ok bool
- //未配置该处理分支直接返回,在dify中处理
- if config, ok = configsMap[key]; !ok {
- ret.Flag = entity.NoExecute
- return ret, nil
- }
- //直接回复分支
- templateVarMap := s.objToMap(inputData)
- if config.Type == 1 {
- contextTemplate := config.ContextTemplate
- if inputData.IsEnglish == 1 {
- contextTemplate = config.EngContextTemplate
- }
- replyContext, err := s.parseTemplate(contextTemplate, templateVarMap)
- if err != nil {
- return ret, err
- }
- ret.ReplyContext = replyContext
- return ret, nil
- }
- //发送http 请求
- responseData, err := s.sendHTTPRequest(&config, templateVarMap, inputData.JwtToken)
- if err != nil {
- return ret, err
- }
- //抽取字段
- responseExtract := make(map[string]string)
- err = json.Unmarshal([]byte(config.ResponseExtract), &responseExtract)
- if err != nil {
- return ret, err
- }
- extractMap := s.extractFields(responseExtract, responseData)
- for k, v := range extractMap {
- templateVarMap[k] = v
- }
- //解析返回模板
- replyContext, err := s.parseTemplate(config.ContextTemplate, templateVarMap)
- if err != nil {
- return ret, err
- }
- ret.Flag = entity.HttpReply
- ret.ReplyContext = replyContext
- return ret, nil
- }
- func (s *MetricProcessConfigService) objToMap(req entity.MetricProcessRequest) map[string]interface{} {
- ret := make(map[string]interface{})
- ret["name"] = req.Name
- ret["think_str"] = entity.ThinkStr
- ret["date_src"] = req.DateSrc
- ret["s_time"] = req.STime
- ret["e_time"] = req.ETime
- ret["local_url"] = req.LocalUrl
- ret["id"] = req.ID
- ret["datetime"] = req.DateTime
- return ret
- }
- // sendHTTPRequest 发送HTTP请求
- func (s *MetricProcessConfigService) sendHTTPRequest(config *entity.MetricProcessConfig, inputData map[string]interface{}, jwtToken string) (string, error) {
- // 解析URL模板
- reqUrl, err := s.parseTemplate(config.URLTemplate, inputData)
- if err != nil {
- return "", fmt.Errorf("解析URL模板失败: %v", err)
- }
- var req *http.Request
- switch config.HTTPMethod {
- case 0: // GET
- // 解析查询参数模板
- query, err := s.parseTemplate(config.QueryTemplate, inputData)
- if err != nil {
- return "", fmt.Errorf("解析查询参数模板失败: %v", err)
- }
- // 对查询参数进行urlencode处理
- if query != "" {
- pairs := strings.Split(query, "&")
- encodedQuery := ""
- for i, pair := range pairs {
- if i > 0 {
- encodedQuery += "&"
- }
- // 分割键值对
- kv := strings.Split(pair, "=")
- if len(kv) == 2 {
- // 对键和值都进行urlencode
- encodedKey := url.QueryEscape(kv[0])
- encodedValue := url.QueryEscape(kv[1])
- encodedQuery += encodedKey + "=" + encodedValue
- }
- }
- reqUrl += "?" + encodedQuery
- }
- req, err = http.NewRequest("GET", reqUrl, nil)
- if err != nil {
- return "", fmt.Errorf("创建GET请求失败: %v", err)
- }
- case 1: // POST
- // 解析请求体模板
- bodyStr, err := s.parseTemplate(config.QueryTemplate, inputData)
- if err != nil {
- return "", fmt.Errorf("解析请求体模板失败: %v", err)
- }
- body := strings.NewReader(bodyStr)
- req, err = http.NewRequest("POST", reqUrl, body)
- if err != nil {
- return "", fmt.Errorf("创建POST请求失败: %v", err)
- }
- // 设置默认内容类型
- req.Header.Set("Content-Type", "application/json")
- default:
- return "", fmt.Errorf("不支持的HTTP方法: %d", config.HTTPMethod)
- }
- req.Header.Set("JWT-TOKEN", jwtToken)
- // 发送请求
- resp, err := s.httpClient.Do(req)
- if err != nil {
- return "", fmt.Errorf("发送请求失败: %v", err)
- }
- defer resp.Body.Close()
- // 读取响应
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- return "", fmt.Errorf("读取响应失败: %v", err)
- }
- responseString := string(body)
- if resp.StatusCode != http.StatusOK {
- return "", fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, responseString)
- }
- return responseString, nil
- }
- // extractFields 提取指定字段
- func (s *MetricProcessConfigService) extractFields(rules map[string]string, responseBody string) map[string]interface{} {
- ret := make(map[string]interface{})
- for field, rule := range rules {
- result := gjson.Get(responseBody, rule)
- ret[field] = result.Value()
- }
- return ret
- }
- // parseTemplate 解析模板
- func (s *MetricProcessConfigService) parseTemplate(tpl string, data map[string]interface{}) (string, error) {
- if tpl == "" {
- return "", nil
- }
- funcMap := template.FuncMap{
- "SplitAndFetch": utils.SplitAndFetch,
- }
- // 创建模板
- t, err := template.New("").Funcs(funcMap).Parse(tpl)
- if err != nil {
- return "", fmt.Errorf("解析模板失败: %v", err)
- }
- // 执行模板
- var buf bytes.Buffer
- if err := t.Execute(&buf, data); err != nil {
- return "", fmt.Errorf("执行模板失败: %v", err)
- }
- return buf.String(), nil
- }
|