package tools import ( "ai_scheduler/internal/config" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/utils_ollama" "context" "encoding/json" "fmt" "gitea.cdlsxd.cn/self-tools/l_request" "github.com/gofiber/websocket/v2" "github.com/ollama/ollama/api" ) // ZltxOrderDetailTool 直连天下订单详情工具 type ZltxOrderDetailTool struct { config config.ToolConfig llm *utils_ollama.Client } // NewZltxOrderDetailTool 创建直连天下订单详情工具 func NewZltxOrderDetailTool(config config.ToolConfig, llm *utils_ollama.Client) *ZltxOrderDetailTool { return &ZltxOrderDetailTool{config: config, llm: llm} } // Name 返回工具名称 func (w *ZltxOrderDetailTool) Name() string { return "zltxOrderDetail" } // Description 返回工具描述 func (w *ZltxOrderDetailTool) Description() string { return "获取直连天下订单详情" } // Definition 返回工具定义 func (w *ZltxOrderDetailTool) Definition() entitys.ToolDefinition { return entitys.ToolDefinition{ Type: "function", Function: entitys.FunctionDef{ Name: w.Name(), Description: w.Description(), Parameters: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "number": map[string]interface{}{ "type": "string", "description": "订单编号/流水号", }, }, "required": []string{"number"}, }, }, } } // ZltxOrderDetailRequest 直连天下订单详情请求参数 type ZltxOrderDetailRequest struct { OrderNumber string `json:"order_number"` } // ZltxOrderDetailResponse 直连天下订单详情响应 type ZltxOrderDetailResponse struct { Code int `json:"code"` Error string `json:"error"` Data ZltxOrderDetailData `json:"data"` Mes string `json:"mes"` } type ZltxOrderLogResponse struct { Code int `json:"code"` Error string `json:"error"` Data any `json:"data"` } // ZltxOrderDetailData 直连天下订单详情数据 type ZltxOrderDetailData struct { Direct map[string]any `json:"direct"` Order map[string]any `json:"order"` } // Execute 执行直连天下订单详情查询 func (w *ZltxOrderDetailTool) Execute(channel chan entitys.Response, c *websocket.Conn, args json.RawMessage, matchJson *entitys.Match) error { var req ZltxOrderDetailRequest if err := json.Unmarshal(args, &req); err != nil { return fmt.Errorf("invalid zltxOrderDetail request: %w", err) } if req.OrderNumber == "" { return fmt.Errorf("number is required") } // 这里可以集成真实的直连天下订单详情API return w.getZltxOrderDetail(channel, c, req.OrderNumber, matchJson) } // getMockZltxOrderDetail 获取模拟直连天下订单详情数据 func (w *ZltxOrderDetailTool) getZltxOrderDetail(ch chan entitys.Response, c *websocket.Conn, number string, matchJson *entitys.Match) (err error) { //查询订单详情 var auth string if c != nil { auth = c.Query("x-authorization", "") } if len(auth) == 0 { auth = w.config.APIKey } req := l_request.Request{ Url: fmt.Sprintf("%szltx_api/admin/direct/ai/%s", w.config.BaseURL, number), Headers: map[string]string{ "Authorization": fmt.Sprintf("Bearer %s", auth), }, Method: "GET", } res, err := req.Send() if err != nil { return fmt.Errorf("订单查询失败:%s", err.Error()) } var codeMap map[string]interface{} if err = json.Unmarshal(res.Content, &codeMap); err != nil { return } if codeMap["code"].(float64) != 200 { return fmt.Errorf("订单查询失败:%s", codeMap["error"]) } var resData ZltxOrderDetailResponse if err = json.Unmarshal(res.Content, &resData); err != nil { return } ch <- entitys.Response{ Index: w.Name(), Content: res.Text, Type: entitys.ResponseJson, } if resData.Data.Direct != nil && resData.Data.Direct["needAi"].(bool) { ch <- entitys.Response{ Index: w.Name(), Content: "正在分析订单日志", Type: entitys.ResponseLoading, } req = l_request.Request{ Url: fmt.Sprintf("%szltx_api/admin/direct/log/%s/%s", w.config.BaseURL, resData.Data.Direct["orderOrderNumber"].(string), resData.Data.Direct["serialNumber"].(string)), Headers: map[string]string{ "Authorization": fmt.Sprintf("Bearer %s", auth), }, Method: "GET", } res, err = req.Send() if err != nil { return } var orderLog ZltxOrderLogResponse if err = json.Unmarshal(res.Content, &orderLog); err != nil { return } if orderLog.Code != 200 { return fmt.Errorf("订单日志查询失败:%s", orderLog.Error) } dataJson, err := json.Marshal(orderLog.Data) if err != nil { return fmt.Errorf("订单日志解析失败:%s", err) } err = w.llm.ChatStream(context.TODO(), ch, []api.Message{ { Role: "system", Content: "你是一个订单日志助手。用户可能会提供订单日志,你需要分析订单日志,提取出订单失败的原因。", }, { Role: "assistant", Content: fmt.Sprintf("聊天记录:%s", string(matchJson.History)), }, { Role: "assistant", Content: fmt.Sprintf("需要分析的订单日志:%s", string(dataJson)), }, { Role: "user", Content: matchJson.UserInput, }, }, w.Name()) if err != nil { return fmt.Errorf("订单日志解析失败:%s", err) } } if resData.Data.Direct == nil { ch <- entitys.Response{ Index: w.Name(), Content: "该订单无充值流水记录,不需要进行订单错误分析,建议检查订单收单模式以及扣款方式等原因😘", Type: entitys.ResponseText, } } // else { //} return }