ai_scheduler/internal/tools/zltx/order_after_reseller.go

358 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package zltx
import (
"ai_scheduler/internal/config"
"ai_scheduler/internal/entitys"
"ai_scheduler/internal/pkg/l_request"
"ai_scheduler/internal/pkg/util"
"context"
"encoding/json"
"fmt"
"sync"
"time"
)
type OrderAfterSaleResellerTool struct {
config config.ToolConfig
}
// NewOrderAfterSaleResellerTool 创建售后订单预检工具
func NewOrderAfterSaleResellerTool(config config.ToolConfig) *OrderAfterSaleResellerTool {
return &OrderAfterSaleResellerTool{config: config}
}
// Name 返回工具名称
func (t *OrderAfterSaleResellerTool) Name() string {
return "zltxOrderAfterSaleReseller"
}
// 未使用-仅实现接口
func (t *OrderAfterSaleResellerTool) Description() string {
return "直连天下下游分销商直充订单售后工具"
}
// 未使用-仅实现接口
func (t *OrderAfterSaleResellerTool) Definition() entitys.ToolDefinition {
return entitys.ToolDefinition{}
}
type OrderAfterSaleResellerRequest struct {
OrderNumber []string `json:"orderNumber"` // 订单号
Account []string `json:"account"` // 充值账号
SerialCreateTime string `json:"serialCreateTime"` // 流水创建时间
AfterType string `json:"afterType"` // 处理方式 1.退款 2.扣款
AfterSalesPrice string `json:"afterSalesPrice"` // 售后金额
AfterSalesReason string `json:"afterSalesReason"` // 售后原因
ResponsibleType string `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无
ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商
}
type OrderAfterSaleResellerResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data []*OrderAfterSaleResellerData `json:"data"`
}
type OrderAfterSaleResellerData struct {
OrderType int `json:"orderType"`
OrderNumber string `json:"orderNumber"`
OrderAmount float64 `json:"orderAmount"`
OrderPrice float64 `json:"orderPrice"`
SignCompany int `json:"signCompany"`
OrderQuantity int `json:"orderQuantity"`
ResellerID int `json:"resellerId"`
ResellerName string `json:"resellerName"`
OurProductID int `json:"ourProductId"`
OurProductTitle string `json:"ourProductTitle"`
Account []string `json:"account"`
Platforms map[int]string `json:"platforms"`
AfterType int `json:"afterType"` // 处理方式 1.退款 2.扣款
Remark string `json:"remark"` // 售后原因
AfterAmount float64 `json:"afterAmount"` // 售后金额
ResponsibleType int `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无
ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商
IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后
CreateTime int `json:"createTime"` // 流水创建时间
}
// 接口返回
type OrderAfterSaleResellerApiResponse struct {
Code int `json:"code"`
Error string `json:"error"`
Data OrderAfterSaleResellerApiData `json:"data"`
}
type OrderAfterSaleResellerApiData struct {
Data []OrderAfterSaleResellerApiBase `json:"data"`
ExtData map[string]OrderAfterSaleResellerApiExtItem `json:"extraData"`
}
type OrderAfterSaleResellerApiBase struct {
OrderType int `json:"orderType"`
OrderNumber string `json:"orderNumber"`
OrderAmount float64 `json:"orderAmount"`
OrderPrice float64 `json:"orderPrice"`
SignCompany int `json:"signCompany"`
OrderQuantity int `json:"orderQuantity"`
ResellerID int `json:"resellerId"`
ResellerName string `json:"resellerName"`
OurProductID int `json:"ourProductId"`
OurProductTitle string `json:"ourProductTitle"`
Account []string `json:"account"`
Platforms map[int]string `json:"platforms"`
}
type OrderAfterSaleResellerApiExtItem struct {
IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 - 未使用
SerialCreateTime int `json:"createTime"` // 流水创建时间
}
func (t *OrderAfterSaleResellerTool) Execute(ctx context.Context, requireData *entitys.RequireData) error {
var req OrderAfterSaleResellerRequest
if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil {
return fmt.Errorf("解析参数失败,请重试或联系管理员")
}
if len(req.OrderNumber) == 0 && len(req.Account) == 0 {
return fmt.Errorf("订单号 和 充值账号 不能同时为空")
}
// 时间格式不匹配,直接置为空
if req.SerialCreateTime != "" {
_, err := time.ParseInLocation(time.DateTime, req.SerialCreateTime, time.Local)
if err != nil {
entitys.ResLog(requireData.Ch, t.Name(), "时间格式不匹配,已置为空")
req.SerialCreateTime = ""
}
}
entitys.ResLog(requireData.Ch, t.Name(), "正在拉取售后订单信息")
return t.checkOrderAfterSaleReseller(req, requireData)
}
func (t *OrderAfterSaleResellerTool) checkOrderAfterSaleReseller(toolReq OrderAfterSaleResellerRequest, requireData *entitys.RequireData) error {
var serialStartTime, serialEndTime int64
if toolReq.SerialCreateTime != "" {
// 流水创建时间上下浮动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
} else {
// 未指定流水创建时间默认30天内
serialEndTime = time.Now().Unix()
serialStartTime = serialEndTime - 60*60*24*30 // 30天内
}
// 账号数量超过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 []*OrderAfterSaleResellerData
var err error
// 多订单号
if len(toolReq.OrderNumber) > 0 {
body := map[string]any{
"order_numbers": toolReq.OrderNumber, // 订单号
}
orderList, err = t.getAfterSaleResellerList(headers, body, toolReq)
if err != nil {
return err
}
} else if len(toolReq.Account) > 0 {
// 多充值账号并发
orderListChan := make(chan []*OrderAfterSaleResellerData, 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, // 充值账号
"create_time": []int64{serialStartTime, serialEndTime}, // 流水创建时间区间
"order_type": 1, // 1.直充
}
orderListIn, errIn := t.getAfterSaleResellerList(headers, body, toolReq)
if errIn != nil {
return
}
orderListChan <- orderListIn
}(account)
}
waitGroup.Wait()
close(orderListChan)
// 合并结果
for orderListIn := range orderListChan {
orderList = append(orderList, orderListIn...)
}
} else {
return fmt.Errorf("订单号 和 充值账号 不能同时为空")
}
// 未查询到相应售后订单,请核实提供信息是否正确
if len(orderList) == 0 {
return fmt.Errorf("未查询到相应售后订单,请核实提供信息是否正确")
}
toolResp := OrderAfterSaleResellerResponse{
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 *OrderAfterSaleResellerTool) getAfterSaleResellerList(headers map[string]string, body map[string]any, originInput OrderAfterSaleResellerRequest) ([]*OrderAfterSaleResellerData, 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 OrderAfterSaleResellerApiResponse
if err = json.Unmarshal(res.Content, &resp); err != nil {
return nil, err
}
if resp.Code != 200 {
return nil, fmt.Errorf("after sale reseller failed: %s", resp.Error)
}
orderList := make([]*OrderAfterSaleResellerData, 0, len(resp.Data.Data))
// 转换数据
for _, item := range resp.Data.Data {
// 处理方式
afterType := util.StringToInt(originInput.AfterType)
if afterType == 0 {
afterType = 1 // 默认退款
}
// 费用承担者
responsibleType := util.StringToInt(originInput.ResponsibleType)
if responsibleType == 0 {
responsibleType = 4 // 默认无
}
// 售后金额
afterSalesPrice := util.StringToFloat64(originInput.AfterSalesPrice)
if afterSalesPrice == 0 {
afterSalesPrice = item.OrderPrice
}
orderList = append(orderList, &OrderAfterSaleResellerData{
OrderType: item.OrderType,
OrderNumber: item.OrderNumber,
OrderAmount: item.OrderAmount,
OrderPrice: item.OrderPrice,
SignCompany: item.SignCompany,
OrderQuantity: item.OrderQuantity,
ResellerID: item.ResellerID,
ResellerName: item.ResellerName,
OurProductID: item.OurProductID,
OurProductTitle: item.OurProductTitle,
Account: item.Account,
Platforms: item.Platforms,
AfterType: afterType,
Remark: originInput.AfterSalesReason,
AfterAmount: afterSalesPrice,
ResponsibleType: responsibleType,
ResponsiblePerson: originInput.ResponsiblePerson,
})
}
// 追加扩展数据
for _, item := range orderList {
if extItem, ok := resp.Data.ExtData[item.OrderNumber]; ok {
item.IsExistsAfterSale = item.OrderType > 100 // 101 直充&已售后
item.CreateTime = extItem.SerialCreateTime
}
}
return orderList, nil
}
// func (t *OrderAfterSaleResellerTool) checkOrderAfterSaleResellerMock(req OrderAfterSaleResellerRequest, requireData *entitys.RequireData) error {
// resp := OrderAfterSaleResellerResponse{
// Code: 0,
// Msg: "success",
// Data: []*OrderAfterSaleResellerData{
// {
// OrderType: 1,
// OrderNumber: "846784115378364417",
// OrderAmount: 0.1,
// OrderPrice: 0.1,
// SignCompany: 1,
// OrderQuantity: 1,
// ResellerID: 23329,
// ResellerName: "分销商23329",
// OurProductID: 106,
// OurProductTitle: "爱奇艺黄金会员周卡",
// Account: []string{"15516353308"},
// Platforms: map[int]string{4: "爱奇艺"},
// CreateTime: 1723304000,
// AfterType: 1,
// Remark: "测试售后",
// AfterAmount: 50,
// ResponsibleType: 1,
// IsExistsAfterSale: false,
// },
// {
// OrderType: 101,
// OrderNumber: "846052057729867777",
// OrderAmount: 23,
// OrderPrice: 23,
// SignCompany: 1,
// OrderQuantity: 1,
// ResellerID: 25629,
// ResellerName: "二期财务分销商简称",
// OurProductID: 104,
// OurProductTitle: "优酷年卡",
// Account: []string{"18380416326"},
// Platforms: map[int]string{1: "爱瓦力"},
// CreateTime: 1723305000,
// AfterType: 2,
// Remark: "测试售后2",
// AfterAmount: 30,
// ResponsibleType: 2,
// IsExistsAfterSale: false,
// },
// },
// }
// if len(req.OrderNumber) == 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
// }