ppt.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_mobile/models"
  6. "eta/eta_mobile/models/ppt_english"
  7. "eta/eta_mobile/services/alarm_msg"
  8. "eta/eta_mobile/utils"
  9. "fmt"
  10. "sort"
  11. "time"
  12. )
  13. const (
  14. ElementsTypeText = "text"
  15. ElementsTypeImage = "image"
  16. ElementsTypeChart = "chart"
  17. ElementsTypeSheet = "sheet"
  18. )
  19. type PPTContent struct {
  20. //Id int `json:"id" description:"此处因目录改版类型有int也有string且并没有使用到该字段所以注释掉"`
  21. Key int `json:"key"`
  22. ModelId int `json:"modelId"`
  23. Title string `json:"title"`
  24. Elements []PPTContentElements `json:"elements"`
  25. }
  26. type PPTContentElements struct {
  27. Type string `json:"type"`
  28. Position int `json:"position"`
  29. Content string `json:"content"`
  30. RichContent string `json:"richContent"`
  31. ChartId string `json:"chartId"`
  32. SheetId string `json:"sheetId"`
  33. SheetHeight string `json:"sheetHeight"`
  34. Src string `json:"src"`
  35. }
  36. // PPT2内容转HTML
  37. func pptContent2Html(content string, isEnglish bool) (htm string, err error) {
  38. contents := make([]PPTContent, 0)
  39. if e := json.Unmarshal([]byte(content), &contents); e != nil {
  40. err = errors.New("PPT内容转换失败")
  41. return
  42. }
  43. pageLen := len(contents)
  44. htmlContent := ``
  45. // iframe图表/表格域名
  46. chartRoot := utils.PublicChartHost
  47. if pageLen > 0 {
  48. htmlPrefix := `<p style="text-align: left; margin-top: 10px; font-size: 16px;">`
  49. htmlSuffix := `</p>`
  50. htmlBr := `<br>`
  51. for i := 0; i < pageLen; i++ {
  52. // 每页标题加粗居中
  53. title := contents[i].Title
  54. if title != "" {
  55. htmlContent += `<p style="font-size: 16px; text-align: left;"><strong>`
  56. htmlContent += title
  57. htmlContent += `</strong></p>`
  58. }
  59. ele := contents[i].Elements
  60. // 每页元素按照Position升序排序
  61. sort.Slice(ele, func(k, j int) bool {
  62. return ele[k].Position < ele[j].Position
  63. })
  64. for _, v := range ele {
  65. // 根据不同的Type拼接不同的内容
  66. htmlContent += htmlPrefix
  67. switch v.Type {
  68. case ElementsTypeText:
  69. htmlContent += v.RichContent
  70. case ElementsTypeImage:
  71. htmlContent += fmt.Sprint(`<img src="`, v.Src, `" class="fr-fic fr-dib fr-draggable">`)
  72. case ElementsTypeChart:
  73. if isEnglish {
  74. // 英文研报图表src多加一个fromPage=en, 表格暂时没有区分
  75. htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s&fromPage=en" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
  76. break
  77. }
  78. htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
  79. case ElementsTypeSheet:
  80. htmlContent += fmt.Sprintf(`<iframe src="%s/sheetshow?code=%s" class="iframe%s" width="100%%" height="%s" style="border-width:0px;"></iframe>`, chartRoot, v.SheetId, v.SheetId, v.SheetHeight)
  81. }
  82. htmlContent += htmlSuffix
  83. }
  84. // 每页中间插入一个换行符, 最后一页不插入
  85. currentPage := i + 1
  86. if currentPage != pageLen {
  87. htmlContent += htmlPrefix + htmlBr + htmlSuffix
  88. }
  89. }
  90. }
  91. htm = htmlContent
  92. return
  93. }
  94. // ResetPPTReport 重置PPT关联的报告(如删除关联的报告后)
  95. func ResetPPTReport(reportId int, isEnglish bool) (err error) {
  96. defer func() {
  97. if err != nil {
  98. utils.FileLog.Info("%s", err.Error())
  99. go alarm_msg.SendAlarmMsg("重置PPT关联报告失败, ResetPPTReport Err: "+err.Error(), 3)
  100. }
  101. }()
  102. // 英文报告
  103. if isEnglish {
  104. en, e := ppt_english.GetPptEnglishByReportId(reportId)
  105. if e != nil && e.Error() != utils.ErrNoRow() {
  106. err = errors.New("获取英文PPT失败, Err: " + e.Error())
  107. return
  108. }
  109. if en != nil {
  110. updateCols := []string{"ReportId", "ReportCode"}
  111. en.ReportId = 0
  112. en.ReportCode = ""
  113. if e = en.Update(updateCols); e != nil {
  114. err = errors.New("更新英文PPT关联报告失败, Err: " + e.Error())
  115. return
  116. }
  117. }
  118. return
  119. }
  120. // 中文报告
  121. item, e := models.GetPptV2ByReportId(reportId)
  122. if e != nil && e.Error() != utils.ErrNoRow() {
  123. err = errors.New("获取PPT失败, Err: " + e.Error())
  124. return
  125. }
  126. if item != nil {
  127. updateCols := []string{"ReportId", "ReportCode"}
  128. item.ReportId = 0
  129. item.ReportCode = ""
  130. if e = item.Update(updateCols); e != nil {
  131. err = errors.New("更新PPT关联报告失败, Err: " + e.Error())
  132. return
  133. }
  134. }
  135. return
  136. }
  137. // UpdatePptEditing 更新PPT编辑状态
  138. func UpdatePptEditing(pptId, status, userId int, userName string, isEn bool) (ret ppt_english.PPTEditingCache, err error) {
  139. if pptId <= 0 {
  140. return
  141. }
  142. cacheKey := ""
  143. if isEn {
  144. cacheKey = fmt.Sprint(utils.CACHE_EN_PPT_EDITING, pptId)
  145. } else {
  146. cacheKey = fmt.Sprint(utils.CACHE_PPT_EDITING, pptId)
  147. }
  148. // 完成编辑
  149. if status == 2 {
  150. _ = utils.Rc.Delete(cacheKey)
  151. return
  152. }
  153. // 读取缓存中的结果
  154. var editor ppt_english.PPTEditingCache
  155. strCache, _ := utils.Rc.RedisString(cacheKey)
  156. fmt.Println(strCache)
  157. if strCache != "" {
  158. e := json.Unmarshal([]byte(strCache), &editor)
  159. if e != nil {
  160. err = fmt.Errorf("解析缓存内容失败: %s", e.Error())
  161. return
  162. }
  163. }
  164. // 标记编辑中
  165. if status == 1 {
  166. // 无人编辑, 写入缓存
  167. if !editor.IsEditing {
  168. ret.IsEditing = true
  169. ret.AdminId = userId
  170. ret.Editor = userName
  171. ret.Tips = fmt.Sprintf("当前%s正在编辑PPT", userName)
  172. b, _ := json.Marshal(ret)
  173. utils.Rc.SetNX(cacheKey, string(b), 3*time.Minute)
  174. return
  175. }
  176. // 有人编辑
  177. if editor.IsEditing {
  178. // 编辑用户与当前用户不一致, 返回编辑用户, 一致则更新缓存
  179. if userId == editor.AdminId {
  180. b, _ := json.Marshal(editor)
  181. utils.Rc.Do("SETEX", cacheKey, int64(180), string(b))
  182. }
  183. ret = editor
  184. return
  185. }
  186. } else {
  187. // 默认查询
  188. ret = editor
  189. }
  190. return
  191. }