feat: 增加电商充值系统-我们的商品统计工具

This commit is contained in:
fuzhongyun 2025-12-30 18:31:20 +08:00
parent f7afef05f7
commit 571b9a88f4
6 changed files with 180 additions and 7 deletions

View File

@ -112,18 +112,20 @@ eino_tools:
hytGoodsBrandSearch:
base_url: "https://gateway.dev.cdlsxd.cn/goods-admin/api/v1/goods/brand/list"
# == 报表分析 data analytics ==
# 负利润分析列表、 负利润分析详情
# 负利润分析列表
daOursProductLoss:
base_url: "http://test.analysis.com/api/dataanalytics/statisOursProductLossSum"
api_key: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzY2OTc4MTQwLCJuYmYiOjE3NjY5NzYzNDAsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.nyQw7_JZd7IfnIkPlfySGJMkFAHy_RtIL6gRqOYdku3ikp_w3x9bt7rrSBDQMi4Z8jC4jL_qxwhJ1D1DV4uLZ_cZBmuuG-gymIDN1TSJKa8hpu4E8L3tPdbT1H6hehXvg10-_ugKAYNBgnvFUbCRnpMl-sNuqCLWZKa_v63L1v3lGZOQiPPyzEGmIulNwqSF8rlzZggJneVTWEQac2BNK4181mpbz0S_m84xuFFO3Qwen2sEntBaPKeKbJ9BAfdSAQPcIlnG9FHF3mttZfxQQF5nbxU7CAGYsu_2kjpcmP-u5x3tT3gCWsF1t84lSZ8mMxIax7rh0-Y55abRoBnrwQ"
base_url: "https://reportapi.1688sup.com/api/dataanalytics/statisOursProductLossSum"
# 利润同比排行榜
daProfitRanking:
base_url: "http://test.analysis.com/api/dataanalytics/profitRankingSum"
api_key: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzY2OTc4MTQwLCJuYmYiOjE3NjY5NzYzNDAsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.nyQw7_JZd7IfnIkPlfySGJMkFAHy_RtIL6gRqOYdku3ikp_w3x9bt7rrSBDQMi4Z8jC4jL_qxwhJ1D1DV4uLZ_cZBmuuG-gymIDN1TSJKa8hpu4E8L3tPdbT1H6hehXvg10-_ugKAYNBgnvFUbCRnpMl-sNuqCLWZKa_v63L1v3lGZOQiPPyzEGmIulNwqSF8rlzZggJneVTWEQac2BNK4181mpbz0S_m84xuFFO3Qwen2sEntBaPKeKbJ9BAfdSAQPcIlnG9FHF3mttZfxQQF5nbxU7CAGYsu_2kjpcmP-u5x3tT3gCWsF1t84lSZ8mMxIax7rh0-Y55abRoBnrwQ"
base_url: "https://reportapi.1688sup.com/api/dataanalytics/profitRankingSum"
# 销售同比分析列表
daOfficialProduct:
base_url: "http://test.analysis.com/api/dataanalytics/statisOfficialProduct"
api_key: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzY2OTc4MTQwLCJuYmYiOjE3NjY5NzYzNDAsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.nyQw7_JZd7IfnIkPlfySGJMkFAHy_RtIL6gRqOYdku3ikp_w3x9bt7rrSBDQMi4Z8jC4jL_qxwhJ1D1DV4uLZ_cZBmuuG-gymIDN1TSJKa8hpu4E8L3tPdbT1H6hehXvg10-_ugKAYNBgnvFUbCRnpMl-sNuqCLWZKa_v63L1v3lGZOQiPPyzEGmIulNwqSF8rlzZggJneVTWEQac2BNK4181mpbz0S_m84xuFFO3Qwen2sEntBaPKeKbJ9BAfdSAQPcIlnG9FHF3mttZfxQQF5nbxU7CAGYsu_2kjpcmP-u5x3tT3gCWsF1t84lSZ8mMxIax7rh0-Y55abRoBnrwQ"
base_url: "https://reportapi.1688sup.com/api/dataanalytics/statisOfficialProduct"
# == 电商充值系统 ==
# 我们的商品统计
rechargeStatisticsOursProduct:
base_url: "http://admin.1688sup.cn:8001/admin/statistics/oursProduct"
api_key: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzY3MDc3NzcwLCJuYmYiOjE3NjcwNzU5NzAsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.Nuw_aR6iSPmhhh9E5rhyTxHBsgWtaTZvbnc7SFTnUBJXTQvYahnk0LyZaVpsVw6FB3cU0F5xOdX3rmGyWyaiszWO6yi-o1oxGMXwhf39fMiWT2xUI6pAn9Ync8DmZ4tOMCNUTdEk4CaQFzrTwJs0c-VR4yW6LgoPmNPvUVZ-KwmusUpnPz5j9RsJItzIWE3bpGGsfB54e2UERcZdbo9BXxCZIBbpAYKBKdl73KuI8SNaXgKvGTrJ6hEN4ESpnbisJVwT5pp_kuChJlcfjHTHFsEf4RJDjN9gTrtDbBWZyY3OmO2ukqYAM7tZPs6TXJwvQGJQsFRVZUBGxS1nD_6DzQ"
dingtalk:
api_key: "dingsbbntrkeiyazcfdg"

View File

@ -207,6 +207,8 @@ type EinoToolsConfig struct {
DaOfficialProduct ToolConfig `mapstructure:"daOfficialProduct"`
// 销售同比下滑详情
DaOfficialProductDecline ToolConfig `mapstructure:"daOfficialProductDecline"`
// 我们的商品统计
RechargeStatisticsOursProduct ToolConfig `mapstructure:"rechargeStatisticsOursProduct"`
}
// LoggingConfig 日志配置

View File

@ -0,0 +1,73 @@
package statistics_ours_product
import (
"ai_scheduler/internal/config"
"ai_scheduler/internal/pkg/l_request"
"context"
"encoding/json"
"fmt"
"strings"
"time"
)
type Client struct {
cfg config.ToolConfig
}
func New(cfg config.ToolConfig) *Client {
return &Client{
cfg: cfg,
}
}
// Call 调用我们的商品统计接口
func (c *Client) Call(ctx context.Context, req StatisticsOursProductRequest) ([]StatisticsOursProductItem, error) {
// 构建 URL 参数
var queryParams []string
if req.Page > 0 {
queryParams = append(queryParams, fmt.Sprintf("page=%d", req.Page))
}
if req.Limit > 0 {
queryParams = append(queryParams, fmt.Sprintf("limit=%d", req.Limit))
}
if req.OursProductId != "" {
queryParams = append(queryParams, fmt.Sprintf("ours_product_id=%s", req.OursProductId))
}
for _, s := range req.Serial {
queryParams = append(queryParams, fmt.Sprintf("serial[]=%s", s))
}
// 添加 timestamp
queryParams = append(queryParams, fmt.Sprintf("timestamp=%d", time.Now().UnixMilli()))
queryString := strings.Join(queryParams, "&")
fullURL := fmt.Sprintf("%s?%s", c.cfg.BaseURL, queryString)
headers := map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", c.cfg.APIKey),
}
reqObj := l_request.Request{
Method: "GET",
Url: fullURL,
Headers: headers,
}
res, err := reqObj.Send()
if err != nil {
return nil, fmt.Errorf("请求失败err: %v", err)
}
var resData StatisticsOursProductResponse
if err := json.Unmarshal([]byte(res.Text), &resData); err != nil {
return nil, fmt.Errorf("解析响应失败err: %v, resp: %s", err, res.Text)
}
if resData.Code != 200 {
return nil, fmt.Errorf("业务错误code: %d, msg: %s", resData.Code, resData.Msg)
}
return resData.Data, nil
}

View File

@ -0,0 +1,33 @@
package statistics_ours_product
import (
"ai_scheduler/internal/config"
"context"
"testing"
)
func TestClient_Call(t *testing.T) {
cfg := config.ToolConfig{
BaseURL: "http://admin.1688sup.cn:8001/admin/statistics/oursProduct",
APIKey: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzY3MDc3NzcwLCJuYmYiOjE3NjcwNzU5NzAsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.Nuw_aR6iSPmhhh9E5rhyTxHBsgWtaTZvbnc7SFTnUBJXTQvYahnk0LyZaVpsVw6FB3cU0F5xOdX3rmGyWyaiszWO6yi-o1oxGMXwhf39fMiWT2xUI6pAn9Ync8DmZ4tOMCNUTdEk4CaQFzrTwJs0c-VR4yW6LgoPmNPvUVZ-KwmusUpnPz5j9RsJItzIWE3bpGGsfB54e2UERcZdbo9BXxCZIBbpAYKBKdl73KuI8SNaXgKvGTrJ6hEN4ESpnbisJVwT5pp_kuChJlcfjHTHFsEf4RJDjN9gTrtDbBWZyY3OmO2ukqYAM7tZPs6TXJwvQGJQsFRVZUBGxS1nD_6DzQ",
}
client := New(cfg)
req := StatisticsOursProductRequest{
Page: 1,
Limit: 100,
Serial: []string{"2025122300", "2025123123"},
}
t.Logf("Testing Call with req: %+v", req)
// 由于没有真实的后端环境和 Token这里注释掉实际调用
// 在开发环境中,你可以取消注释并填入有效的 Token 进行测试
res, err := client.Call(context.Background(), req)
if err != nil {
t.Logf("Call failed: %v", err)
} else {
t.Logf("Call success, resp: %+v", res)
}
}

View File

@ -0,0 +1,30 @@
package statistics_ours_product
// StatisticsOursProductRequest 我们的商品统计请求参数
type StatisticsOursProductRequest struct {
Page int `json:"page"` // 页码
Limit int `json:"limit"` // 每页条数
Serial []string `json:"serial"` // 流水号范围 (通常是日期格式,如 YYYYMMDDHH)
OursProductId string `json:"ours_product_id"` // 我们的商品ID (可选)
}
// StatisticsOursProductResponse 我们的商品统计响应结构
// 注意:接口直接返回数组,而不是包含在 data 字段中的对象
type StatisticsOursProductResponse struct {
Code int `json:"code"`
Msg string `json:"error"` // 接口返回字段名为 error
Data []StatisticsOursProductItem `json:"data"` // data 是一个数组
}
type StatisticsOursProductItem struct {
OursProductId int `json:"ours_product_id"`
ResellerId int `json:"reseller_id"`
TotalPrice string `json:"total_price"`
Count string `json:"count"`
SuccessCount string `json:"success_count"`
SuccessPrice string `json:"success_price"`
FailCount string `json:"fail_count"`
FailPrice string `json:"fail_price"`
Profit string `json:"profit"`
OursProductName string `json:"ours_product_name"`
}

View File

@ -0,0 +1,33 @@
package recharge
import (
"ai_scheduler/internal/config"
toolManager "ai_scheduler/internal/domain/tools"
"ai_scheduler/internal/domain/workflow/runtime"
"ai_scheduler/internal/entitys"
"context"
)
const WorkflowIDStatisticsOursProduct = "recharge.statisticsOursProduct"
func init() {
runtime.Register(WorkflowIDStatisticsOursProduct, func(d *runtime.Deps) (runtime.Workflow, error) {
return &statisticsOursProduct{cfg: d.Conf, toolManager: d.ToolManager}, nil
})
}
type statisticsOursProduct struct {
cfg *config.Config
toolManager *toolManager.Manager
}
type StatisticsOursProductWorkflowInput struct {
// 预留字段
}
func (w *statisticsOursProduct) ID() string { return WorkflowIDStatisticsOursProduct }
func (w *statisticsOursProduct) Invoke(ctx context.Context, rec *entitys.Recognize) (map[string]any, error) {
// 保持流程为空,仅返回 nil
return nil, nil
}