ai_scheduler/internal/tools/zltx/order_after_supplier.go

280 lines
9.6 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 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 string `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"`
Error string `json:"error"`
Data OrderAfterSaleSupplierApiData `json:"data"`
}
type OrderAfterSaleSupplierApiData struct {
Data []OrderAfterSaleSupplierApiBase `json:"data"`
ExtData map[string]OrderAfterSaleSupplierApiExtItem `json:"extraData"`
}
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"` // 签约主体名称
ExecuteTime int `json:"executeTime"` // 充值执行时间
}
type OrderAfterSaleSupplierApiExtItem struct {
IsExistsAfterSale bool `json:"existAfterSales"` // 是否已存在售后 - 未使用
SerialCreateTime int `json:"createTime"` // 流水创建时间
}
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 fmt.Errorf("解析参数失败,请重试或联系管理员")
}
if len(req.SerialNumber) == 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.checkOrderAfterSaleSupplier(req, requireData)
}
func (t *OrderAfterSaleSupplierTool) checkOrderAfterSaleSupplier(toolReq OrderAfterSaleSupplierRequest, 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 []*OrderAfterSaleSupplierData
var err error
// 多流水号
if len(toolReq.SerialNumber) > 0 {
body := map[string]any{
"serial_numbers": toolReq.SerialNumber, // 流水号
}
orderList, err = t.getAfterSaleSupplierList(headers, body, toolReq)
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, // 充值账号
"create_time": []int64{serialStartTime, serialEndTime}, // 流水创建时间区间
}
orderListIn, errIn := t.getAfterSaleSupplierList(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 := 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, originInput OrderAfterSaleSupplierRequest) ([]*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 != 200 {
return nil, fmt.Errorf("after sale supplier failed: %s", resp.Error)
}
orderList := make([]*OrderAfterSaleSupplierData, 0, len(resp.Data.Data))
// 转换数据
for _, item := range resp.Data.Data {
// 处理方式
afterType := util.StringToInt(originInput.AfterType)
if afterType == 0 {
afterType = 1 // 默认退款
}
// 售后金额
afterSalesPrice := util.StringToFloat64(originInput.AfterSalesPrice)
if afterSalesPrice == 0 {
afterSalesPrice = item.PlatformPrice
}
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: originInput.AfterSalesReason,
SalePrice: afterSalesPrice,
SaleType: afterType,
})
}
// 追加扩展数据
for _, item := range orderList {
if extItem, ok := resp.Data.ExtData[item.SerialNumber]; ok {
item.IsExistsAfterSale = extItem.IsExistsAfterSale
item.ExecuteTime = extItem.SerialCreateTime
}
}
return orderList, nil
}