diff --git a/config/config_test.yaml b/config/config_test.yaml index 4ebccb8..85a7eb1 100644 --- a/config/config_test.yaml +++ b/config/config_test.yaml @@ -71,6 +71,10 @@ tools: zltxOrderAfterSaleResellerBatch: enabled: true base_url: "https://gateway.dev.cdlsxd.cn/zltx_api/admin/afterSales/reseller_pre_ai" + weather: + enabled: true + base_url: "https://restapi.amap.com/v3/weather/weatherInfo" + api_key: "12afbde5ab78cb7e575ff76bd0bdef2b" diff --git a/internal/biz/do/ctx.go b/internal/biz/do/ctx.go index d252c47..1c577ed 100644 --- a/internal/biz/do/ctx.go +++ b/internal/biz/do/ctx.go @@ -131,7 +131,8 @@ func (d *Do) loadSystemInfo(ctx context.Context, client *gateway.Client, require // 获取任务列表的辅助函数 func (d *Do) loadTaskList(ctx context.Context, client *gateway.Client, requireData *entitys.RequireData) error { if taskInfo := client.GetTasks(); len(taskInfo) == 0 { - tasks, err := d.GetTasks(requireData.Sys.SysID) + // 从数据库获取任务列表, 0 表示获取公共的任务 + tasks, err := d.GetTasks(requireData.Sys.SysID, 0) if err != nil { return err } @@ -140,6 +141,7 @@ func (d *Do) loadTaskList(ctx context.Context, client *gateway.Client, requireDa } else { requireData.Tasks = taskInfo } + return nil } @@ -242,12 +244,12 @@ func (d *Do) getSessionChatHis(requireData *entitys.RequireData) (his []model.Ai return } -func (d *Do) GetTasks(sysId int32) (tasks []model.AiTask, err error) { +func (d *Do) GetTasks(sysId ...int32) (tasks []model.AiTask, err error) { cond := builder.NewCond() - cond = cond.And(builder.Eq{"sys_id": sysId}) + //cond = cond.And(builder.Eq{"sys_id": sysId}) cond = cond.And(builder.IsNull{"delete_at"}) - cond = cond.And(builder.Eq{"status": 1}) + cond = cond.And(builder.Eq{"status": 1}.And(builder.In("sys_id", sysId))) _, err = d.taskImpl.GetListToStruct(&cond, nil, &tasks, "") return diff --git a/internal/biz/do/handle.go b/internal/biz/do/handle.go index 2e2a313..65eeeea 100644 --- a/internal/biz/do/handle.go +++ b/internal/biz/do/handle.go @@ -12,6 +12,7 @@ import ( "ai_scheduler/internal/pkg/l_request" "ai_scheduler/internal/pkg/mapstructure" "ai_scheduler/internal/tools" + "ai_scheduler/internal/tools/public" "ai_scheduler/internal/tools_bot" "context" "encoding/json" @@ -182,7 +183,7 @@ func (r *Handle) handleKnowle(ctx context.Context, requireData *entitys.RequireD return fmt.Errorf("tool not found: %s", configData.Tool) } - if knowledgeTool, ok := tool.(*tools.KnowledgeBaseTool); !ok { + if knowledgeTool, ok := tool.(*public.KnowledgeBaseTool); !ok { return fmt.Errorf("未找到知识库Tool: %s", configData.Tool) } else { host = knowledgeTool.GetConfig().BaseURL @@ -193,7 +194,7 @@ func (r *Handle) handleKnowle(ctx context.Context, requireData *entitys.RequireD // 知识库的session为空,请求知识库获取, 并绑定 if requireData.SessionInfo.KnowlegeSessionID == "" { // 请求知识库 - if sessionIdKnowledge, err = tools.GetKnowledgeBaseSession(host, requireData.Sys.KnowlegeBaseID, requireData.Sys.KnowlegeTenantKey); err != nil { + if sessionIdKnowledge, err = public.GetKnowledgeBaseSession(host, requireData.Sys.KnowlegeBaseID, requireData.Sys.KnowlegeTenantKey); err != nil { return } diff --git a/internal/tools/calculator.go b/internal/tools/calculator.go deleted file mode 100644 index fecde64..0000000 --- a/internal/tools/calculator.go +++ /dev/null @@ -1,121 +0,0 @@ -package tools - -import ( - "ai_scheduler/internal/entitys" - - "context" - "encoding/json" - "fmt" - "math" -) - -// CalculatorTool 计算器工具 -type CalculatorTool struct{} - -// NewCalculatorTool 创建计算器工具 -func NewCalculatorTool() *CalculatorTool { - return &CalculatorTool{} -} - -// Name 返回工具名称 -func (c *CalculatorTool) Name() string { - return "calculate" -} - -// Description 返回工具描述 -func (c *CalculatorTool) Description() string { - return "执行基本的数学运算,支持加减乘除和幂运算" -} - -// Definition 返回工具定义 -func (c *CalculatorTool) Definition() entitys.ToolDefinition { - return entitys.ToolDefinition{ - Type: "function", - Function: entitys.FunctionDef{ - Name: c.Name(), - Description: c.Description(), - Parameters: map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "operation": map[string]interface{}{ - "type": "string", - "description": "运算类型", - "enum": []string{"add", "subtract", "multiply", "divide", "power"}, - }, - "a": map[string]interface{}{ - "type": "number", - "description": "第一个数字", - }, - "b": map[string]interface{}{ - "type": "number", - "description": "第二个数字", - }, - }, - "required": []string{"operation", "a", "b"}, - }, - }, - } -} - -// CalculateRequest 计算请求参数 -type CalculateRequest struct { - Operation string `json:"operation"` - A float64 `json:"a"` - B float64 `json:"b"` -} - -// CalculateResponse 计算响应 -type CalculateResponse struct { - Operation string `json:"operation"` - A float64 `json:"a"` - B float64 `json:"b"` - Result float64 `json:"result"` - Expression string `json:"expression"` -} - -// Execute 执行计算 -func (c *CalculatorTool) Execute(ctx context.Context, args json.RawMessage) (interface{}, error) { - var req CalculateRequest - if err := json.Unmarshal(args, &req); err != nil { - return nil, fmt.Errorf("invalid calculate request: %w", err) - } - - var result float64 - var expression string - - switch req.Operation { - case "add": - result = req.A + req.B - expression = fmt.Sprintf("%.2f + %.2f = %.2f", req.A, req.B, result) - case "subtract": - result = req.A - req.B - expression = fmt.Sprintf("%.2f - %.2f = %.2f", req.A, req.B, result) - case "multiply": - result = req.A * req.B - expression = fmt.Sprintf("%.2f × %.2f = %.2f", req.A, req.B, result) - case "divide": - if req.B == 0 { - return nil, fmt.Errorf("division by zero is not allowed") - } - result = req.A / req.B - expression = fmt.Sprintf("%.2f ÷ %.2f = %.2f", req.A, req.B, result) - case "power": - result = math.Pow(req.A, req.B) - expression = fmt.Sprintf("%.2f ^ %.2f = %.2f", req.A, req.B, result) - default: - return nil, fmt.Errorf("unsupported operation: %s", req.Operation) - } - - // 检查结果是否有效 - if math.IsNaN(result) || math.IsInf(result, 0) { - return nil, fmt.Errorf("calculation resulted in invalid number") - } - - return &CalculateResponse{ - Operation: req.Operation, - A: req.A, - B: req.B, - Result: result, - Expression: expression, - }, nil -} diff --git a/internal/tools/manager.go b/internal/tools/manager.go index 2ebbb69..87212b7 100644 --- a/internal/tools/manager.go +++ b/internal/tools/manager.go @@ -5,6 +5,7 @@ import ( "ai_scheduler/internal/data/constants" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/utils_ollama" + "ai_scheduler/internal/tools/public" zltxtool "ai_scheduler/internal/tools/zltx" "context" @@ -44,30 +45,30 @@ func NewManager(config *config.Config, llm *utils_ollama.Client) *Manager { // 注册直连天下订单详情工具 if config.Tools.ZltxOrderDetail.Enabled { - zltxOrderDetailTool := NewZltxOrderDetailTool(config.Tools.ZltxOrderDetail, m.llm) + zltxOrderDetailTool := zltxtool.NewZltxOrderDetailTool(config.Tools.ZltxOrderDetail, m.llm) m.tools[zltxOrderDetailTool.Name()] = zltxOrderDetailTool } //注册直连天下订单日志工具 if config.Tools.ZltxOrderDirectLog.Enabled { - zltxOrderLogTool := NewZltxOrderLogTool(config.Tools.ZltxOrderDirectLog) + zltxOrderLogTool := zltxtool.NewZltxOrderLogTool(config.Tools.ZltxOrderDirectLog) m.tools[zltxOrderLogTool.Name()] = zltxOrderLogTool } //注册直连天下商品工具 if config.Tools.ZltxProduct.Enabled { - zltxProductTool := NewZltxProductTool(config.Tools.ZltxProduct) + zltxProductTool := zltxtool.NewZltxProductTool(config.Tools.ZltxProduct) m.tools[zltxProductTool.Name()] = zltxProductTool } //注册直连天下订单统计工具 if config.Tools.ZltxOrderStatistics.Enabled { - zltxOrderStatisticsTool := NewZltxOrderStatisticsTool(config.Tools.ZltxOrderStatistics) + zltxOrderStatisticsTool := zltxtool.NewZltxOrderStatisticsTool(config.Tools.ZltxOrderStatistics) m.tools[zltxOrderStatisticsTool.Name()] = zltxOrderStatisticsTool } // 注册知识库工具 if config.Tools.Knowledge.Enabled { - knowledgeTool := NewKnowledgeBaseTool(config.Tools.Knowledge) + knowledgeTool := public.NewKnowledgeBaseTool(config.Tools.Knowledge) m.tools[knowledgeTool.Name()] = knowledgeTool } @@ -86,9 +87,14 @@ func NewManager(config *config.Config, llm *utils_ollama.Client) *Manager { zltxOrderAfterSaleResellerBatchTool := zltxtool.NewOrderAfterSaleResellerBatchTool(config.Tools.ZltxOrderAfterSaleResellerBatch) m.tools[zltxOrderAfterSaleResellerBatchTool.Name()] = zltxOrderAfterSaleResellerBatchTool } + // 注册天气工具 + if config.Tools.Weather.Enabled { + weatherTool := public.NewWeatherTool(config.Tools.Weather) + m.tools[weatherTool.Name()] = weatherTool + } // 普通对话 - chat := NewNormalChatTool(m.llm, config) + chat := public.NewNormalChatTool(m.llm, config) m.tools[chat.Name()] = chat return m diff --git a/internal/tools/konwledge_base.go b/internal/tools/public/konwledge_base.go similarity index 99% rename from internal/tools/konwledge_base.go rename to internal/tools/public/konwledge_base.go index dbbb5ce..505a349 100644 --- a/internal/tools/konwledge_base.go +++ b/internal/tools/public/konwledge_base.go @@ -1,4 +1,4 @@ -package tools +package public import ( "ai_scheduler/internal/config" diff --git a/internal/tools/konwledge_base_test.go b/internal/tools/public/konwledge_base_test.go similarity index 97% rename from internal/tools/konwledge_base_test.go rename to internal/tools/public/konwledge_base_test.go index de1ab3f..0838587 100644 --- a/internal/tools/konwledge_base_test.go +++ b/internal/tools/public/konwledge_base_test.go @@ -1,4 +1,4 @@ -package tools +package public import ( "testing" diff --git a/internal/tools/normal_chat.go b/internal/tools/public/normal_chat.go similarity index 99% rename from internal/tools/normal_chat.go rename to internal/tools/public/normal_chat.go index 56010fc..a4c96e0 100644 --- a/internal/tools/normal_chat.go +++ b/internal/tools/public/normal_chat.go @@ -1,4 +1,4 @@ -package tools +package public import ( "ai_scheduler/internal/config" diff --git a/internal/tools/public/weather.go b/internal/tools/public/weather.go new file mode 100644 index 0000000..0292fa4 --- /dev/null +++ b/internal/tools/public/weather.go @@ -0,0 +1,345 @@ +package public + +import ( + "ai_scheduler/internal/config" + "ai_scheduler/internal/entitys" + "ai_scheduler/internal/pkg/l_request" + "log" + "strconv" + + "context" + "encoding/json" + "fmt" + "time" +) + +// WeatherTool 天气查询工具 +type WeatherTool struct { + mockData bool + config config.ToolConfig +} + +// NewWeatherTool 创建天气工具 +func NewWeatherTool(config config.ToolConfig) *WeatherTool { + return &WeatherTool{config: config} +} + +// Name 返回工具名称 +func (w *WeatherTool) Name() string { + return "get_weather" +} + +// Description 返回工具描述 +func (w *WeatherTool) Description() string { + return "获取指定城市的天气信息" +} + +// Definition 返回工具定义 +func (w *WeatherTool) Definition() entitys.ToolDefinition { + return entitys.ToolDefinition{ + Type: "function", + Function: entitys.FunctionDef{ + Name: w.Name(), + Description: w.Description(), + Parameters: map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "city": map[string]interface{}{ + "type": "string", + "description": "城市名称,如:北京、上海、广州", + }, + "unit": map[string]interface{}{ + "type": "string", + "description": "温度单位,celsius(摄氏度)或fahrenheit(华氏度)", + "enum": []string{"celsius", "fahrenheit"}, + "default": "celsius", + }, + "extensions": map[string]interface{}{ + "type": "string", + "description": "扩展参数,base/all base:返回实况天气 all:返回预报天气", + "enum": []string{"base", "all"}, + "default": "base", + }, + }, + "required": []string{"city"}, + }, + }, + } +} + +// WeatherRequest 天气请求参数 +type WeatherRequest struct { + City string `json:"city"` + Extensions string `json:"extensions"` // 扩展参数,base/all base:返回实况天气 all:返回预报天气 + Unit string `json:"unit,omitempty"` +} + +// WeatherResponse 天气响应 +type WeatherResponse struct { + City string `json:"city"` + Unit string `json:"unit"` + Timestamp string `json:"timestamp"` + LiveWeather *LiveWeather `json:"live_weather,omitempty"` // 实时天气 + Forecasts []ForecastWeather `json:"forecasts,omitempty"` // 预报天气 +} + +// ForecastWeather 预报天气 +type ForecastWeather struct { + Date string `json:"date"` + Week string `json:"week"` + DayWeather string `json:"day_weather"` + NightWeather string `json:"night_weather"` + DayTemp float64 `json:"day_temp"` + NightTemp float64 `json:"night_temp"` + DayWind string `json:"day_wind"` + NightWind string `json:"night_wind"` + DayWindPower string `json:"day_wind_power"` + NightWindPower string `json:"night_wind_power"` +} + +// LiveWeather 实时天气 +type LiveWeather struct { + Temperature float64 `json:"temperature"` + Condition string `json:"condition"` + Humidity int `json:"humidity"` + WindSpeed float64 `json:"wind_speed"` + WindDirection string `json:"wind_direction"` +} + +// Execute 执行天气查询 +func (w *WeatherTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { + var req WeatherRequest + if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { + return fmt.Errorf("invalid weather request: %w", err) + } + + if req.City == "" { + return fmt.Errorf("city is required") + } + + if req.Unit == "" { + req.Unit = "celsius" + } + + // 设置默认获取实时天气信息 + if req.Extensions == "" { + req.Extensions = "base" + } + + // 这里可以集成真实的天气API + responseMsg, err := w.getRealWeather(req) + if err != nil { + return fmt.Errorf("failed to get real weather: %w", err) + } + + // 根据 extensions 参数返回不同的天气信息 + if req.Extensions == "base" { + entitys.ResText(requireData.Ch, "", fmt.Sprintf("%s实时天气:%s,温度:%.1f℃,湿度:%d%%,风速:%.1fkm/h,风向:%s", + req.City, + responseMsg.LiveWeather.Condition, + responseMsg.LiveWeather.Temperature, + responseMsg.LiveWeather.Humidity, + responseMsg.LiveWeather.WindSpeed, + responseMsg.LiveWeather.WindDirection)) + } else { + + rspStr := fmt.Sprintf("%s天气预报:\n", req.City) + for _, forecast := range responseMsg.Forecasts { + rspStr += fmt.Sprintf("%s 温度:%.1f℃/%.1f℃ 风力:%s %s\n", + forecast.Date, forecast.DayTemp, forecast.NightTemp, forecast.DayWind, forecast.NightWind) + } + + entitys.ResText(requireData.Ch, "", rspStr) + } + return nil +} + +//// getMockWeather 获取模拟天气数据 +//func (w *WeatherTool) getMockWeather(city, unit string) *WeatherResponse { +// rand.Seed(time.Now().UnixNano()) +// +// // 模拟不同城市的基础温度 +// baseTemp := map[string]float64{ +// "北京": 15.0, +// "上海": 18.0, +// "广州": 25.0, +// "深圳": 26.0, +// "杭州": 17.0, +// "成都": 16.0, +// } +// +// temp := baseTemp[city] +// if temp == 0 { +// temp = 20.0 // 默认温度 +// } +// +// // 添加随机变化 +// temp += (rand.Float64() - 0.5) * 10 +// +// // 转换温度单位 +// if unit == "fahrenheit" { +// temp = temp*9/5 + 32 +// } +// +// conditions := []string{"晴朗", "多云", "阴天", "小雨", "中雨"} +// condition := conditions[rand.Intn(len(conditions))] +// +// return &WeatherResponse{ +// City: city, +// Temperature: float64(int(temp*10)) / 10, // 保留一位小数 +// Unit: unit, +// Condition: condition, +// Humidity: rand.Intn(40) + 40, // 40-80% +// WindSpeed: float64(rand.Intn(20)) + 1.0, +// Timestamp: time.Now().Format("2006-01-02 15:04:05"), +// } +//} + +// getRealWeather 调用高德天气API +func (w *WeatherTool) getRealWeather(request WeatherRequest) (*WeatherResponse, error) { + // 构建请求URL + req := l_request.Request{ + Url: w.config.BaseURL, + Headers: map[string]string{}, + Params: map[string]string{ + "city": request.City, // 城市名称 + "key": w.config.APIKey, // API密钥 + // extensions: 基础天气数据 可选值:base/all base:返回实况天气 all:返回预报天气 + "extensions": request.Extensions, // 基础天气数据 + "output": "JSON", // JSON格式返回 + }, + Method: "GET", + } + res, err := req.Send() + if err != nil { + return nil, err + } + + // 解析API响应 + var apiResp struct { + Status string `json:"status"` + Count string `json:"count"` + Info string `json:"info"` + Infocode string `json:"infocode"` + + // 预报天气信息数据 + Forecasts []struct { + City string `json:"city"` + Adcode string `json:"adcode"` + Province string `json:"province"` + Reporttime string `json:"reporttime"` + Casts []struct { + Date string `json:"date"` + Week string `json:"week"` + Dayweather string `json:"dayweather"` + Nightweather string `json:"nightweather"` + Daytemp string `json:"daytemp"` + Nighttemp string `json:"nighttemp"` + Daywind string `json:"daywind"` + Nightwind string `json:"nightwind"` + Daypower string `json:"daypower"` + Nightpower string `json:"nightpower"` + DaytempFloat string `json:"daytemp_float"` + NighttempFloat string `json:"nighttemp_float"` + } `json:"casts"` + } `json:"forecasts"` + // 实况天气信息数据 + Lives []struct { + Province string `json:"province"` + City string `json:"city"` + Adcode string `json:"adcode"` + Weather string `json:"weather"` + Temperature string `json:"temperature"` + Winddirection string `json:"winddirection"` + Windpower string `json:"windpower"` + Humidity string `json:"humidity"` + Reporttime string `json:"reporttime"` + TemperatureFloat string `json:"temperature_float"` + HumidityFloat string `json:"humidity_float"` + } `json:"lives"` + } + + log.Printf("weather API response: %s", string(res.Content)) + + if err = json.Unmarshal(res.Content, &apiResp); err != nil { + return nil, fmt.Errorf("parse weather API response failed: %w", err) + } + + // 检查API返回状态 + if apiResp.Status != "1" { + return nil, fmt.Errorf("weather API returned error: %s, info: %s", apiResp.Status, apiResp.Info) + } + + // 获取城市名称 + cityName := "" + if len(apiResp.Lives) > 0 { + cityName = apiResp.Lives[0].City + } else if len(apiResp.Forecasts) > 0 { + cityName = apiResp.Forecasts[0].City + } else { + return nil, fmt.Errorf("no weather data found") + } + + // 构建响应 + response := &WeatherResponse{ + City: cityName, + Unit: request.Unit, + Timestamp: time.Now().Format("2006-01-02 15:04:05"), + } + // 处理实时天气 + if len(apiResp.Lives) > 0 { + liveData := apiResp.Lives[0] + + // 转换温度 + temp, _ := strconv.ParseFloat(liveData.Temperature, 64) + if request.Unit == "fahrenheit" { + temp = temp*9/5 + 32 + } + + // 转换湿度和风速 + humidity, _ := strconv.Atoi(liveData.Humidity) + windSpeed, _ := strconv.ParseFloat(liveData.Windpower, 64) + + response.LiveWeather = &LiveWeather{ + Temperature: temp, + Condition: liveData.Weather, + Humidity: humidity, + WindSpeed: windSpeed, + WindDirection: liveData.Winddirection, + } + } + + // 处理预报天气 + if len(apiResp.Forecasts) > 0 && len(apiResp.Forecasts[0].Casts) > 0 { + response.Forecasts = make([]ForecastWeather, 0, len(apiResp.Forecasts[0].Casts)) + + for _, cast := range apiResp.Forecasts[0].Casts { + // 转换温度 + dayTemp, _ := strconv.ParseFloat(cast.Daytemp, 64) + nightTemp, _ := strconv.ParseFloat(cast.Nighttemp, 64) + + if request.Unit == "fahrenheit" { + dayTemp = dayTemp*9/5 + 32 + nightTemp = nightTemp*9/5 + 32 + } + + forecast := ForecastWeather{ + Date: cast.Date, + Week: cast.Week, + DayWeather: cast.Dayweather, + NightWeather: cast.Nightweather, + DayTemp: dayTemp, + NightTemp: nightTemp, + DayWind: cast.Daywind, + NightWind: cast.Nightwind, + DayWindPower: cast.Daypower, + NightWindPower: cast.Nightpower, + } + + response.Forecasts = append(response.Forecasts, forecast) + } + } + + return response, nil + +} diff --git a/internal/tools/weather.go b/internal/tools/weather.go deleted file mode 100644 index 744216f..0000000 --- a/internal/tools/weather.go +++ /dev/null @@ -1,139 +0,0 @@ -package tools - -import ( - "ai_scheduler/internal/entitys" - - "context" - "encoding/json" - "fmt" - "math/rand" - "time" -) - -// WeatherTool 天气查询工具 -type WeatherTool struct { - mockData bool -} - -// NewWeatherTool 创建天气工具 -func NewWeatherTool() *WeatherTool { - return &WeatherTool{} -} - -// Name 返回工具名称 -func (w *WeatherTool) Name() string { - return "get_weather" -} - -// Description 返回工具描述 -func (w *WeatherTool) Description() string { - return "获取指定城市的天气信息" -} - -// Definition 返回工具定义 -func (w *WeatherTool) Definition() entitys.ToolDefinition { - return entitys.ToolDefinition{ - Type: "function", - Function: entitys.FunctionDef{ - Name: w.Name(), - Description: w.Description(), - Parameters: map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "city": map[string]interface{}{ - "type": "string", - "description": "城市名称,如:北京、上海、广州", - }, - "unit": map[string]interface{}{ - "type": "string", - "description": "温度单位,celsius(摄氏度)或fahrenheit(华氏度)", - "enum": []string{"celsius", "fahrenheit"}, - "default": "celsius", - }, - }, - "required": []string{"city"}, - }, - }, - } -} - -// WeatherRequest 天气请求参数 -type WeatherRequest struct { - City string `json:"city"` - Unit string `json:"unit,omitempty"` -} - -// WeatherResponse 天气响应 -type WeatherResponse struct { - City string `json:"city"` - Temperature float64 `json:"temperature"` - Unit string `json:"unit"` - Condition string `json:"condition"` - Humidity int `json:"humidity"` - WindSpeed float64 `json:"wind_speed"` - Timestamp string `json:"timestamp"` -} - -// Execute 执行天气查询 -func (w *WeatherTool) Execute(ctx context.Context, args json.RawMessage) (interface{}, error) { - var req WeatherRequest - if err := json.Unmarshal(args, &req); err != nil { - return nil, fmt.Errorf("invalid weather request: %w", err) - } - - if req.City == "" { - return nil, fmt.Errorf("city is required") - } - - if req.Unit == "" { - req.Unit = "celsius" - } - - if w.mockData { - return w.getMockWeather(req.City, req.Unit), nil - } - - // 这里可以集成真实的天气API - return w.getMockWeather(req.City, req.Unit), nil -} - -// getMockWeather 获取模拟天气数据 -func (w *WeatherTool) getMockWeather(city, unit string) *WeatherResponse { - rand.Seed(time.Now().UnixNano()) - - // 模拟不同城市的基础温度 - baseTemp := map[string]float64{ - "北京": 15.0, - "上海": 18.0, - "广州": 25.0, - "深圳": 26.0, - "杭州": 17.0, - "成都": 16.0, - } - - temp := baseTemp[city] - if temp == 0 { - temp = 20.0 // 默认温度 - } - - // 添加随机变化 - temp += (rand.Float64() - 0.5) * 10 - - // 转换温度单位 - if unit == "fahrenheit" { - temp = temp*9/5 + 32 - } - - conditions := []string{"晴朗", "多云", "阴天", "小雨", "中雨"} - condition := conditions[rand.Intn(len(conditions))] - - return &WeatherResponse{ - City: city, - Temperature: float64(int(temp*10)) / 10, // 保留一位小数 - Unit: unit, - Condition: condition, - Humidity: rand.Intn(40) + 40, // 40-80% - WindSpeed: float64(rand.Intn(20)) + 1.0, - Timestamp: time.Now().Format("2006-01-02 15:04:05"), - } -} diff --git a/internal/tools/zltx_after_direct.go b/internal/tools/zltx/zltx_after_direct.go similarity index 99% rename from internal/tools/zltx_after_direct.go rename to internal/tools/zltx/zltx_after_direct.go index 5f1e20e..01a6282 100644 --- a/internal/tools/zltx_after_direct.go +++ b/internal/tools/zltx/zltx_after_direct.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config" diff --git a/internal/tools/zltx_after_pre.go b/internal/tools/zltx/zltx_after_pre.go similarity index 99% rename from internal/tools/zltx_after_pre.go rename to internal/tools/zltx/zltx_after_pre.go index b44812b..5bbf809 100644 --- a/internal/tools/zltx_after_pre.go +++ b/internal/tools/zltx/zltx_after_pre.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config" diff --git a/internal/tools/zltx_order_detail.go b/internal/tools/zltx/zltx_order_detail.go similarity index 99% rename from internal/tools/zltx_order_detail.go rename to internal/tools/zltx/zltx_order_detail.go index f253f59..7dae9f1 100644 --- a/internal/tools/zltx_order_detail.go +++ b/internal/tools/zltx/zltx_order_detail.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config" diff --git a/internal/tools/zltx_order_direct_log.go b/internal/tools/zltx/zltx_order_direct_log.go similarity index 99% rename from internal/tools/zltx_order_direct_log.go rename to internal/tools/zltx/zltx_order_direct_log.go index bf82408..b1b1483 100644 --- a/internal/tools/zltx_order_direct_log.go +++ b/internal/tools/zltx/zltx_order_direct_log.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config" diff --git a/internal/tools/zltx_product.go b/internal/tools/zltx/zltx_product.go similarity index 99% rename from internal/tools/zltx_product.go rename to internal/tools/zltx/zltx_product.go index 61b8bb1..de24236 100644 --- a/internal/tools/zltx_product.go +++ b/internal/tools/zltx/zltx_product.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config" diff --git a/internal/tools/zltx_statistics.go b/internal/tools/zltx/zltx_statistics.go similarity index 99% rename from internal/tools/zltx_statistics.go rename to internal/tools/zltx/zltx_statistics.go index f53d4b1..4a051a8 100644 --- a/internal/tools/zltx_statistics.go +++ b/internal/tools/zltx/zltx_statistics.go @@ -1,4 +1,4 @@ -package tools +package zltx import ( "ai_scheduler/internal/config"