package zltx import ( "ai_scheduler/internal/config" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/l_request" "context" "encoding/json" "fmt" "sync" "time" ) type OrderAfterSaleSupplierTool struct { config config.ToolConfig } // NewOrderAfterSaleSupplierTool 创建售后订单预检工具 func NewOrderAfterSaleSupplierTool(config config.ToolConfig) *OrderAfterSaleSupplierTool { return &OrderAfterSaleSupplierTool{config: config} } // Name 返回工具名称 func (t *OrderAfterSaleSupplierTool) Name() string { return "zltxOrderAfterSaleSupplier" } // 未使用-仅实现接口 func (t *OrderAfterSaleSupplierTool) Description() string { return "直连天下上游供应商直充订单售后工具" } // 未使用-仅实现接口 func (t *OrderAfterSaleSupplierTool) Definition() entitys.ToolDefinition { return entitys.ToolDefinition{} } type OrderAfterSaleSupplierRequest struct { SerialNumber []string `json:"serialNumber"` // 流水号 Account []string `json:"account"` // 充值账号 SerialCreateTime string `json:"serialCreateTime"` // 流水创建时间 AfterSalesReason string `json:"afterSalesReason"` // 售后原因 AfterSalesPrice string `json:"afterSalesPrice"` // 售后金额 AfterType int `json:"afterType"` // 售后类型 1.加款 2.扣款 } // 工具最终返回 type OrderAfterSaleSupplierResponse struct { Code int `json:"code"` Msg string `json:"msg"` Data []*OrderAfterSaleSupplierData `json:"data"` } type OrderAfterSaleSupplierData struct { SerialNumber string `json:"serialNumber"` // 流水号 PlatformName string `json:"platformName"` // 供应商名称 SignCompany int `json:"signCompany"` // 签约主体 PlatformProductName string `json:"platformProductName"` // 商品名称 PlatformPrice float64 `json:"platformPrice"` // 上游价格 TerminalAccount string `json:"terminalAccount"` // 充值账号 Status int `json:"status"` // 充值状态 PlatformProductID int `json:"platformProductId"` // 上有商品id PlatformID int `json:"platformId"` // 上游平台id SignCompanyName string `json:"signCompanyName"` // 签约主体名称 Reason string `json:"reason"` // 售后原因 SalePrice float64 `json:"salePrice"` // 售后金额 SaleType int `json:"saleType"` // 处理方式 1.加款 2.扣款 ExecuteTime int `json:"executeTime"` // 流水创建时间 IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 } // 接口返回 type OrderAfterSaleSupplierApiResponse struct { Code int `json:"code"` Msg string `json:"msg"` Data OrderAfterSaleSupplierApiData `json:"data"` } type OrderAfterSaleSupplierApiData struct { Data []OrderAfterSaleSupplierApiBase `json:"data"` ExtData map[string]OrderAfterSaleSupplierApiExtItem `json:"ext"` } type OrderAfterSaleSupplierApiBase struct { SerialNumber string `json:"serialNumber"` // 流水号 PlatformName string `json:"platformName"` // 供应商名称 SignCompany int `json:"signCompany"` // 签约主体 PlatformProductName string `json:"platformProductName"` // 商品名称 PlatformPrice float64 `json:"platformPrice"` // 上游价格 TerminalAccount string `json:"terminalAccount"` // 充值账号 Status int `json:"status"` // 充值状态 PlatformProductID int `json:"platformProductId"` // 上有商品id PlatformID int `json:"platformId"` // 上游平台id SignCompanyName string `json:"signCompanyName"` // 签约主体名称 Reason string `json:"reason"` // 售后原因 SalePrice float64 `json:"salePrice"` // 售后金额 SaleType int `json:"saleType"` // 处理方式 1.加款 2.扣款 } type OrderAfterSaleSupplierApiExtItem struct { IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 SerialCreateTime int `json:"serialCreateTime"` // 流水创建时间 } func (t *OrderAfterSaleSupplierTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { var req OrderAfterSaleSupplierRequest if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { return err } if len(req.SerialNumber) == 0 && len(req.Account) == 0 { return fmt.Errorf("充值流水号 和 充值账号 不能同时为空") } entitys.ResLog(requireData.Ch, t.Name(), "正在拉取售后订单信息") return t.checkOrderAfterSaleSupplierMock(req, requireData) } func (t *OrderAfterSaleSupplierTool) checkOrderAfterSaleSupplier(toolReq OrderAfterSaleSupplierRequest, requireData *entitys.RequireData) error { // 流水创建时间上下浮动10min serialCreateTime, err := time.ParseInLocation(time.DateTime, toolReq.SerialCreateTime, time.Local) if err != nil { return err } serialStartTime := serialCreateTime.Unix() - 10*60 serialEndTime := serialCreateTime.Unix() + 10*60 // 账号数量超过10直接截断 if len(toolReq.Account) > 10 { entitys.ResLog(requireData.Ch, t.Name(), "账号数量超过10已被截断") toolReq.Account = toolReq.Account[:10] } headers := map[string]string{ "Authorization": fmt.Sprintf("Bearer %s", requireData.Auth), } // 最终输出 var orderList []*OrderAfterSaleSupplierData // 多流水号 if len(toolReq.SerialNumber) > 0 { body := map[string]any{ "serialNumber": toolReq.SerialNumber, // 流水号 } orderList, err = t.getAfterSaleSupplierList(headers, body) if err != nil { return err } } else if len(toolReq.Account) > 0 { // 多充值账号并发 orderListChan := make(chan []*OrderAfterSaleSupplierData, len(toolReq.Account)) waitGroup := sync.WaitGroup{} // 并发请求 for _, account := range toolReq.Account { waitGroup.Add(1) go func(account string) { defer waitGroup.Done() body := map[string]any{ "account": account, // 充值账号 "serialStartTime": serialStartTime, // 流水创建时间 "serialEndTime": serialEndTime, // 流水结束时间 } orderListIn, errIn := t.getAfterSaleSupplierList(headers, body) if errIn != nil { return } orderListChan <- orderListIn }(account) } // 等待所有请求完成 waitGroup.Wait() close(orderListChan) for orderListIn := range orderListChan { orderList = append(orderList, orderListIn...) } } else { return fmt.Errorf("充值流水号 和 充值账号 不能同时为空") } toolResp := OrderAfterSaleSupplierResponse{ Code: 0, Msg: "Success", Data: orderList, } var jsonByte []byte jsonByte, err = json.Marshal(toolResp) if err != nil { return err } entitys.ResLog(requireData.Ch, t.Name(), "售后订单信息拉取完成") entitys.ResJson(requireData.Ch, t.Name(), string(jsonByte)) return nil } func (t *OrderAfterSaleSupplierTool) getAfterSaleSupplierList(headers map[string]string, body map[string]any) ([]*OrderAfterSaleSupplierData, error) { req := l_request.Request{ Url: t.config.BaseURL, Headers: headers, Method: "POST", Json: body, } res, err := req.Send() if err != nil { return nil, err } // 解析响应 var resp OrderAfterSaleSupplierApiResponse if err = json.Unmarshal(res.Content, &resp); err != nil { return nil, err } if resp.Code != 0 { return nil, fmt.Errorf("after sale supplier failed: %s", resp.Msg) } orderList := make([]*OrderAfterSaleSupplierData, 0, len(resp.Data.Data)) // 转换数据 for _, item := range resp.Data.Data { orderList = append(orderList, &OrderAfterSaleSupplierData{ SerialNumber: item.SerialNumber, PlatformName: item.PlatformName, SignCompany: item.SignCompany, PlatformProductName: item.PlatformProductName, PlatformPrice: item.PlatformPrice, TerminalAccount: item.TerminalAccount, Status: item.Status, PlatformProductID: item.PlatformProductID, PlatformID: item.PlatformID, SignCompanyName: item.SignCompanyName, Reason: item.Reason, SalePrice: item.SalePrice, SaleType: item.SaleType, }) } // 追加扩展数据 for _, item := range orderList { if extItem, ok := resp.Data.ExtData[item.SerialNumber]; ok { item.IsExistsAfterSale = extItem.IsExistsAfterSale item.ExecuteTime = extItem.SerialCreateTime } } return orderList, nil } // mock待删除 func (t *OrderAfterSaleSupplierTool) checkOrderAfterSaleSupplierMock(req OrderAfterSaleSupplierRequest, requireData *entitys.RequireData) error { resp := OrderAfterSaleSupplierResponse{ Code: 0, Msg: "success", Data: []*OrderAfterSaleSupplierData{ { SerialNumber: "847465394004430849", PlatformName: "爱奇艺", SignCompany: 1, PlatformProductName: "爱奇艺官方周卡", PlatformPrice: 6, TerminalAccount: "15516353308", Status: 1, PlatformProductID: 2, PlatformID: 4, SignCompanyName: "成都蓝色兄弟网络科技有限公司", ExecuteTime: 1763961931, Reason: "测试售后", SalePrice: 50, SaleType: 1, IsExistsAfterSale: false, }, { SerialNumber: "843493448012140545", PlatformName: "卓望别名1", SignCompany: 1, PlatformProductName: "卓望--别名商品1", PlatformPrice: 897.7765, TerminalAccount: "18380416326", Status: -1, PlatformProductID: 7497, PlatformID: 15, SignCompanyName: "成都蓝色兄弟网络科技有限公司", ExecuteTime: 1763014914, Reason: "测试售后2", SalePrice: 30, SaleType: 2, IsExistsAfterSale: true, }, }, } if len(req.SerialNumber) == 1 { resp.Data = resp.Data[:1] } jsonByte, err := json.Marshal(resp) if err != nil { return err } entitys.ResLog(requireData.Ch, t.Name(), "售后订单信息拉取完成") entitys.ResJson(requireData.Ch, t.Name(), string(jsonByte)) return nil }