# 天元API调用记录功能 - 实施总结 ## 功能概述 本功能实现了天元API调用的成本记录,包括: 1. 在 `feature` 表添加 `cost_price` 字段,存储每个接口的成本价 2. 创建 `tianyuanapi_call_log` 表,记录每次API调用的详细信息 3. 无论成功失败都记录,但只有成功调用才计算成本 4. 提供统计功能,可查询时间段内的调用次数和总成本 ## 已完成的工作 ### 1. 数据库层面 ✅ **文件:** `ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql` **修改内容:** - 在 `feature` 表添加 `cost_price` 字段(decimal(10, 2),默认0.00) - 创建 `tianyuanapi_call_log` 表,包含以下字段: - `feature_id`: 关联feature表 - `api_id`: 天元API标识(如:YYSYBE08) - `order_id`: 关联订单(可选) - `query_id`: 关联查询(可选) - `call_status`: 调用状态(0=失败,1=成功) - `call_time`: 调用时间 - `response_time`: 响应耗时(毫秒) - `cost_price`: 本次调用成本(成功时有值,失败为0) - `error_code`: 错误码(失败时) - `error_message`: 错误信息(失败时) - `request_params`: 请求参数(JSON) - `response_data`: 响应数据(JSON,截取前1000字符) - `transaction_id`: 天元API流水号 **索引设计:** - `idx_feature_id`: 按feature_id查询 - `idx_api_id`: 按api_id查询 - `idx_order_id`: 按order_id查询 - `idx_query_id`: 按query_id查询 - `idx_call_status`: 按调用状态查询 - `idx_call_time`: 按调用时间查询 - `idx_feature_time`: 复合索引(feature_id + call_time) ### 2. Service层面 ✅ **文件:** `ycc-proxy-server/app/main/api/internal/service/tianyuanapiCallLogService.go` **新增方法:** 1. `RecordCall(ctx context.Context, opts CallLogOptions) error` - 记录API调用 - 自动获取feature的成本价 - 成功时记录成本,失败时成本为0 - 异步记录,不影响主流程 2. `GetStatistics(ctx context.Context, filter StatisticsFilter) (*Statistics, error)` - 获取统计信息 - 支持按feature_id、api_id、时间范围过滤 - 返回:总调用次数、成功次数、失败次数、总成本 ### 3. ApiRequestService修改 ✅ **文件:** `ycc-proxy-server/app/main/api/internal/service/apirequestService.go` **新增字段:** - `tianyuanapiCallLogService *TianyuanapiCallLogService` - `apiFeatureMapCache map[string]string` - apiID到featureID的缓存 - `apiFeatureMapMutex sync.RWMutex` - 缓存读写锁 **新增方法:** 1. `callTianyuanApiWithLog(ctx context.Context, featureID, apiID string, params map[string]interface{}) (*tianyuanapi.Response, error)` - 调用天元API - 记录调用开始时间 - 计算响应耗时 - 异步记录调用日志 - 返回响应和错误 2. 在 `ProcessRequests` 方法中构建 `apiID -> featureID` 映射缓存 **修改的方法(示例):** - `ProcessYYSYBE08Request` - 已修改 - `ProcessFLXG0V4BRequest` - 已修改 **待修改的方法(30个):** 剩余30个方法需要将 `a.callTianyuanApiWithLog(ctx, "", "API名称", ...)` 替换为 `a.callTianyuanApiWithLog(ctx, "", "API名称", ...)` 详细列表见:`批量替换API调用说明.md` ### 4. ServiceContext修改 ✅ **文件:** `ycc-proxy-server/app/main/api/internal/svc/servicecontext.go` **新增模型:** ```go TianyuanapiCallLogModel model.TianyuanapiCallLogModel TianyuanapiCallLogService *service.TianyuanapiCallLogService ``` **新增初始化:** ```go tianyuanapiCallLogModel := model.NewTianyuanapiCallLogModel(db, cacheConf) tianyuanapiCallLogService := service.NewTianyuanapiCallLogService(tianyuanapiCallLogModel, featureModel) ``` **修改ApiRequestService初始化:** ```go apiRequestService := service.NewApiRequestService( c, featureModel, productFeatureModel, userFeatureWhitelistModel, tianyuanapi, tianyuanapiCallLogService, // 新增参数 ) ``` ### 5. Model生成脚本 ✅ **文件:** `ycc-proxy-server/deploy/sql/generate_tianyuanapi_models.sh` **功能:** - 生成 `feature` 表的Model(已更新,包含cost_price字段) - 生成 `tianyuanapi_call_log` 表的Model ### 6. 文档 ✅ **已创建的文档:** 1. `天元API调用记录修改说明.md` - 详细的修改步骤和示例 2. `批量替换API调用说明.md` - 批量修改API调用方法的指南 ## 待完成的工作 ### 1. 执行SQL脚本 ⏳ ```bash # 在数据库中执行迁移脚本 mysql -u root -p ycc < ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql ``` ### 2. 生成Model代码 ⏳ ```bash cd ycc-proxy-server/deploy/sql bash generate_tianyuanapi_models.sh ``` 这将生成以下文件: - `app/main/model/featureModel_gen.go` (已更新,包含cost_price字段) - `app/main/model/featureModel.go` (已更新) - `app/main/model/tianyuanapiCallLogModel_gen.go` (新建) - `app/main/model/tianyuanapiCallLogModel.go` (新建) ### 3. 批量修改API调用方法 ⏳ **需要修改30个方法,将:** ```go resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{ ``` **替换为:** ```go ctx := context.Background() resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{ ``` **参考文档:** `批量替换API调用说明.md` **建议使用IDE批量替换功能:** 1. 打开 `apirequestService.go` 2. 按 `Ctrl+H` 打开查找替换 3. 查找:`a.callTianyuanApiWithLog(ctx, "", "` 4. 替换:`a.callTianyuanApiWithLog(ctx, "", "` 5. 全部替换 **然后手动在每个方法开头添加:** ```go ctx := context.Background() ``` ### 4. 编译验证 ⏳ ```bash cd ycc-proxy-server go build ./... ``` 检查是否有编译错误。 ### 5. 测试验证 ⏳ 1. 运行项目 2. 发起几个API请求(成功和失败各几次) 3. 检查 `tianyuanapi_call_log` 表,验证: - 记录是否正确插入 - 成功调用有正确的成本价 - 失败调用成本为0 - 响应耗时是否记录 - 错误信息是否正确 ### 6. 后台配置 ⏳ 在后台"功能管理"页面,为每个feature配置成本价: 1. 进入"功能管理" 2. 编辑某个功能 3. 设置"天元API调用成本价"字段 4. 保存 ## 统计功能使用示例 ```go // 获取某个功能在某个时间段的调用统计 filter := StatisticsFilter{ FeatureID: "feature-id-123", StartDate: time.Now().AddDate(0, 0, -30), // 30天前 EndDate: time.Now(), } stats, err := ctx.TianyuanapiCallLogService.GetStatistics(context.Background(), filter) if err == nil { fmt.Printf("总调用次数: %d\n", stats.TotalCalls) fmt.Printf("成功次数: %d\n", stats.SuccessCalls) fmt.Printf("失败次数: %d\n", stats.FailedCalls) fmt.Printf("总成本: %.2f元\n", stats.TotalCost) } ``` ## SQL查询示例 ### 查询某个接口的调用记录 ```sql SELECT * FROM tianyuanapi_call_log WHERE api_id = 'YYSYBE08' ORDER BY call_time DESC LIMIT 100; ``` ### 统计某天所有接口的调用情况 ```sql SELECT api_id, COUNT(*) as total_calls, SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls, SUM(CASE WHEN call_status = 0 THEN 1 ELSE 0 END) as failed_calls, SUM(cost_price) as total_cost FROM tianyuanapi_call_log WHERE DATE(call_time) = CURDATE() GROUP BY api_id; ``` ### 查询成功率最低的接口 ```sql SELECT api_id, COUNT(*) as total_calls, SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls, (SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) as success_rate FROM tianyuanapi_call_log WHERE call_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY api_id ORDER BY success_rate ASC LIMIT 10; ``` ## 注意事项 1. **成本价配置**:需要在后台为每个feature配置成本价,否则所有调用的成本都是0 2. **性能考虑**:调用日志采用异步记录,不影响API响应速度 3. **数据量控制**:response_data只记录前1000字符,避免存储过大 4. **缓存机制**:apiID到featureID的映射在 `ProcessRequests` 时构建,避免频繁查询数据库 5. **失败不收费**:根据需求,调用失败时天元API不收费,所以cost_price为0 ## 后续优化建议 1. **定时清理**:可以添加定时任务,定期清理超过一定时间的日志数据(如90天) 2. **成本预警**:可以添加监控,当某个时间段的总成本超过阈值时发送告警 3. **成功率监控**:监控各接口的成功率,低于阈值时告警 4. **性能分析**:分析响应时间,找出性能瓶颈 5. **数据归档**:将历史日志归档到其他存储,避免主表过大 ## 文件清单 ### 新增文件 1. `deploy/sql/tianyuanapi_cost_migration.sql` - 数据库迁移脚本 2. `deploy/sql/generate_tianyuanapi_models.sh` - Model生成脚本 3. `app/main/api/internal/service/tianyuanapiCallLogService.go` - 调用记录服务 4. `deploy/sql/天元API调用记录修改说明.md` - 详细修改说明 5. `deploy/sql/批量替换API调用说明.md` - 批量替换指南 6. `deploy/sql/天元API调用记录功能完成总结.md` - 本文档 ### 修改文件 1. `app/main/api/internal/service/apirequestService.go` - 添加调用记录逻辑 2. `app/main/api/internal/svc/servicecontext.go` - 添加新Model和Service初始化 ### 待生成文件(执行脚本后) 1. `app/main/model/featureModel_gen.go` - 已更新 2. `app/main/model/featureModel.go` - 已更新 3. `app/main/model/tianyuanapiCallLogModel_gen.go` - 新建 4. `app/main/model/tianyuanapiCallLogModel.go` - 新建