- 增加骆驼模块设置接口支持获取和更新配置 - 使用Redis缓存设置数据,实现模块配置的持久化管理 - 引入预拉取订单日志功能,支持日志的保存和按时间范围查询 - 预拉取订单请求响应数据记录到Redis,方便问题追踪 - 根据模块设置动态调整账号登录、预拉取订单并发数量 - 调整账号登录逻辑以支持配置的并发控制 - 优化预拉取订单补充流程,支持多面额库存管理 - 修正集成API请求函数名及调用,记录详细调用日志数据 - 调整定时任务调度频率,增加预拉取订单补充任务的执行频率 - 升级golang版本到1.25.5,保持开发环境最新状态
165 lines
4.5 KiB
Go
165 lines
4.5 KiB
Go
package camel_oil
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"time"
|
||
|
||
v1 "kami/api/camel_oil/v1"
|
||
"kami/utility/cache"
|
||
|
||
"github.com/gogf/gf/v2/errors/gerror"
|
||
"github.com/gogf/gf/v2/os/glog"
|
||
"github.com/gogf/gf/v2/os/gtime"
|
||
)
|
||
|
||
// GetPrefetchOrderLogs 获取预拉取订单日志
|
||
func (s *sCamelOil) GetPrefetchOrderLogs(ctx context.Context, req *v1.GetPrefetchOrderLogsReq) (res *v1.GetPrefetchOrderLogsRes, err error) {
|
||
// 计算时间范围跨度
|
||
duration := req.EndTime.Time.Sub(req.StartTime.Time)
|
||
if duration <= 0 {
|
||
return nil, gerror.New("结束时间必须大于开始时间")
|
||
}
|
||
|
||
// 限制查询时间范围不超过24小时
|
||
if duration.Hours() > 24 {
|
||
return nil, gerror.New("查询时间范围不能超过24小时")
|
||
}
|
||
|
||
glog.Infof(ctx, "获取预拉取订单日志,时间范围: %s - %s", req.StartTime.Format("Y-m-d H:i:s"), req.EndTime.Format("Y-m-d H:i:s"))
|
||
|
||
// Redis key 前缀
|
||
redisKeyPrefix := "camel_oil:prefetch:logs:"
|
||
|
||
var logs []v1.PrefetchOrderLogItem
|
||
|
||
// 遍历时间范围内的每一分钟
|
||
currentTime := req.StartTime.Time
|
||
for currentTime.Before(req.EndTime.Time) || currentTime.Equal(req.EndTime.Time) {
|
||
timeKey := currentTime.Format("2006-01-02_15:04")
|
||
redisKey := redisKeyPrefix + timeKey
|
||
|
||
// 从Redis获取日志数据
|
||
logData, err := cache.NewCache().Get(ctx, redisKey)
|
||
if err != nil {
|
||
glog.Warningf(ctx, "获取Redis日志失败,key: %s, error: %v", redisKey, err)
|
||
currentTime = currentTime.Add(time.Minute)
|
||
continue
|
||
}
|
||
|
||
if logData.IsEmpty() {
|
||
currentTime = currentTime.Add(time.Minute)
|
||
continue
|
||
}
|
||
|
||
// 解析日志数据
|
||
var minuteLogs []map[string]interface{}
|
||
if err := json.Unmarshal([]byte(logData.String()), &minuteLogs); err != nil {
|
||
glog.Warningf(ctx, "解析日志数据失败,key: %s, error: %v", redisKey, err)
|
||
currentTime = currentTime.Add(time.Minute)
|
||
continue
|
||
}
|
||
|
||
// 处理每条日志
|
||
for _, log := range minuteLogs {
|
||
// 提取面额
|
||
amount, ok := log["amount"].(float64)
|
||
if !ok {
|
||
continue
|
||
}
|
||
|
||
// 提取手机号
|
||
phone, ok := log["phone"].(string)
|
||
if !ok {
|
||
continue
|
||
}
|
||
|
||
// 提取时间戳
|
||
timestamp, ok := log["timestamp"].(string)
|
||
if !ok {
|
||
continue
|
||
}
|
||
|
||
// 提取响应数据
|
||
respStr, ok := log["resp_str"].(string)
|
||
if !ok {
|
||
respStr = ""
|
||
}
|
||
|
||
// 添加到结果列表,直接使用结构化字段
|
||
logs = append(logs, v1.PrefetchOrderLogItem{
|
||
Timestamp: timestamp,
|
||
Phone: phone,
|
||
Amount: amount,
|
||
ResponseData: respStr,
|
||
})
|
||
}
|
||
|
||
currentTime = currentTime.Add(time.Minute)
|
||
}
|
||
|
||
glog.Infof(ctx, "获取到预拉取订单日志 %d 条", len(logs))
|
||
|
||
// 返回结果
|
||
res = &v1.GetPrefetchOrderLogsRes{
|
||
Logs: logs,
|
||
}
|
||
|
||
return res, nil
|
||
}
|
||
|
||
// SavePrefetchOrderLog 保存预拉取订单请求日志到Redis
|
||
func (s *sCamelOil) SavePrefetchOrderLog(ctx context.Context, phone string, amount float64, respStr string) {
|
||
// 构建日志数据
|
||
logEntry := map[string]interface{}{
|
||
"timestamp": gtime.Now().Format("Y-m-d H:i:s"),
|
||
"phone": phone, // 实际使用时应该脱敏处理
|
||
"amount": amount,
|
||
"resp_str": respStr, // 保存响应数据
|
||
}
|
||
|
||
// 将日志数据序列化为JSON
|
||
logData, jsonErr := json.Marshal(logEntry)
|
||
if jsonErr != nil {
|
||
glog.Errorf(ctx, "序列化预拉取订单日志失败: %v", jsonErr)
|
||
return
|
||
}
|
||
|
||
// 生成Redis key (按分钟级别)
|
||
now := gtime.Now()
|
||
timeKey := now.Format("2006-01-02_15:04")
|
||
redisKey := fmt.Sprintf("camel_oil:prefetch:logs:%s", timeKey)
|
||
|
||
// 获取当前分钟已有的日志
|
||
var logs []map[string]interface{}
|
||
existingData, cacheErr := cache.NewCache().Get(ctx, redisKey)
|
||
if cacheErr == nil && !existingData.IsEmpty() {
|
||
if err := json.Unmarshal([]byte(existingData.String()), &logs); err != nil {
|
||
// 如果解析失败,创建新的日志数组
|
||
logs = []map[string]interface{}{}
|
||
}
|
||
}
|
||
|
||
// 添加新的日志
|
||
var newLog map[string]interface{}
|
||
if err := json.Unmarshal(logData, &newLog); err == nil {
|
||
logs = append(logs, newLog)
|
||
}
|
||
|
||
// 重新序列化并保存到Redis,设置1小时过期时间
|
||
updatedLogData, marshalErr := json.Marshal(logs)
|
||
if marshalErr != nil {
|
||
glog.Errorf(ctx, "重新序列化日志失败: %v", marshalErr)
|
||
return
|
||
}
|
||
|
||
// 使用cache包保存到Redis
|
||
if cacheErr := cache.NewCache().Set(ctx, redisKey, string(updatedLogData), time.Hour); cacheErr != nil {
|
||
glog.Errorf(ctx, "保存预拉取订单日志到Redis失败: %v", cacheErr)
|
||
return
|
||
}
|
||
|
||
// 记录到应用日志
|
||
glog.Infof(ctx, "保存预拉取订单日志 - 手机号: %s, 金额: %.2f", phone, amount)
|
||
} |