package reply import ( "aiweek/file" "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" ) //设置真正的id-content键值对。 func (r *Reply) SetReplyContent() (*Reply, error) { uDeskId := filter.GetWeeklyTicket() contentMap := make(map[string][]string) //计数器 j := 1 for _, v := range uDeskId { 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 nil, err } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { return } }(resp.Body) body, err := io.ReadAll(resp.Body) if err != nil { // 处理错误 log.Printf("获取工单过滤器下的回复信息失败,读取返回体过程,错误是:%v\n", err) return nil, err } 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 { continue } //工单id转换为cloudid cloudId := filter.Id2CloudId(v) log.Printf("正在处理map中的第%v个数据,键是%v\n", j, v) if cloudId == "" { contentMap[v] = repliesContentSlice } else { contentMap[cloudId] = repliesContentSlice } log.Printf("第%v个数据数据处理完成\n", j) j++ } r.replyContent = contentMap return r, nil } func (e *Excel) CreateNewExcel(reply *Reply) { // 示例的 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 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, _ := filepath.Abs(relPath) e.ExcelPath = absPath } func (e *Excel) SetAddress() { url := file.GetFileServerUrl() address := url + e.ExcelName e.ExcelAddress = address }