diff --git a/internal/data/constants/bot.go b/internal/data/constants/bot.go index 6dc6680..0863cb8 100644 --- a/internal/data/constants/bot.go +++ b/internal/data/constants/bot.go @@ -3,5 +3,8 @@ package constants type BotTools string const ( - BotToolsBugOptimizationSubmit = "bug_optimization_submit" // 系统的bug/优化建议 + BotToolsBugOptimizationSubmit = "bug_optimization_submit" // 系统的bug/优化建议 + BotToolsAfterSalesSupplier = "after_sales_supplier" // 供应商售后 + BotToolsAfterSalesResellerSingle = "after_sales_reseller_single" // 分销商单条售后 + BotToolsAfterSalesResellerBatch = "after_sales_reseller_batch" // 分销商批量售后 ) diff --git a/internal/tools/zltx_after_sale.go b/internal/tools/zltx_after_sale.go deleted file mode 100644 index d5706ac..0000000 --- a/internal/tools/zltx_after_sale.go +++ /dev/null @@ -1,131 +0,0 @@ -package tools - -import ( - "ai_scheduler/internal/config" - "ai_scheduler/internal/entitys" - "context" - "encoding/json" - "fmt" - "sort" - - "gitea.cdlsxd.cn/self-tools/l_request" -) - -type ZltxOrderAfterSaleTool struct { - config config.ToolConfig -} - -func (z ZltxOrderAfterSaleTool) Name() string { - return "zltxOrderAfterSale" -} - -func (z ZltxOrderAfterSaleTool) Description() string { - return "查询直连天下订单售后信息" -} - -func (z ZltxOrderAfterSaleTool) Definition() entitys.ToolDefinition { - return entitys.ToolDefinition{ - Type: "function", - Function: entitys.FunctionDef{ - Name: z.Name(), - Description: z.Description(), - Parameters: map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "number": map[string]interface{}{ - "type": "string", - "description": "账号或分销商号", - }, - }, - "required": []string{"number"}, - }, - }, - } -} - -type ZltxOrderAfterSaleRequest struct { - Number string `json:"number"` -} - -func (z ZltxOrderAfterSaleTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { - var req ZltxOrderAfterSaleRequest - if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { - return err - } - if req.Number == "" { - return fmt.Errorf("number is required") - } - return z.getZltxOrderAfterSale(req.Number, requireData) -} - -type ZltxOrderAfterSaleResponse struct { - Code int `json:"code"` - Data struct { - List []*ZltxOrderAfterSaleData `json:"list"` - } `json:"data"` - Error string `json:"error"` -} - -type ZltxOrderAfterSaleData struct { - // 处理方式 价款/扣款 - HandleMethod string `json:"handle_method"` - // 售后金额 - AfterSaleAmount float64 `json:"after_sale_amount"` - // 售后原因 - AfterSaleReason string `json:"after_sale_reason"` - // 原单信息 - OriginalOrderInfo *OrderInfo -} - -type OrderInfo struct { - SerialNumber string `json:"serial_number"` // 订单流水号 - SupplierName string `json:"supplier_name"` // 供应商名称 - SigningBody string `json:"signing_body"` // 签约主体 - ProductName string `json:"product_name"` // 商品名称 - UpstreamPrice float64 `json:"upstream_price"` // 上游价格 - RechargeAccount string `json:"recharge_account"` // 充值账号 - RechargeStatus string `json:"recharge_status"` // 充值状态 -} - -func (z ZltxOrderAfterSaleTool) getZltxOrderAfterSale(number string, requireData *entitys.RequireData) error { - //查询订单详情 - - url := fmt.Sprintf("%s%s", z.config.BaseURL, number) - req := l_request.Request{ - Url: url, - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", requireData.Auth), - }, - Method: "GET", - } - res, err := req.Send() - var resData ZltxOrderAfterSaleResponse - if err != nil { - return err - } - if err := json.Unmarshal(res.Content, &resData); err != nil { - return err - } - if resData.Code != 200 { - return fmt.Errorf("为获取到数据,请检查权限: %s", string(res.Content)) - } - //按照日期排序 - sort.Slice(resData.Data.RecentThreeDays, func(i, j int) bool { - return resData.Data.RecentThreeDays[i].Date < resData.Data.RecentThreeDays[j].Date - }) - sort.Slice(resData.Data.RecentOneMonth, func(i, j int) bool { - return resData.Data.RecentOneMonth[i].Date < resData.Data.RecentOneMonth[j].Date - }) - jsonByte, err := json.Marshal(resData) - if err != nil { - return err - } - entitys.ResJson(requireData.Ch, z.Name(), string(jsonByte)) - return nil -} - -func NewZltxOrderAfterSaleTool(config config.ToolConfig) *ZltxOrderAfterSaleTool { - return &ZltxOrderAfterSaleTool{ - config: config, - } -} diff --git a/internal/tools_bot/after_sales_supplier.go b/internal/tools_bot/after_sales_supplier.go new file mode 100644 index 0000000..aca4a45 --- /dev/null +++ b/internal/tools_bot/after_sales_supplier.go @@ -0,0 +1,77 @@ +package tools_bot + +import ( + "ai_scheduler/internal/entitys" + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/ollama/ollama/api" +) + +type AfterSalesSupplierArgs struct { + OrderNumber string `json:"orderNumber"` + SerialNumber string `json:"serialNumber"` + Account string `json:"account"` + OrderTimeStart int `json:"orderTimeStart"` + OrderTimeEnd int `json:"orderTimeEnd"` +} + +type AfterSalesSupplierList struct { + AfterSalesSupplierData []*AfterSalesSupplierData `json:"afterSalesSupplierData"` +} + +type AfterSalesSupplierData struct { + OrderNumber string `json:"orderNumber"` + SerialNumber string `json:"serialNumber"` + Account string `json:"account"` + OrderTimeStart int `json:"orderTimeStart"` + OrderTimeEnd int `json:"orderTimeEnd"` +} + +// AfterSalesSupplier 售后供应商 +func (w *BotTool) AfterSalesSupplier(ctx context.Context, requireData *entitys.RequireData) (err error) { + // 1. 参数提取 + extractResponse, err := w.llm.Generation(ctx, &api.GenerateRequest{ + Model: w.config.Ollama.Model, + Stream: new(bool), + System: ` + 你是一个内容提取工具,用户会提供上游供应商售后流水/订单相关问题,你需要提取用户咨询的订单/流水信息。 + - 提取的信息有 订单号、流水号、充值账号、订单时间区间 + - 仅返回json: {"orderNumber":"","serialNumber":"","account":"","orderTimeStart":unix时间戳,"orderTimeEnd":unix时间戳} + - 不要有额外的描述、markdown等 + 用户输入:%s + `, + Prompt: requireData.Req.Text, + }) + if err != nil { + return + } + afterSalesSupplierArgs := &AfterSalesSupplierArgs{} + _ = json.Unmarshal([]byte(extractResponse.Response), afterSalesSupplierArgs) + + // 流水号为空 + if afterSalesSupplierArgs.SerialNumber == "" { + // 1.1 通过充值账号查询订单号 + + // 1.2 通过订单号拉取流水号 + + } + + // 流水号不存在 + if afterSalesSupplierArgs.SerialNumber == "" { + return fmt.Errorf("serialNumber is required") + } + + // 流水号转切片 + serialNumbers := strings.Split(afterSalesSupplierArgs.SerialNumber, ",") + _ = serialNumbers + + // 2. 获取流水详情 + // ZltxOrderAfterSaleDetailTool + + // 3. 组装售后订单详情 + + return nil +} diff --git a/internal/tools_bot/dtalk_bot.go b/internal/tools_bot/dtalk_bot.go index 18ac27f..e699a3b 100644 --- a/internal/tools_bot/dtalk_bot.go +++ b/internal/tools_bot/dtalk_bot.go @@ -17,6 +17,7 @@ type BotTool struct { llm *utils_ollama.Client sessionImpl *impl.SessionImpl taskMap map[string]string // task_id -> session_id + // zltxOrderAfterSaleTool tools.ZltxOrderAfterSaleTool } // NewBotTool 创建直连天下订单详情工具 @@ -29,6 +30,12 @@ func (w *BotTool) Execute(ctx context.Context, toolName string, requireData *ent switch toolName { case constants.BotToolsBugOptimizationSubmit: err = w.BugOptimizationSubmit(ctx, requireData) + case constants.BotToolsAfterSalesSupplier: + err = w.AfterSalesSupplier(ctx, requireData) + // case constants.BotToolsAfterSalesResellerSingle: + // err = w.AfterSalesResellerSingle(ctx, requireData) + // case constants.BotToolsAfterSalesResellerBatch: + // err = w.AfterSalesResellerBatch(ctx, requireData) default: log.Errorf("未知的工具类型:%s", toolName) err = errors.ParamErr("未知的工具类型:%s", toolName)