report.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package services
  2. import (
  3. "eta/eta_mini_api/models"
  4. "eta/eta_mini_api/services/go_redis"
  5. "eta/eta_mini_api/utils"
  6. "fmt"
  7. html2 "golang.org/x/net/html"
  8. "net/url"
  9. "strings"
  10. "time"
  11. )
  12. // HandleReportContent
  13. // @Description: 处理报告内容(动态图表/表格添加授权token)
  14. // @author: Roc
  15. // @datetime 2025-01-07 10:03:15
  16. // @param body string
  17. // @return newBody string
  18. func HandleReportContent(body string, opType string, tokenMap map[string]string) (newBody string) {
  19. if body == `` {
  20. return
  21. }
  22. newBody = body
  23. // 解析HTML
  24. doc, err := html2.Parse(strings.NewReader(body))
  25. if err != nil {
  26. fmt.Println("Error parsing HTML:", err)
  27. return
  28. }
  29. replaceIframeSrc(doc, opType, tokenMap)
  30. // 输出修改后的HTML
  31. var modifiedHtml strings.Builder
  32. err = html2.Render(&modifiedHtml, doc)
  33. if err != nil {
  34. fmt.Println("Error rendering HTML:", err)
  35. return
  36. }
  37. newBody = modifiedHtml.String()
  38. fmt.Println(newBody)
  39. return
  40. }
  41. // replaceIframeSrc 遍历HTML节点,替换iframe的src属性
  42. func replaceIframeSrc(n *html2.Node, opType string, tokenMap map[string]string) {
  43. if n.Type == html2.ElementNode && n.Data == "iframe" {
  44. for i, attr := range n.Attr {
  45. if attr.Key == "src" {
  46. newLink := attr.Val
  47. // 处理链接
  48. switch opType {
  49. case `add`:
  50. newLink = linkAddToken(attr.Val, tokenMap)
  51. case `del`:
  52. newLink = linkDelToken(attr.Val)
  53. }
  54. // 替换原来的链接
  55. n.Attr[i].Val = newLink
  56. break
  57. }
  58. }
  59. }
  60. // 递归处理子节点
  61. for c := n.FirstChild; c != nil; c = c.NextSibling {
  62. replaceIframeSrc(c, opType, tokenMap)
  63. }
  64. }
  65. // linkAddToken 链接添加token
  66. func linkAddToken(link string, tokenMap map[string]string) string {
  67. var err error
  68. defer func() {
  69. if err != nil {
  70. utils.FileLog.Info(fmt.Sprintf("linkAddToken: 处理链接失败, %v", err))
  71. }
  72. }()
  73. parsedURL, err := url.Parse(link)
  74. if err != nil {
  75. return link
  76. }
  77. // 获取查询参数
  78. queryParams := parsedURL.Query()
  79. // 先移除authToken参数,避免莫名其妙的这个值入库了
  80. queryParams.Del("authToken")
  81. // 获取code参数
  82. code := queryParams.Get("code")
  83. if code == "" {
  84. return link
  85. }
  86. showType := `chart`
  87. if strings.Contains(parsedURL.Path, "sheetshow") {
  88. showType = `excel`
  89. }
  90. // 避免报告里面一个图表/表格重复生成token
  91. key := fmt.Sprint(showType, `:`, code)
  92. if tokenMap != nil {
  93. if token, ok := tokenMap[key]; ok {
  94. // 在链接后面添加一个token值
  95. return link + "&authToken=" + token
  96. }
  97. }
  98. token, err := GeneralChartToken(showType, code)
  99. if err != nil {
  100. return link
  101. }
  102. if tokenMap != nil {
  103. tokenMap[key] = token
  104. }
  105. // 在链接后面添加一个token值
  106. return link + "&authToken=" + token
  107. }
  108. // linkDelToken 链接添加token
  109. func linkDelToken(link string) string {
  110. var err error
  111. defer func() {
  112. if err != nil {
  113. utils.FileLog.Info(fmt.Sprintf("linkDelToken: 处理链接失败, %v", err))
  114. }
  115. }()
  116. parsedURL, err := url.Parse(link)
  117. if err != nil {
  118. return link
  119. }
  120. // 获取查询参数
  121. queryParams := parsedURL.Query()
  122. // 移除authToken参数
  123. queryParams.Del("authToken")
  124. // 更新URL的查询参数
  125. parsedURL.RawQuery = queryParams.Encode()
  126. return parsedURL.String()
  127. }
  128. // GeneralChartToken
  129. // @Description: 生产图表/表格授权token
  130. // @author: Roc
  131. // @datetime 2025-01-07 10:41:36
  132. // @param showType string
  133. // @param uniqueCode string
  134. // @return token string
  135. // @return err error
  136. func GeneralChartToken(showType, uniqueCode string) (token string, err error) {
  137. // 缓存key
  138. token = utils.MD5(fmt.Sprint(showType+`:`, uniqueCode, time.Now().UnixNano()/1e6))
  139. key := fmt.Sprint(utils.CACHE_CHART_AUTH, token)
  140. go_redis.SetNX(key, uniqueCode, utils.BusinessConfReportChartExpiredTime)
  141. return
  142. }
  143. // CheckIsOpenChartExpired
  144. // @Description: 判断是否开启图表授权
  145. // @author: Roc
  146. // @datetime 2025-01-07 16:51:34
  147. // @return isOpenChartExpired bool
  148. // @return err error
  149. func CheckIsOpenChartExpired() (isOpenChartExpired bool, err error) {
  150. obj := new(models.BusinessConf)
  151. item, e := obj.GetItemByConfKey(models.BusinessConfIsOpenChartExpired)
  152. if e != nil {
  153. err = fmt.Errorf("CheckIsOpenChartExpired, %v", e)
  154. return
  155. }
  156. if item.Id <= 0 {
  157. return
  158. }
  159. if item.ConfVal == `true` {
  160. isOpenChartExpired = true
  161. }
  162. return
  163. }