package reply import ( "aiweek/option" "aiweek/tools" "aiweek/udesk/auth" "aiweek/udesk/filter" "fmt" "github.com/PuerkitoBio/goquery" "github.com/tidwall/gjson" "github.com/xuri/excelize/v2" "io" "log" "net/http" "os" "path/filepath" "strconv" "strings" "sync" "time" ) //设置真正的id-content键值对。 func (e *Excel) SetReplyContent() *Excel { uDeskId := filter.GetWeeklyTicket() contentMap := make(map[string][]string) var wg sync.WaitGroup //计数器 j := 0 for _, v := range uDeskId { j++ wg.Add(1) log.Printf("goroutie%v:开始执行\n", j) time.Sleep(150 * time.Millisecond) go func(v string, j int) { defer wg.Done() idUrl := fmt.Sprintf("https://servicecenter-alauda.udesk.cn/open_api_v1/tickets/%v/replies?", v) repliesUrl := auth.Geturlstring(idUrl) resp, err := http.Get(repliesUrl) if err != nil { // 处理错误 log.Printf("获取工单过滤器下的回复信息失败,发送请求过程,错误是:%v\n", err) return } body, err := io.ReadAll(resp.Body) if err != nil { // 处理错误 log.Printf("获取工单过滤器下的回复信息失败,读取返回体过程,错误是:%v\n", err) return } defer resp.Body.Close() jsonData := string(body) //*查找回复内容和配图 repliesContent := gjson.Get(jsonData, "replies").Array() var s = make([]string, 0) //排除关于客户的回复 for _, v := range repliesContent { b := v.String() replyType := gjson.Get(b, "author.user_type").String() if replyType == "agent" { finalContent := gjson.Get(b, "content").String() doc, _ := goquery.NewDocumentFromReader(strings.NewReader(finalContent)) doc.Find("p,img").Each(func(i int, selection *goquery.Selection) { imgSrc, exists := selection.Attr("src") if exists { s = append(s, imgSrc) s = append(s, "\n") } s = append(s, selection.Text()) //排除掉宏的内容 macros := excludeMacros() s = tools.ExcludeSlice(macros, s) s = tools.RemoveEmptyStrings(s) s = append(s, "\n") }) } } repliesContentSlice := tools.ReverseSlice(s) repliesContentSlice = tools.RemoveNewlineElements(repliesContentSlice) repliesContentSlice = tools.AddNewlineToEachElement(repliesContentSlice) //跳过没有回复内容的工单。 if len(repliesContentSlice) == 0 { return } //工单id转换为cloudid cloudId := filter.Id2CloudId(v) if cloudId == "" { contentMap[v] = repliesContentSlice log.Printf("goroutine%v:回复内容处理完成,工单id(非cloudid是%v)", j, v) } else { contentMap[cloudId] = repliesContentSlice log.Printf("goroutine%v:回复内容处理完成,工单id(非cloudid是%v)", j, v) } log.Printf("goroutine%v结束\n", j) }(v, j) } wg.Wait() e.Reply.replyContent = contentMap return e } func (e *Excel) CreateNewExcel() { // 示例的 map // 创建一个新的 Excel 文件 f := excelize.NewFile() // 设置工作表的名称 index, err := f.NewSheet("Sheet1") if err != nil { log.Println("设置工作表名称失败,错误是:", err) return } // 在第一行,第一列写入标题 err = f.SetCellValue("Sheet1", "A1", "工单id") if err != nil { log.Println("写入A1标题失败,错误是:", err) return } err = f.SetCellValue("Sheet1", "B1", "工单回复") if err != nil { log.Println("写入B1标题失败,错误是:", err) return } //遍历 map,将键和值写入 Excel 表格 row := 2 for key, value := range e.Reply.replyContent { log.Println(row, key, value) err := f.SetCellValue("Sheet1", "A"+strconv.Itoa(row), key) if err != nil { log.Println("插入A行数据到excel实例中失败,错误是:", err) return } err = f.SetCellValue("Sheet1", "B"+strconv.Itoa(row), value) if err != nil { log.Println("插入B行数据到excel实例中失败,错误是:", err) return } row++ } // 设置工作表为默认激活状态 f.SetActiveSheet(index) // 保存 Excel 文件 if err := f.SaveAs(ExcelName); err != nil { log.Fatal(err) } wd, _ := os.Getwd() relPath := filepath.Join(wd, ExcelName) absPath, err := filepath.Abs(relPath) if err != nil { log.Printf("获取excel路径失败错误是:%v", err) } e.ExcelPath = absPath address := option.FILESERVER_ADDRESS + e.ExcelName e.ExcelAddress = address }