share_poster.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "hongze/hongze_yb/global"
  7. "hongze/hongze_yb/utils"
  8. "io/ioutil"
  9. "net/http"
  10. "strings"
  11. )
  12. // SharePosterReq 分享海报请求体
  13. type SharePosterReq struct {
  14. Source string `json:"source" description:"来源"`
  15. Pars string `json:"pars" description:"海报动态信息"`
  16. CodeScene string `json:"code_scene" description:"太阳码scene"`
  17. CodePath string `json:"code_path" description:"太阳码path"`
  18. Version string `json:"version" description:"版本号" `
  19. }
  20. // CreatePosterFromSource 生成分享海报
  21. func CreatePosterFromSource(source string, pars string) (imgUrl string, err error) {
  22. var errMsg string
  23. defer func() {
  24. if err != nil {
  25. global.LOG.Critical(fmt.Sprintf("CreatePosterFromSource: source=%s, pars:%s, errMsg:%s", source, pars, errMsg))
  26. go SendEmail(utils.APPNAME+"【"+global.CONFIG.Serve.RunMode+"】"+"失败提醒", "生成分享海报失败, "+errMsg+", CreatePosterFromSource: "+err.Error(), utils.EmailSendToUsers)
  27. }
  28. }()
  29. // TODO:根据请求路径及版本号获取图片, 无对应图片则生成图片
  30. // 根据来源选择指定模板并填充html内容, 及生成图片的长宽
  31. heightMap := map[string]int{
  32. "chapter_detail": 370,
  33. "chapter_list": 369,
  34. "chart_detail": 381,
  35. "chart_list": 338,
  36. "report_detail": 355,
  37. "report_list": 369,
  38. }
  39. width := 294
  40. height := heightMap[source]
  41. if height == 0 {
  42. errMsg = "图片长度有误"
  43. err = errors.New(errMsg)
  44. return "", err
  45. }
  46. reqContent := ""
  47. switch source {
  48. case "chart_detail":
  49. if reqContent, err = FillContent2ChartDetailHtml(pars); err != nil {
  50. return
  51. }
  52. }
  53. if reqContent == "" {
  54. errMsg = "html内容有误"
  55. err = errors.New(errMsg)
  56. return
  57. }
  58. // 请求python服务htm2img
  59. htm2ImgReq := make(map[string]interface{})
  60. htm2ImgReq["html_content"] = reqContent
  61. htm2ImgReq["width"] = width
  62. htm2ImgReq["height"] = height
  63. if res, err := postHtml2Img(htm2ImgReq); err != nil || res == nil {
  64. err = errors.New("html转图片请求失败")
  65. return
  66. } else {
  67. if res.Code != 200 {
  68. err = errors.New("html转图片失败: " + res.Msg)
  69. return
  70. }
  71. imgUrl = res.Data
  72. }
  73. // TODO:记录请求路径对应的图片信息
  74. return
  75. }
  76. type ChartDetailPosterReq struct {
  77. ChartInfoId int `json:"chart_info_id"`
  78. ChartName string `json:"chart_name"`
  79. ChartImage string `json:"chart_image"`
  80. }
  81. // 生成html文本-图表详情页
  82. func FillContent2ChartDetailHtml(pars string) (contentStr string, err error) {
  83. // 解析html填充的参数
  84. params := new(ChartDetailPosterReq)
  85. if err = json.Unmarshal([]byte(pars), &params); err != nil {
  86. return
  87. }
  88. // 获取模板内容
  89. demoPath := "static/htm2img/chart_detail.html"
  90. contentByte, err := ioutil.ReadFile(demoPath)
  91. if err != nil {
  92. return
  93. }
  94. // TODO:获取太阳码
  95. // 替换模板内容
  96. contentStr = string(contentByte)
  97. contentStr = strings.ReplaceAll(contentStr, "{{CHART_NAME}}", params.ChartName)
  98. contentStr = strings.ReplaceAll(contentStr, "{{CHART_IMAGE}}", params.ChartImage)
  99. contentStr = strings.ReplaceAll(contentStr, "{{SUN_CODE}}", "")
  100. return
  101. }
  102. type Html2ImgResp struct {
  103. Code int `json:"code"`
  104. Msg string `json:"msg"`
  105. Data string `json:"data"`
  106. }
  107. // postHtml2Img 请求htm2img接口
  108. func postHtml2Img(param map[string]interface{}) (resp *Html2ImgResp, err error) {
  109. pythonUrl := ""
  110. if global.CONFIG.Serve.RunMode == "release" {
  111. } else {
  112. pythonUrl = "http://127.0.0.1:8888/"
  113. }
  114. postUrl := pythonUrl + "htm2img"
  115. postData, err := json.Marshal(param)
  116. if err != nil {
  117. return
  118. }
  119. result, err := Html2ImgHttpPost(postUrl, string(postData), "application/json")
  120. if err != nil {
  121. return
  122. }
  123. if err = json.Unmarshal(result, &resp); err != nil {
  124. return
  125. }
  126. return resp, nil
  127. }
  128. // Html2ImgHttpPost post请求
  129. func Html2ImgHttpPost(url, postData string, params ...string) ([]byte, error) {
  130. body := ioutil.NopCloser(strings.NewReader(postData))
  131. client := &http.Client{}
  132. req, err := http.NewRequest("POST", url, body)
  133. if err != nil {
  134. return nil, err
  135. }
  136. contentType := "application/x-www-form-urlencoded;charset=utf-8"
  137. if len(params) > 0 && params[0] != "" {
  138. contentType = params[0]
  139. }
  140. req.Header.Set("Content-Type", contentType)
  141. resp, err := client.Do(req)
  142. if err != nil {
  143. return nil, err
  144. }
  145. defer resp.Body.Close()
  146. b, err := ioutil.ReadAll(resp.Body)
  147. fmt.Println("HttpPost:" + string(b))
  148. return b, err
  149. }