123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- package services
- import (
- "encoding/json"
- "eta/eta_report/utils"
- "fmt"
- html2 "golang.org/x/net/html"
- "net/url"
- "strings"
- "time"
- )
- // HandleReportContent
- // @Description: 处理报告内容(动态图表/表格添加授权token)
- // @author: Roc
- // @datetime 2025-01-07 10:03:15
- // @param body string
- // @return newBody string
- func HandleReportContent(body string, opType string, tokenMap map[string]string) (newBody string) {
- if body == `` {
- return
- }
- newBody = body
- // 解析HTML
- doc, err := html2.Parse(strings.NewReader(body))
- if err != nil {
- fmt.Println("Error parsing HTML:", err)
- return
- }
- replaceIframeSrc(doc, opType, tokenMap)
- // 输出修改后的HTML
- var modifiedHtml strings.Builder
- err = html2.Render(&modifiedHtml, doc)
- if err != nil {
- fmt.Println("Error rendering HTML:", err)
- return
- }
- newBody = modifiedHtml.String()
- fmt.Println(newBody)
- return
- }
- // replaceIframeSrc 遍历HTML节点,替换iframe的src属性
- func replaceIframeSrc(n *html2.Node, opType string, tokenMap map[string]string) {
- if n.Type == html2.ElementNode && n.Data == "iframe" {
- for i, attr := range n.Attr {
- if attr.Key == "src" {
- newLink := attr.Val
- // 处理链接
- switch opType {
- case `add`:
- newLink = linkAddToken(attr.Val, tokenMap)
- case `del`:
- newLink = linkDelToken(attr.Val)
- }
- // 替换原来的链接
- n.Attr[i].Val = newLink
- break
- }
- }
- }
- // 递归处理子节点
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- replaceIframeSrc(c, opType, tokenMap)
- }
- }
- // linkAddToken 链接添加token
- func linkAddToken(link string, tokenMap map[string]string) string {
- var err error
- defer func() {
- if err != nil {
- utils.FileLog.Info("处理链接失败,ERR:" + err.Error())
- }
- }()
- parsedURL, err := url.Parse(link)
- if err != nil {
- return link
- }
- // 获取查询参数
- queryParams := parsedURL.Query()
- // 先移除authToken参数,避免莫名其妙的这个值入库了
- queryParams.Del("authToken")
- // 获取code参数
- code := queryParams.Get("code")
- if code == "" {
- return link
- }
- showType := `chart`
- if strings.Contains(parsedURL.Path, "sheetshow") {
- showType = `excel`
- }
- // 避免报告里面一个图表/表格重复生成token
- key := fmt.Sprint(showType, `:`, code)
- if tokenMap != nil {
- if token, ok := tokenMap[key]; ok {
- // 在链接后面添加一个token值
- return link + "&authToken=" + token
- }
- }
- token, err := GeneralChartToken(showType, code, 30*time.Minute)
- if err != nil {
- return link
- }
- if tokenMap != nil {
- tokenMap[key] = token
- }
- // 在链接后面添加一个token值
- return link + "&authToken=" + token
- }
- // linkDelToken 链接添加token
- func linkDelToken(link string) string {
- var err error
- defer func() {
- if err != nil {
- utils.FileLog.Info("处理链接失败,ERR:" + err.Error())
- }
- }()
- parsedURL, err := url.Parse(link)
- if err != nil {
- return link
- }
- // 获取查询参数
- queryParams := parsedURL.Query()
- // 移除authToken参数
- queryParams.Del("authToken")
- // 更新URL的查询参数
- parsedURL.RawQuery = queryParams.Encode()
- return parsedURL.String()
- }
- // GeneralChartToken
- // @Description: 生产图表/表格授权token
- // @author: Roc
- // @datetime 2025-01-07 10:41:36
- // @param showType string
- // @param uniqueCode string
- // @param expireTime time.Duration
- // @return token string
- // @return err error
- func GeneralChartToken(showType, uniqueCode string, expireTime time.Duration) (token string, err error) {
- // 缓存key
- token = utils.MD5(fmt.Sprint(showType+`:`, uniqueCode, time.Now().UnixNano()/1e6))
- key := fmt.Sprint(utils.CACHE_CHART_AUTH, token)
- err = utils.Rc.Put(key, uniqueCode, expireTime)
- return
- }
- // HandleReportContentStruct
- // @Description: 处理内容组件的链接
- // @author: Roc
- // @datetime 2025-01-07 13:38:39
- // @param body string
- // @param opType string
- // @return newBody string
- func HandleReportContentStruct(body string, opType string, tokenMap map[string]string) (newBody string) {
- if body == `` {
- return
- }
- newBody = body
- // 解析JSON数据到map[string]interface{}
- var jsonData []map[string]interface{}
- if err := json.Unmarshal([]byte(body), &jsonData); err != nil {
- fmt.Println("Error parsing JSON:", err)
- return
- }
- // 处理每个组件
- for i := range jsonData {
- if err := processMap(jsonData[i], opType, tokenMap); err != nil {
- fmt.Println("Error processing component:", err)
- return
- }
- }
- // 将处理后的数据转换回JSON字符串
- modifiedJSON, err := json.MarshalIndent(jsonData, "", " ")
- if err != nil {
- fmt.Println("Error marshaling JSON:", err)
- return
- }
- newBody = string(modifiedJSON)
- return
- }
- // processMap 递归处理map中的content字段
- func processMap(data map[string]interface{}, opType string, tokenMap map[string]string) error {
- for key, value := range data {
- switch v := value.(type) {
- case string:
- if key == "content" {
- newContent := v
- // 处理链接
- switch opType {
- case `add`:
- newContent = linkAddToken(v, tokenMap)
- case `del`:
- newContent = linkDelToken(v)
- }
- data[key] = newContent
- }
- case map[string]interface{}:
- if err := processMap(v, opType, tokenMap); err != nil {
- return err
- }
- case []interface{}:
- for i := range v {
- if m, ok := v[i].(map[string]interface{}); ok {
- if err := processMap(m, opType, tokenMap); err != nil {
- return err
- }
- }
- }
- }
- }
- return nil
- }
|