package tools_bot import ( errors "ai_scheduler/internal/data/error" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg" "ai_scheduler/internal/pkg/l_request" "context" "encoding/json" "fmt" "time" "github.com/gofiber/fiber/v2/log" "github.com/google/uuid" "xorm.io/builder" ) // BugOptimizationSubmitForm 工单提交表单参数 type BugOptimizationSubmitForm struct { Mark string `json:"mark"` // 工单标识 Text string `json:"text"` // 工单描述 Img string `json:"img"` // 工单截图 Creator string `json:"creator"` // 工单创建人 TaskId string `json:"task_id"` // 当初任务ID } const ( // 工单QA BotBugOptimizationSubmitQA = "温子新" BotBugOptimizationSubmitPM = "贺泽琨" // 管理员unionId - fzy BotBugOptimizationSubmitAdminUnionId = "uoCiPKNdFmuiSFmAiiXmmiSKpQiEiE" ) // BugOptimizationSubmit 工单提交 func (w *BotTool) BugOptimizationSubmit(ctx context.Context, requireData *entitys.RequireData) (err error) { // 获取用户信息 cond := builder.NewCond() cond = cond.And(builder.Eq{"session_id": requireData.Session}) sessionInfo, err := w.sessionImpl.GetOneBySearch(&cond) if err != nil { err = errors.SysErr("获取会话信息失败:%v", err.Error()) return } userName := sessionInfo["user_name"].(string) // 构建工单表单参数 body := BugOptimizationSubmitForm{ Mark: requireData.Match.Index, Text: requireData.Req.Text, Img: requireData.Req.Img, Creator: userName, TaskId: uuid.New().String(), } request := l_request.Request{ Url: "https://connector.dingtalk.com/webhook/flow/10352c521dd02104cee9000c", Method: "POST", Headers: map[string]string{ "Content-Type": "application/json", }, JsonByte: pkg.JsonByteIgonErr(body), } res, err := request.Send() if err != nil { log.Errorf("发送请求失败: %s", err.Error()) return } data := make(map[string]bool) if err = json.Unmarshal(res.Content, &data); err != nil { return fmt.Errorf("解析工单响应失败:%w", err) } if data["success"] { // 记录 task_id 到 session_id 的映射 w.SetTaskMapping(body.TaskId, requireData.Session) entitys.ResLog(requireData.Ch, requireData.Match.Index, "问题记录中") // 等待异步回调完成再结束 for { sessionID, ok := w.GetSessionByTaskID(body.TaskId) if !ok || sessionID != requireData.Session { break } entitys.ResLoading(requireData.Ch, requireData.Match.Index, "问题记录中...") time.Sleep(time.Second) } return } entitys.ResJson(requireData.Ch, requireData.Match.Index, fmt.Sprintf("bug问题请咨询 @%s ,优化建议请咨询 @%s 。", BotBugOptimizationSubmitQA, BotBugOptimizationSubmitPM)) return } // SetTaskMapping 设置 task_id 到 session_id 的映射(内存版)。 // 后续考虑使用 Redis,确保幂等与过期清理。 func (w *BotTool) SetTaskMapping(taskID, sessionID string) { if taskID == "" || sessionID == "" { return } w.taskMap[taskID] = sessionID } // GetSessionByTaskID 读取映射 func (w *BotTool) GetSessionByTaskID(taskID string) (string, bool) { v, ok := w.taskMap[taskID] return v, ok } // DelTaskMapping 删除 task_id 到 session_id 的映射(内存版)。 func (w *BotTool) DelTaskMapping(taskID string) { delete(w.taskMap, taskID) }